[hamradio-commits] [qsstv] 02/06: Imported Upstream version 9.1.5

Dave Hibberd hibby-guest at moszumanska.debian.org
Tue May 24 21:44:52 UTC 2016


This is an automated email from the git hooks/post-receive script.

hibby-guest pushed a commit to branch master
in repository qsstv.

commit 74a8e01c8640b8419dff52626dc5321faedf08a8
Author: Hibby <d at vehibberd.com>
Date:   Tue May 24 20:58:14 2016 +0100

    Imported Upstream version 9.1.5
---
 qsstv/COPYING => COPYING                           |    0
 README.txt                                         |    7 +
 qsstv/{qsstvdefs.h => appdefs.h}                   |   34 +-
 qsstv/appglobal.cpp                                |   76 +
 qsstv/appglobal.h                                  |   72 +
 qsstv/config/baseconfig.cpp                        |    6 +
 qsstv/config/baseconfig.h                          |   22 +
 qsstv/config/configdialog.cpp                      |   86 +
 qsstv/config/configdialog.h                        |   33 +
 qsstv/config/configdialog.ui                       |  281 ++
 qsstv/config/configparams.h                        |   18 +
 qsstv/config/cwconfig.cpp                          |   67 +
 qsstv/config/cwconfig.h                            |   32 +
 qsstv/config/cwconfig.ui                           |  267 ++
 qsstv/config/directoriesconfig.cpp                 |  184 +
 qsstv/config/directoriesconfig.h                   |   46 +
 qsstv/config/directoriesconfig.ui                  |  487 +++
 .../drmprofileconfig.cpp}                          |   58 +-
 qsstv/config/drmprofileconfig.h                    |   55 +
 .../drmprofileconfig.ui}                           |   10 +-
 qsstv/config/frequencyselectwidget.cpp             |  251 ++
 qsstv/config/frequencyselectwidget.h               |   46 +
 qsstv/config/frequencyselectwidget.ui              |  149 +
 qsstv/config/ftpconfig.cpp                         |  151 +
 qsstv/config/ftpconfig.h                           |   48 +
 qsstv/config/ftpconfig.ui                          |  471 ++
 qsstv/config/guiconfig.cpp                         |  114 +
 qsstv/config/guiconfig.h                           |   42 +
 qsstv/config/guiconfig.ui                          |  198 +
 qsstv/config/hybridconfig.cpp                      |  121 +
 qsstv/config/hybridconfig.h                        |   38 +
 qsstv/config/hybridconfig.ui                       |  456 ++
 qsstv/config/hybridnotifyconfig.cpp                |  123 +
 qsstv/config/hybridnotifyconfig.h                  |   38 +
 qsstv/config/hybridnotifyconfig.ui                 |  456 ++
 qsstv/config/operatorconfig.cpp                    |   77 +
 qsstv/config/operatorconfig.h                      |   33 +
 qsstv/config/operatorconfig.ui                     |  282 ++
 qsstv/config/repeaterconfig.cpp                    |  110 +
 qsstv/config/repeaterconfig.h                      |   39 +
 qsstv/config/repeaterconfig.ui                     |  340 ++
 .../rigcontrolform.cpp => config/rigconfig.cpp}    |  124 +-
 qsstv/config/rigconfig.h                           |   45 +
 qsstv/config/rigconfig.ui                          | 2143 +++++++++
 qsstv/config/soundconfig.cpp                       |  153 +
 qsstv/config/soundconfig.h                         |   43 +
 .../soundcontrol.ui => config/soundconfig.ui}      |  157 +-
 qsstv/config/waterfallconfig.cpp                   |   82 +
 qsstv/config/waterfallconfig.h                     |   37 +
 qsstv/config/waterfallconfig.ui                    |  200 +
 qsstv/configdialog.cpp                             |  557 ---
 qsstv/configdialog.h                               |   52 -
 qsstv/configform.ui                                | 2670 ------------
 qsstv/configparams.cpp                             |  110 -
 qsstv/configparams.h                               |   91 -
 qsstv/dispatch/dispatcher.cpp                      |  445 ++
 qsstv/{ => dispatch}/dispatcher.h                  |   37 +-
 qsstv/dispatch/dispatchevents.h                    |  644 +++
 qsstv/dispatcher.cpp                               |  568 ---
 qsstv/dispatchevents.h                             |  567 ---
 qsstv/documentation/manual/doxygen_sqlite3.db      |  Bin 0 -> 20480 bytes
 .../manual/images/Gallery_image_options.png        |  Bin 0 -> 947185 bytes
 qsstv/documentation/manual/images/Gallery_rx.png   |  Bin 0 -> 991987 bytes
 .../manual/images/Gallery_template.png             |  Bin 0 -> 101784 bytes
 qsstv/documentation/manual/images/Gallery_tx.png   |  Bin 0 -> 395505 bytes
 qsstv/documentation/manual/images/binary.png       |  Bin 0 -> 189 bytes
 qsstv/documentation/manual/images/bsr_nfy.png      |  Bin 0 -> 8447 bytes
 qsstv/documentation/manual/images/bsr_select.png   |  Bin 0 -> 29901 bytes
 qsstv/documentation/manual/images/calibration.png  |  Bin 0 -> 17829 bytes
 qsstv/documentation/manual/images/config.png       |  Bin 0 -> 13929 bytes
 qsstv/documentation/manual/images/config1.png      |  Bin 0 -> 34726 bytes
 qsstv/documentation/manual/images/config10.png     |  Bin 0 -> 61052 bytes
 qsstv/documentation/manual/images/config11.png     |  Bin 0 -> 43280 bytes
 qsstv/documentation/manual/images/config12.png     |  Bin 0 -> 63358 bytes
 qsstv/documentation/manual/images/config2.png      |  Bin 0 -> 83109 bytes
 qsstv/documentation/manual/images/config3.png      |  Bin 0 -> 41811 bytes
 qsstv/documentation/manual/images/config4.png      |  Bin 0 -> 76666 bytes
 qsstv/documentation/manual/images/config5.png      |  Bin 0 -> 80058 bytes
 qsstv/documentation/manual/images/config6.png      |  Bin 0 -> 31946 bytes
 qsstv/documentation/manual/images/config7.png      |  Bin 0 -> 55107 bytes
 qsstv/documentation/manual/images/config8.png      |  Bin 0 -> 64012 bytes
 qsstv/documentation/manual/images/config9.png      |  Bin 0 -> 34998 bytes
 qsstv/documentation/manual/images/cqrlog1.png      |  Bin 0 -> 31072 bytes
 qsstv/documentation/manual/images/cqrlog2.png      |  Bin 0 -> 159450 bytes
 qsstv/documentation/manual/images/editor_1.png     |  Bin 0 -> 46417 bytes
 qsstv/documentation/manual/images/editor_2.png     |  Bin 0 -> 65956 bytes
 qsstv/documentation/manual/images/editor_3.png     |  Bin 0 -> 108818 bytes
 .../manual/images/editor_image_size.png            |  Bin 0 -> 9662 bytes
 qsstv/documentation/manual/images/entertext.png    |  Bin 0 -> 7303 bytes
 qsstv/documentation/manual/images/eraser.png       |  Bin 0 -> 1226 bytes
 qsstv/documentation/manual/images/fix.png          |  Bin 0 -> 58939 bytes
 qsstv/documentation/manual/images/flrig1.png       |  Bin 0 -> 44384 bytes
 .../manual/images/hybrid_checkbox.png              |  Bin 0 -> 1385 bytes
 .../manual/images/hybrid_dis_checkbox.png          |  Bin 0 -> 1181 bytes
 qsstv/documentation/manual/images/multiline.png    |  Bin 0 -> 10665 bytes
 qsstv/documentation/manual/images/receivedrm.png   |  Bin 0 -> 266130 bytes
 .../documentation/manual/images/refreshbutton.png  |  Bin 0 -> 1790 bytes
 .../manual/images/rxdrm_constellation.png          |  Bin 0 -> 2357 bytes
 .../documentation/manual/images/rxdrm_segments.png |  Bin 0 -> 492 bytes
 qsstv/documentation/manual/images/rxdrm_status.png |  Bin 0 -> 10254 bytes
 qsstv/documentation/manual/images/rxwidget1.png    |  Bin 0 -> 498851 bytes
 .../documentation/manual/images/sstvdrmselect.png  |  Bin 0 -> 18139 bytes
 qsstv/documentation/manual/images/statusbar.png    |  Bin 0 -> 6902 bytes
 qsstv/documentation/manual/images/statusleds.png   |  Bin 0 -> 1604 bytes
 qsstv/documentation/manual/images/transmitdrm.png  |  Bin 0 -> 347771 bytes
 .../manual/images/tx-with-template.png             |  Bin 0 -> 447085 bytes
 .../manual/images/txdrm_compression.png            |  Bin 0 -> 2285 bytes
 .../documentation/manual/images/txdrm_options.png  |  Bin 0 -> 13080 bytes
 qsstv/documentation/manual/images/txdrm_status.png |  Bin 0 -> 12622 bytes
 qsstv/documentation/manual/images/txwidget1.png    |  Bin 0 -> 332079 bytes
 qsstv/documentation/manual/images/vk4aes.jpg       |  Bin 0 -> 11489 bytes
 qsstv/documentation/manual/images/waterfall.png    |  Bin 0 -> 165766 bytes
 qsstv/documentation/manual/images/wf_bsr_id.png    |  Bin 0 -> 3332 bytes
 qsstv/documentation/manual/images/wftextpopup.png  |  Bin 0 -> 22203 bytes
 .../{Doxyfile => documentation/manual/manual.doxy} | 1723 ++++----
 qsstv/documentation/manual/manual.txt              |  891 ++++
 .../manual/manual/Gallery_image_options.png        |  Bin 0 -> 947185 bytes
 qsstv/documentation/manual/manual/Gallery_rx.png   |  Bin 0 -> 991987 bytes
 .../manual/manual/Gallery_template.png             |  Bin 0 -> 101784 bytes
 qsstv/documentation/manual/manual/Gallery_tx.png   |  Bin 0 -> 395505 bytes
 qsstv/documentation/manual/manual/_copying.html    |   77 +
 qsstv/documentation/manual/manual/_r_x_d_r_m.html  |  138 +
 .../documentation/manual/manual/_r_x_s_s_t_v.html  |  121 +
 qsstv/documentation/manual/manual/_t_x_d_r_m.html  |  124 +
 .../documentation/manual/manual/_t_x_s_s_t_v.html  |  149 +
 qsstv/documentation/manual/manual/arrow.png        |  Bin 0 -> 298 bytes
 qsstv/documentation/manual/manual/arrowdown.png    |  Bin 0 -> 246 bytes
 qsstv/documentation/manual/manual/arrowright.png   |  Bin 0 -> 229 bytes
 qsstv/documentation/manual/manual/bc_s.png         |  Bin 0 -> 676 bytes
 qsstv/documentation/manual/manual/bdwn.png         |  Bin 0 -> 147 bytes
 qsstv/documentation/manual/manual/binary.png       |  Bin 0 -> 189 bytes
 qsstv/documentation/manual/manual/bsr_nfy.png      |  Bin 0 -> 8447 bytes
 qsstv/documentation/manual/manual/bsr_select.png   |  Bin 0 -> 29901 bytes
 qsstv/documentation/manual/manual/calibration.png  |  Bin 0 -> 17829 bytes
 qsstv/documentation/manual/manual/camera.png       |  Bin 0 -> 1627 bytes
 qsstv/documentation/manual/manual/changelog.html   |  161 +
 qsstv/documentation/manual/manual/closed.png       |  Bin 0 -> 132 bytes
 qsstv/documentation/manual/manual/config.png       |  Bin 0 -> 13929 bytes
 qsstv/documentation/manual/manual/config1.png      |  Bin 0 -> 34726 bytes
 qsstv/documentation/manual/manual/config10.png     |  Bin 0 -> 61052 bytes
 qsstv/documentation/manual/manual/config11.png     |  Bin 0 -> 43280 bytes
 qsstv/documentation/manual/manual/config12.png     |  Bin 0 -> 63358 bytes
 qsstv/documentation/manual/manual/config2.png      |  Bin 0 -> 83109 bytes
 qsstv/documentation/manual/manual/config3.png      |  Bin 0 -> 41811 bytes
 qsstv/documentation/manual/manual/config4.png      |  Bin 0 -> 76666 bytes
 qsstv/documentation/manual/manual/config5.png      |  Bin 0 -> 80058 bytes
 qsstv/documentation/manual/manual/config6.png      |  Bin 0 -> 31946 bytes
 qsstv/documentation/manual/manual/config7.png      |  Bin 0 -> 55107 bytes
 qsstv/documentation/manual/manual/config8.png      |  Bin 0 -> 64012 bytes
 qsstv/documentation/manual/manual/config9.png      |  Bin 0 -> 34998 bytes
 qsstv/documentation/manual/manual/cqrlog1.png      |  Bin 0 -> 31072 bytes
 qsstv/documentation/manual/manual/cqrlog2.png      |  Bin 0 -> 159450 bytes
 qsstv/documentation/manual/manual/credits.html     |   98 +
 qsstv/documentation/manual/manual/doc.png          |  Bin 0 -> 746 bytes
 qsstv/documentation/manual/manual/doubletone.png   |  Bin 0 -> 233 bytes
 qsstv/documentation/manual/manual/doxygen.png      |  Bin 0 -> 3779 bytes
 qsstv/documentation/manual/manual/dynsections.js   |   97 +
 qsstv/documentation/manual/manual/edit.png         |  Bin 0 -> 1249 bytes
 qsstv/documentation/manual/manual/editor.html      |  203 +
 qsstv/documentation/manual/manual/editor_1.png     |  Bin 0 -> 46417 bytes
 qsstv/documentation/manual/manual/editor_2.png     |  Bin 0 -> 65956 bytes
 .../manual/manual/editor_image_size.png            |  Bin 0 -> 9662 bytes
 qsstv/documentation/manual/manual/entertext.png    |  Bin 0 -> 7303 bytes
 qsstv/documentation/manual/manual/eraser.png       |  Bin 0 -> 1226 bytes
 .../documentation/manual/manual/externalprog.html  |  113 +
 qsstv/documentation/manual/manual/fcircle.png      |  Bin 0 -> 959 bytes
 qsstv/documentation/manual/manual/fileopen.png     |  Bin 0 -> 1356 bytes
 qsstv/documentation/manual/manual/filesave.png     |  Bin 0 -> 821 bytes
 qsstv/documentation/manual/manual/fix.png          |  Bin 0 -> 58939 bytes
 qsstv/documentation/manual/manual/fixdrm.html      |   83 +
 qsstv/documentation/manual/manual/flrig1.png       |  Bin 0 -> 44384 bytes
 qsstv/documentation/manual/manual/folderclosed.png |  Bin 0 -> 616 bytes
 qsstv/documentation/manual/manual/folderopen.png   |  Bin 0 -> 597 bytes
 qsstv/documentation/manual/manual/frect.png        |  Bin 0 -> 394 bytes
 qsstv/documentation/manual/manual/gallery.html     |   89 +
 .../manual/manual/gettingstarted.html              |  366 ++
 .../manual/manual/hybrid_checkbox.png              |  Bin 0 -> 1385 bytes
 .../manual/manual/hybrid_dis_checkbox.png          |  Bin 0 -> 1181 bytes
 qsstv/documentation/manual/manual/imagepopup.html  |   93 +
 qsstv/documentation/manual/manual/index.html       |  101 +
 qsstv/documentation/manual/manual/index.js         |   29 +
 .../documentation/manual/manual/installation.html  |  114 +
 qsstv/documentation/manual/manual/jquery.js        |   68 +
 qsstv/documentation/manual/manual/line.png         |  Bin 0 -> 624 bytes
 qsstv/documentation/manual/manual/multiline.png    |  Bin 0 -> 10665 bytes
 qsstv/documentation/manual/manual/nav_f.png        |  Bin 0 -> 153 bytes
 qsstv/documentation/manual/manual/nav_g.png        |  Bin 0 -> 95 bytes
 qsstv/documentation/manual/manual/nav_h.png        |  Bin 0 -> 98 bytes
 qsstv/documentation/manual/manual/navtree.css      |  143 +
 qsstv/documentation/manual/manual/navtree.js       |  523 +++
 qsstv/documentation/manual/manual/navtreedata.js   |   14 +
 qsstv/documentation/manual/manual/navtreeindex0.js |   30 +
 qsstv/documentation/manual/manual/open.png         |  Bin 0 -> 123 bytes
 qsstv/documentation/manual/manual/pages.html       |   79 +
 qsstv/documentation/manual/manual/qsstv.css        |  835 ++++
 qsstv/documentation/manual/manual/receivedrm.png   |  Bin 0 -> 266130 bytes
 .../documentation/manual/manual/refreshbutton.png  |  Bin 0 -> 1790 bytes
 qsstv/documentation/manual/manual/replay.png       |  Bin 0 -> 1417 bytes
 qsstv/documentation/manual/manual/resize.js        |   97 +
 .../manual/manual/rxdrm_constellation.png          |  Bin 0 -> 2357 bytes
 .../documentation/manual/manual/rxdrm_segments.png |  Bin 0 -> 492 bytes
 qsstv/documentation/manual/manual/rxdrm_status.png |  Bin 0 -> 10254 bytes
 qsstv/documentation/manual/manual/rxwidget1.png    |  Bin 0 -> 498851 bytes
 qsstv/documentation/manual/manual/splitbar.png     |  Bin 0 -> 314 bytes
 qsstv/documentation/manual/manual/start.png        |  Bin 0 -> 1263 bytes
 qsstv/documentation/manual/manual/statusbar.html   |  105 +
 qsstv/documentation/manual/manual/statusbar.png    |  Bin 0 -> 6902 bytes
 qsstv/documentation/manual/manual/statusleds.png   |  Bin 0 -> 1604 bytes
 qsstv/documentation/manual/manual/stop.png         |  Bin 0 -> 1122 bytes
 qsstv/documentation/manual/manual/sweep.png        |  Bin 0 -> 278 bytes
 qsstv/documentation/manual/manual/sync_off.png     |  Bin 0 -> 853 bytes
 qsstv/documentation/manual/manual/sync_on.png      |  Bin 0 -> 845 bytes
 qsstv/documentation/manual/manual/tab_a.png        |  Bin 0 -> 142 bytes
 qsstv/documentation/manual/manual/tab_b.png        |  Bin 0 -> 169 bytes
 qsstv/documentation/manual/manual/tab_h.png        |  Bin 0 -> 177 bytes
 qsstv/documentation/manual/manual/tab_s.png        |  Bin 0 -> 184 bytes
 qsstv/documentation/manual/manual/tabs.css         |   60 +
 qsstv/documentation/manual/manual/text.png         |  Bin 0 -> 517 bytes
 qsstv/documentation/manual/manual/todo1.html       |   81 +
 qsstv/documentation/manual/manual/tone.png         |  Bin 0 -> 358 bytes
 qsstv/documentation/manual/manual/transmitdrm.png  |  Bin 0 -> 347771 bytes
 .../manual/manual/txdrm_compression.png            |  Bin 0 -> 2285 bytes
 .../documentation/manual/manual/txdrm_options.png  |  Bin 0 -> 13080 bytes
 qsstv/documentation/manual/manual/txdrm_status.png |  Bin 0 -> 12622 bytes
 qsstv/documentation/manual/manual/txwidget1.png    |  Bin 0 -> 332079 bytes
 qsstv/documentation/manual/manual/vk4aes.jpg       |  Bin 0 -> 11489 bytes
 qsstv/documentation/manual/manual/waterfall.png    |  Bin 0 -> 165766 bytes
 qsstv/documentation/manual/manual/wftextpopup.png  |  Bin 0 -> 22203 bytes
 qsstv/documentation/manual/manual/whatsnew.html    |   91 +
 qsstv/documentation/manual/qsstv.css               |  835 ++++
 qsstv/drmprofileform.h                             |   40 -
 qsstv/drmrx/channeldecode.cpp                      |  402 +-
 qsstv/drmrx/deflate_uncompress.cpp                 |  294 --
 qsstv/drmrx/demodulator.cpp                        |  158 +-
 qsstv/drmrx/demodulator.h                          |    5 +-
 qsstv/drmrx/drm.cpp                                |   15 +
 qsstv/drmrx/drm.h                                  |   27 +-
 qsstv/drmrx/drmconstellationframe.cpp              |    2 +-
 qsstv/drmrx/drmdatainput.cpp                       |  879 ----
 qsstv/drmrx/drmdatainput.h                         |   29 -
 qsstv/drmrx/drmrx.cpp                              |   76 +
 qsstv/drmrx/drmrx.h                                |   32 +
 qsstv/drmrx/drmstatusframe.cpp                     |  241 +-
 qsstv/drmrx/drmstatusframe.h                       |   32 +-
 qsstv/drmrx/drmstatusframe.ui                      |  206 +-
 qsstv/drmrx/fixform.cpp                            |    4 +-
 qsstv/drmrx/fixform.ui                             |   29 +-
 qsstv/drmrx/getmode.cpp                            |    2 +-
 qsstv/drmrx/getofdm.cpp                            |    2 +-
 qsstv/drmrx/getofdmsync.cpp                        |   53 +-
 qsstv/drmrx/hybridcrypt.cpp                        |  135 -
 qsstv/drmrx/sourcedecoder.cpp                      |  844 ++--
 qsstv/drmrx/sourcedecoder.h                        |   12 +-
 qsstv/drmtx/bsrform.cpp                            |   23 +-
 qsstv/drmtx/common/DRMSignalIO.cpp                 |    2 +-
 qsstv/drmtx/common/DrmTransmitter.cpp              |    5 +-
 qsstv/drmtx/common/GlobalDefinitions.h             |    4 +-
 qsstv/drmtx/common/Parameter.h                     |   52 +-
 qsstv/drmtx/common/SDC/SDCTransmit.cpp             |   46 +-
 qsstv/drmtx/common/csoundout.cpp                   |    2 +-
 qsstv/drmtx/common/datadecoding/DABMOT.cpp         |    5 +-
 qsstv/drmtx/common/datadecoding/DABMOT.h           |    2 +-
 qsstv/drmtx/common/datadecoding/MOTSlideShow.cpp   |    5 +-
 .../common/ofdmcellmapping/OFDMCellMapping.cpp     |   14 +
 qsstv/drmtx/common/soundinterface.h                |    2 +-
 qsstv/drmtx/common/tables/TableCarMap.h            |   11 -
 qsstv/drmtx/common/util/Buffer.h                   |    6 +-
 qsstv/drmtx/drmparams.cpp                          |   35 +
 qsstv/drmtx/drmparams.h                            |   24 +
 qsstv/drmtx/drmtransmitter.cpp                     |   26 +-
 qsstv/drmtx/drmtransmitter.h                       |   15 +-
 qsstv/drmtx/drmtx.cpp                              |  330 ++
 qsstv/drmtx/drmtx.h                                |   68 +
 qsstv/dsp/downsamplefilter.cpp                     |  326 +-
 qsstv/dsp/downsamplefilter.h                       |   29 +-
 qsstv/dsp/filter.cpp                               |  447 +-
 qsstv/dsp/filter.h                                 |  112 +-
 qsstv/dsp/filterparam.cpp                          | 4542 +++-----------------
 qsstv/dsp/filterparam.h                            |   60 +-
 qsstv/dsp/filters.cpp                              |  179 +
 qsstv/dsp/filters.h                                |   62 +
 qsstv/dsp/nco.h                                    |   26 +-
 qsstv/dsp/synthes.cpp                              |   45 +-
 qsstv/dsp/synthes.h                                |    8 +
 qsstv/editor/canvassizeform.cpp                    |   30 +
 qsstv/editor/canvassizeform.h                      |   24 +
 qsstv/editor/canvassizeform.ui                     |  138 +
 qsstv/editor/editor.cpp                            |   14 +-
 qsstv/editor/editor.h                              |    2 +-
 qsstv/editor/editorform.ui                         |  326 +-
 qsstv/editor/editorscene.cpp                       |  822 ++--
 qsstv/editor/editorview.cpp                        |  765 ++--
 qsstv/editor/editorview.h                          |   10 +-
 qsstv/editor/gradientdialog.cpp                    |    2 +-
 qsstv/editor/graphicitems.cpp                      |  756 ++--
 qsstv/editor/graphicitems.h                        |   10 +-
 qsstv/editor/textform.ui                           |   41 +-
 qsstv/gallerywidget.cpp                            |  320 --
 qsstv/gallerywidget.ui                             |  215 -
 qsstv/icons/binary.png                             |  Bin 0 -> 189 bytes
 qsstv/icons/doubleleft.png                         |  Bin 0 -> 1143 bytes
 qsstv/icons/doubleright.png                        |  Bin 0 -> 1084 bytes
 qsstv/icons/down.png                               |  Bin 0 -> 722 bytes
 qsstv/icons/left.png                               |  Bin 0 -> 1240 bytes
 qsstv/icons/up.png                                 |  Bin 0 -> 787 bytes
 qsstv/logbook/logbook.cpp                          |   21 +-
 qsstv/logbook/logbook.h                            |    3 +-
 qsstv/main.cpp                                     |   28 +-
 qsstv/mainwidgets/gallerywidget.cpp                |  221 +
 qsstv/{ => mainwidgets}/gallerywidget.h            |   17 +-
 qsstv/mainwidgets/gallerywidget.ui                 |  152 +
 qsstv/mainwidgets/rxfunctions.cpp                  |  189 +
 qsstv/mainwidgets/rxfunctions.h                    |   53 +
 qsstv/mainwidgets/rxwidget.cpp                     |  306 ++
 qsstv/{ => mainwidgets}/rxwidget.h                 |   52 +-
 qsstv/mainwidgets/rxwidget.ui                      |  975 +++++
 qsstv/mainwidgets/txfunctions.cpp                  |  504 +++
 qsstv/mainwidgets/txfunctions.h                    |   85 +
 qsstv/{ => mainwidgets}/txwidget.cpp               |  529 +--
 qsstv/{ => mainwidgets}/txwidget.h                 |   92 +-
 qsstv/{ => mainwidgets}/txwidget.ui                |  530 ++-
 qsstv/mainwindow.cpp                               |  472 +-
 qsstv/mainwindow.h                                 |   26 +-
 qsstv/mainwindow.ui                                |  114 +-
 qsstv/qsstv.pro                                    |  803 ++--
 qsstv/qsstv.qrc                                    |    6 +
 qsstv/qsstvglobal.cpp                              |   95 -
 qsstv/qsstvglobal.h                                |   88 -
 qsstv/rig/freqdisplay.ui                           |   13 +-
 qsstv/rig/rigcontrol.cpp                           |  466 +-
 qsstv/rig/rigcontrol.h                             |   79 +-
 qsstv/rig/rigcontrolform.cpp                       |    2 +-
 qsstv/rig/rigparams.h                              |   32 -
 qsstv/rxfunctions.cpp                              |  466 --
 qsstv/rxfunctions.h                                |   74 -
 qsstv/rxwidget.cpp                                 |  260 --
 qsstv/rxwidget.ui                                  |  877 ----
 qsstv/scope/scopeoffset.cpp                        |    2 +
 qsstv/scope/scopeoffset.h                          |    2 +
 qsstv/scope/scopeplot.cpp                          |    1 -
 qsstv/scope/scopeview.cpp                          |   30 +-
 qsstv/scope/scopeview.h                            |    5 +-
 qsstv/sound/calibration.cpp                        |  123 +-
 qsstv/sound/calibration.h                          |    2 +-
 qsstv/sound/calibration.ui                         |   26 +-
 qsstv/sound/calibrationform.ui                     |  127 -
 qsstv/sound/resampler.cpp                          |  146 -
 qsstv/sound/resampler.cpp_new                      |  147 -
 qsstv/sound/resampler.h                            |   28 -
 qsstv/sound/soundalsa.cpp                          |  341 ++
 qsstv/sound/soundalsa.h                            |   44 +
 qsstv/sound/soundbase.cpp                          |  431 ++
 qsstv/sound/soundbase.h                            |  120 +
 qsstv/sound/soundcontrol.cpp                       |  120 -
 qsstv/sound/soundcontrol.h                         |   31 -
 qsstv/sound/soundio.cpp                            |  855 ----
 qsstv/sound/soundio.cpp_new                        |  851 ----
 qsstv/sound/soundio.h                              |  142 -
 qsstv/sound/soundpulse.cpp                         |  177 +
 qsstv/sound/soundpulse.h                           |   43 +
 qsstv/sound/waterfalltext.cpp                      |  134 +-
 qsstv/sound/waterfalltext.h                        |   11 +-
 qsstv/sound/wavio.cpp                              |  213 +-
 qsstv/sound/wavio.h                                |    6 +-
 qsstv/sstv/cw.cpp                                  |  205 +-
 qsstv/sstv/cw.h                                    |    2 +-
 qsstv/sstv/modes/modeavt.cpp                       |   16 +-
 qsstv/sstv/modes/modeavt.h                         |    4 +-
 qsstv/sstv/modes/modebase.cpp                      |  512 ++-
 qsstv/sstv/modes/modebase.h                        |   83 +-
 qsstv/sstv/modes/modebw.cpp                        |   59 +-
 qsstv/sstv/modes/modebw.h                          |    2 +-
 qsstv/sstv/modes/modegbr.cpp                       |  201 +-
 qsstv/sstv/modes/modegbr.h                         |    2 +-
 qsstv/sstv/modes/modegbr2.cpp                      |  254 +-
 qsstv/sstv/modes/modegbr2.h                        |    5 +-
 qsstv/sstv/modes/modepd.cpp                        |  270 +-
 qsstv/sstv/modes/modepd.h                          |    2 +-
 qsstv/sstv/modes/modergb.cpp                       |  162 +-
 qsstv/sstv/modes/modergb.h                         |    2 +-
 qsstv/sstv/modes/moderobot1.cpp                    |  348 +-
 qsstv/sstv/modes/moderobot1.h                      |    4 +-
 qsstv/sstv/modes/moderobot2.cpp                    |  156 +-
 qsstv/sstv/modes/moderobot2.h                      |    2 +-
 qsstv/sstv/sstvparam.cpp                           |  126 +-
 qsstv/sstv/sstvparam.h                             |  141 +-
 qsstv/sstv/sstvrx.cpp                              |  438 ++
 qsstv/sstv/sstvrx.h                                |   75 +
 qsstv/sstv/sstvtx.cpp                              |  252 ++
 qsstv/sstv/sstvtx.h                                |   35 +
 qsstv/sstv/syncprocessor.cpp                       | 1421 +++---
 qsstv/sstv/syncprocessor.h                         |  297 +-
 qsstv/sstv/visfskid.cpp                            |  665 +++
 qsstv/sstv/visfskid.h                              |  154 +
 qsstv/txfunctions.cpp                              |  740 ----
 qsstv/txfunctions.h                                |  154 -
 qsstv/utils/arraydumper.cpp                        |  244 ++
 qsstv/utils/arraydumper.h                          |   14 +
 qsstv/utils/buffermanag.h                          |   19 +-
 qsstv/utils/color.cpp                              |  777 ++++
 qsstv/utils/color.h                                |   47 +
 qsstv/utils/dirdialog.cpp                          |  114 +
 qsstv/utils/dirdialog.h                            |   19 +
 qsstv/utils/fftcalc.cpp                            |   65 +
 qsstv/utils/fftcalc.h                              |   27 +
 qsstv/utils/ftp.cpp                                |  409 +-
 qsstv/utils/ftp.h                                  |   49 +-
 qsstv/utils/hexconvertor.cpp                       |   28 +
 qsstv/utils/hexconvertor.h                         |   10 +
 qsstv/utils/hybridcrypt.cpp                        |   58 +-
 qsstv/utils/jp2io.cpp                              |  612 +++
 qsstv/utils/jp2io.h                                |  111 +
 qsstv/utils/logging.cpp                            |   34 +-
 qsstv/utils/logging.h                              |   15 +-
 qsstv/utils/loggingform.ui                         |    3 +
 qsstv/utils/loggingparams.cpp                      |   74 +-
 qsstv/utils/loggingparams.h                        |   38 +-
 qsstv/utils/qftp.cpp                               |   63 +-
 qsstv/utils/qjp2io.cpp                             |  400 --
 qsstv/utils/qjp2io.h                               |   61 -
 qsstv/utils/qurlinfo.cpp                           |   20 +-
 qsstv/utils/reedsolomoncoder.cpp                   |   67 +-
 qsstv/utils/reedsolomoncoder.h                     |    4 +-
 qsstv/utils/supportfunctions.cpp                   |  285 +-
 qsstv/utils/supportfunctions.h                     |   22 +-
 qsstv/utils/vector.h                               |    2 +-
 qsstv/videocapt/cameradialog.cpp                   |  278 ++
 qsstv/videocapt/cameradialog.h                     |   99 +
 qsstv/videocapt/cameradialog.ui                    |  229 +
 qsstv/videocapt/imagesettings.cpp                  |  256 ++
 qsstv/videocapt/imagesettings.h                    |   82 +
 qsstv/videocapt/imagesettings.ui                   |  168 +
 qsstv/videocapt/v4l2control.cpp                    |  298 ++
 qsstv/videocapt/v4l2control.h                      |  108 +
 qsstv/videocapt/videocapture.cpp                   |  870 +---
 qsstv/videocapt/videocapture.h                     |   58 +-
 qsstv/widgets/blockview.cpp                        |   55 -
 qsstv/widgets/blockview.h                          |   34 -
 qsstv/widgets/blockview.ui                         |   28 -
 qsstv/widgets/cameracontrol.cpp                    |  144 -
 qsstv/widgets/cameracontrol.h                      |   46 -
 qsstv/widgets/cameracontrol.ui                     |  400 --
 qsstv/widgets/drmsegmentsview.cpp                  |   75 +
 qsstv/widgets/drmsegmentsview.h                    |   37 +
 qsstv/widgets/drmsegmentsview.ui                   |   55 +
 qsstv/widgets/extviewer.cpp                        |   31 +
 qsstv/widgets/extviewer.h                          |   30 +
 qsstv/widgets/extviewer.ui                         |   44 +
 qsstv/widgets/fftdisplay.cpp                       |  304 +-
 qsstv/widgets/fftdisplay.h                         |   52 +-
 qsstv/widgets/imagematrix.cpp                      |  219 +
 qsstv/widgets/imagematrix.h                        |   60 +
 qsstv/widgets/imageviewer.cpp                      |  682 +--
 qsstv/widgets/imageviewer.h                        |   87 +-
 qsstv/widgets/qscale.cpp                           |  371 --
 qsstv/widgets/qscale.h                             |  111 -
 qsstv/widgets/spectrumwidget.cpp                   |   96 +-
 qsstv/widgets/spectrumwidget.h                     |   13 +-
 qsstv/widgets/spectrumwidget.ui                    |  595 ++-
 qsstv/widgets/vumeter.cpp                          |   18 +-
 qsstv/widgets/vumeter.h                            |    1 +
 qsstv/widgets/waterfallform.cpp                    |    2 +-
 qsstv/widgets/waterfallform.ui                     |   26 +-
 qsstv/widgets/xyzplaintextedit.cpp                 |   14 +
 qsstv/widgets/xyzplaintextedit.h                   |   21 +
 qsstv/xmlrpc/ipcmessage.cpp                        |   15 +-
 qsstv/xmlrpc/maiaObject.cpp                        |   10 +-
 qsstv/xmlrpc/maiaXmlRpcServer.cpp                  |    7 +-
 qsstv/xmlrpc/maiaXmlRpcServerConnection.cpp        |   23 +-
 qsstv/xmlrpc/maiaXmlRpcServerConnection.h          |    1 +
 qsstv/xmlrpc/xmlinterface.cpp                      |   18 +-
 qsstv/xmlrpc/xmlinterface.h                        |    2 +
 qsstv_8_2.pro => qsstv_9_1.pro                     |   10 +-
 qwt/qwt_transform.cpp                              |    4 +-
 qwt/qwt_transform.h                                |    4 +-
 475 files changed, 37221 insertions(+), 26625 deletions(-)

diff --git a/qsstv/COPYING b/COPYING
similarity index 100%
rename from qsstv/COPYING
rename to COPYING
diff --git a/README.txt b/README.txt
new file mode 100644
index 0000000..7da08df
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,7 @@
+For the full manual please go to
+http://users.telenet.be/on4qz/qsstv_9/manual/index.html
+
+There you'll find the complete installation instructions wich is part of the user manual.
+
+
+
diff --git a/qsstv/qsstvdefs.h b/qsstv/appdefs.h
similarity index 52%
rename from qsstv/qsstvdefs.h
rename to qsstv/appdefs.h
index c93b293..3cd9708 100644
--- a/qsstv/qsstvdefs.h
+++ b/qsstv/appdefs.h
@@ -1,25 +1,24 @@
+#ifndef APPDEFS_H
+#define APPDEFS_H
 #include <stdint.h>
 #include <complex>
 using namespace std; /* Because of the library: "complex" */
-#ifndef QSSTVDEFS_H
-#define QSSTVDEFS_H
 
-#define RXSTRIPE 1024
-#define TXSTRIPE 1024
-#define SUBSAMPLINGRATIO 4
-
-#define SAMPLINGSTRIPE (SUBSAMPLINGRATIO*RXSTRIPE) // 4 times oversampled
-
-#define MAXNUMCHANNELS 2
 #define SOUNDFRAME  quint32
-#define BASESAMPLERATE 48000.
-#define SAMPLERATE (BASESAMPLERATE/SUBSAMPLINGRATIO)
 
+#define BASESAMPLERATE 48000
+#define SUBSAMPLINGFACTOR 4
+#define MONOCHANNEL 1
+#define STEREOCHANNEL 2
+#define RXSTRIPE 1024
+#define TXSTRIPE 1024
+#define FILTERPARAMTYPE double
+#define DOWNSAMPLESIZE (SUBSAMPLINGFACTOR*RXSTRIPE)
+#define SAMPLERATE (BASESAMPLERATE/SUBSAMPLINGFACTOR)
 
-//typedef double DSPFLOAT;
-typedef float DSPFLOAT;
+typedef double DSPFLOAT;
 typedef unsigned char byte;
-enum etransmissionMode {SSTV,DRM,NOMODE};
+
 
 /* Define the application specific data-types ------------------------------- */
 typedef	double							_REAL;
@@ -29,9 +28,4 @@ typedef unsigned char				_BYTE;
 typedef bool							  _BOOLEAN;
 typedef unsigned char 			_BINARY;
 
-#ifndef false
-#define false false
-#define true true
-#endif
-
-#endif // QSSTVDEFS_H
+#endif // APPDEFS_H
diff --git a/qsstv/appglobal.cpp b/qsstv/appglobal.cpp
new file mode 100644
index 0000000..a2c3595
--- /dev/null
+++ b/qsstv/appglobal.cpp
@@ -0,0 +1,76 @@
+#include "appglobal.h"
+#include "logging.h"
+#include "soundbase.h"
+#include <QPixmap>
+#include <QCursor>
+
+
+const QString MAJORVERSION  = "9.1";
+const QString CONFIGVERSION = "9.0";
+const QString MINORVERSION  = ".5";
+const QString LOGVERSION = ("qsstv."+MAJORVERSION+MINORVERSION+".log");
+const QString ORGANIZATION = "ON4QZ";
+const QString APPLICATION  = ("qsstv_" +CONFIGVERSION);
+const QString qsstvVersion=QString("QSSTV " + MAJORVERSION+MINORVERSION);
+const QString shortName=QString("QSSTV");
+
+
+QSplashScreen *splashPtr;
+QString splashStr;
+
+mainWindow *mainWindowPtr;
+soundBase *soundIOPtr;
+logFile *logFilePtr;
+configDialog *configDialogPtr;
+
+
+
+dispatcher *dispatcherPtr;
+QStatusBar *statusBarPtr;
+rxWidget *rxWidgetPtr;
+txWidget *txWidgetPtr;
+galleryWidget *galleryWidgetPtr;
+waterfallText *waterfallPtr;
+rigControl *rigControllerPtr;
+xmlInterface *xmlIntfPtr;
+logBook *logBookPtr;
+
+bool useHybrid;
+
+
+
+
+
+etransmissionMode transmissionModeIndex;  // SSTV , DRM
+
+
+
+QPixmap *greenPXMPtr;
+QPixmap *redPXMPtr;
+
+#ifndef QT_NO_DEBUG
+scopeView *scopeViewerData;
+scopeView *scopeViewerSyncNarrow;
+scopeView *scopeViewerSyncWide;
+#endif
+
+
+void globalInit()
+{
+  logFilePtr=new logFile();
+  logFilePtr->open(LOGVERSION);
+  QSettings qSettings;
+  qSettings.beginGroup("MAIN");
+  logFilePtr->readSettings();
+  greenPXMPtr=new QPixmap(16,16);
+  greenPXMPtr->fill(Qt::green);
+  redPXMPtr=new QPixmap(16,16);
+  redPXMPtr->fill(Qt::red);
+  qSettings.endGroup();
+}
+
+void globalEnd(void)
+{
+  logFilePtr->close();
+}
+
diff --git a/qsstv/appglobal.h b/qsstv/appglobal.h
new file mode 100644
index 0000000..7509270
--- /dev/null
+++ b/qsstv/appglobal.h
@@ -0,0 +1,72 @@
+#ifndef APPGLOBAL_H
+#define APPGLOBAL_H
+#include "logging.h"
+//#include "mainwindow.h"
+#include "appdefs.h"
+
+class QSplashScreen;
+class scopeView;
+class rxWidget;
+class txWidget;
+class galleryWidget;
+class waterfallText;
+class rigControl;
+class xmlInterface;
+class logBook;
+class dispatcher;
+
+enum etransmissionMode {TRXSSTV,TRXDRM,TRXNOMODE};
+
+extern const QString MAJORVERSION;
+extern const QString CONFIGVERSION;
+extern const QString MINORVERSION;
+extern  const QString ORGANIZATION;
+extern const QString APPLICATION;
+extern const QString qsstvVersion;
+extern const QString shortName;
+#define MAGICNUMBER   (('4'<<24)+('Q'<<16)+('Z'<<8)+'S')
+
+class soundBase;
+class mainWindow;
+class QStatusBar;
+class configDialog;
+
+extern mainWindow *mainWindowPtr;
+extern soundBase *soundIOPtr;
+extern QSplashScreen *splashPtr;
+extern QString splashStr;
+extern dispatcher *dispatcherPtr;
+extern QStatusBar *statusBarPtr;
+
+
+extern rxWidget *rxWidgetPtr;
+extern txWidget *txWidgetPtr;
+extern galleryWidget *galleryWidgetPtr;
+extern waterfallText *waterfallPtr;
+extern rigControl *rigControllerPtr;
+extern xmlInterface *xmlIntfPtr;
+extern configDialog *configDialogPtr;
+extern logBook *logBookPtr;
+
+
+extern QPixmap *greenPXMPtr;
+extern QPixmap *redPXMPtr;
+
+extern logFile *logFilePtr;
+extern bool useHybrid;
+
+
+
+extern etransmissionMode transmissionModeIndex;  // SSTV , DRM
+
+
+#ifndef QT_NO_DEBUG
+extern scopeView *scopeViewerData;
+extern scopeView *scopeViewerSyncNarrow;
+extern scopeView *scopeViewerSyncWide;
+#endif
+
+void globalInit(void);
+void globalEnd(void);
+
+#endif // APPGLOBAL_H
diff --git a/qsstv/config/baseconfig.cpp b/qsstv/config/baseconfig.cpp
new file mode 100644
index 0000000..02939cf
--- /dev/null
+++ b/qsstv/config/baseconfig.cpp
@@ -0,0 +1,6 @@
+#include "baseconfig.h"
+
+baseConfig::baseConfig(QWidget *parent):QWidget(parent)
+{
+  changed=false;
+}
diff --git a/qsstv/config/baseconfig.h b/qsstv/config/baseconfig.h
new file mode 100644
index 0000000..71352ea
--- /dev/null
+++ b/qsstv/config/baseconfig.h
@@ -0,0 +1,22 @@
+#ifndef BASECONFIG_H
+#define BASECONFIG_H
+
+#include <QString>
+#include <QWidget>
+#include <QSettings>
+#include "utils/supportfunctions.h"
+
+class baseConfig: public QWidget
+{
+public:
+  baseConfig(QWidget *parent = 0);
+  virtual void readSettings()=0;
+  virtual void writeSettings()=0;
+  virtual void getParams()=0;
+  virtual void setParams()=0;
+  bool hasChanged() {return changed;}
+protected:
+  bool changed;
+};
+
+#endif // BASECONFIG_H
diff --git a/qsstv/config/configdialog.cpp b/qsstv/config/configdialog.cpp
new file mode 100644
index 0000000..fec1bf6
--- /dev/null
+++ b/qsstv/config/configdialog.cpp
@@ -0,0 +1,86 @@
+#include "configdialog.h"
+#include "ui_configdialog.h"
+#include "gallerywidget.h"
+#include "mainwindow.h"
+
+
+configDialog::configDialog(QWidget *parent) :
+  QDialog(parent),
+  ui(new Ui::configDialog)
+{
+  ui->setupUi(this);
+  ui->catWidget->attachRigController(rigControllerPtr);
+  ui->configTabWidget->setCurrentIndex(0);
+}
+
+configDialog::~configDialog()
+{
+  delete ui;
+}
+
+void configDialog::readSettings()
+{
+  ui->cwWidget->readSettings();
+  ui->directoryWidget->readSettings();
+  ui->drmProfilesWidget->readSettings();
+  ui->ftpWidget->readSettings();
+  ui->guiWidget->readSettings();
+  ui->hybridWidget->readSettings();
+  ui->hybridNotifyWidget->readSettings();
+  ui->operatorWidget->readSettings();
+  ui->repeaterWidget->readSettings();
+  ui->catWidget->readSettings();
+  ui->soundWidget->readSettings();
+  ui->waterfallWidget->readSettings();
+  ui->freqSelectWidget->readSettings();
+}
+
+void configDialog::writeSettings()
+{
+  ui->operatorWidget->writeSettings();
+  ui->directoryWidget->writeSettings();
+  ui->soundWidget->writeSettings();
+  ui->guiWidget->writeSettings();
+  ui->catWidget->writeSettings();
+  ui->ftpWidget->writeSettings();
+  ui->repeaterWidget->writeSettings();
+  ui->hybridWidget->writeSettings();
+  ui->hybridNotifyWidget->writeSettings();
+  ui->drmProfilesWidget->writeSettings();
+  ui->cwWidget->writeSettings();
+  ui->waterfallWidget->writeSettings();
+  soundNeedsRestart=ui->soundWidget->hasChanged();
+  guiNeedsRestart=ui->guiWidget->hasChanged();
+  ui->freqSelectWidget->writeSettings();
+  if(ui->guiWidget->backGroundColorChanged)
+    {
+      emit bgColorChanged();
+      ui->guiWidget->backGroundColorChanged=false;
+    }
+
+}
+
+/**
+    Opens the configuration dialog
+*/
+
+int configDialog::exec()
+{
+  if(QDialog::exec())
+  {
+    writeSettings();
+    if(ui->directoryWidget->hasChanged() || ui->guiWidget->hasChanged())
+      {
+        galleryWidgetPtr->changedMatrix();
+      }
+    mainWindowPtr->setSSTVDRMPushButton(transmissionModeIndex==TRXDRM);
+
+    return QDialog::Accepted;
+  }
+  else
+  {
+    return QDialog::Rejected;
+  }
+}
+
+
diff --git a/qsstv/config/configdialog.h b/qsstv/config/configdialog.h
new file mode 100644
index 0000000..c954c35
--- /dev/null
+++ b/qsstv/config/configdialog.h
@@ -0,0 +1,33 @@
+#ifndef CONFIGDIALOG_H
+#define CONFIGDIALOG_H
+
+#include <QDialog>
+
+namespace Ui {
+class configDialog;
+}
+
+class configDialog : public QDialog
+{
+  Q_OBJECT
+
+public:
+  explicit configDialog(QWidget *parent = 0);
+  ~configDialog();
+  void readSettings();
+  void writeSettings();
+  int exec();
+  bool soundNeedsRestart;
+  bool guiNeedsRestart;
+
+
+signals:
+  void bgColorChanged();
+
+
+private:
+  Ui::configDialog *ui;
+
+};
+
+#endif // CONFIGDIALOG_H
diff --git a/qsstv/config/configdialog.ui b/qsstv/config/configdialog.ui
new file mode 100644
index 0000000..c97b795
--- /dev/null
+++ b/qsstv/config/configdialog.ui
@@ -0,0 +1,281 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>configDialog</class>
+ <widget class="QDialog" name="configDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>818</width>
+    <height>438</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Configuration</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QTabWidget" name="configTabWidget">
+     <property name="currentIndex">
+      <number>10</number>
+     </property>
+     <widget class="QWidget" name="operatorTab">
+      <attribute name="title">
+       <string>Operator</string>
+      </attribute>
+      <layout class="QVBoxLayout" name="verticalLayout_4">
+       <item>
+        <widget class="operatorConfig" name="operatorWidget" native="true"/>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="directoryTab">
+      <attribute name="title">
+       <string>Directories</string>
+      </attribute>
+      <layout class="QVBoxLayout" name="verticalLayout_3">
+       <item>
+        <widget class="directoriesConfig" name="directoryWidget" native="true"/>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="guiTab">
+      <attribute name="title">
+       <string>Gui</string>
+      </attribute>
+      <layout class="QVBoxLayout" name="verticalLayout_5">
+       <item>
+        <widget class="guiConfig" name="guiWidget" native="true"/>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="soundTab">
+      <attribute name="title">
+       <string>Sound</string>
+      </attribute>
+      <layout class="QVBoxLayout" name="verticalLayout_2">
+       <item>
+        <widget class="soundConfig" name="soundWidget" native="true"/>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="catTab">
+      <attribute name="title">
+       <string>CAT</string>
+      </attribute>
+      <layout class="QVBoxLayout" name="verticalLayout_6">
+       <item>
+        <widget class="rigConfig" name="catWidget" native="true"/>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="cwTab">
+      <attribute name="title">
+       <string>CW</string>
+      </attribute>
+      <layout class="QVBoxLayout" name="verticalLayout_7">
+       <item>
+        <widget class="cwConfig" name="cwWidget" native="true"/>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="repeaterTab">
+      <attribute name="title">
+       <string>Repeater</string>
+      </attribute>
+      <layout class="QVBoxLayout" name="verticalLayout_8">
+       <item>
+        <widget class="repeaterConfig" name="repeaterWidget" native="true"/>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="ftpTab">
+      <attribute name="title">
+       <string>FTP</string>
+      </attribute>
+      <layout class="QVBoxLayout" name="verticalLayout_9">
+       <item>
+        <widget class="ftpConfig" name="ftpWidget" native="true"/>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="waterfallTab">
+      <attribute name="title">
+       <string>Waterfall</string>
+      </attribute>
+      <layout class="QVBoxLayout" name="verticalLayout_10">
+       <item>
+        <widget class="waterfallConfig" name="waterfallWidget" native="true"/>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="hybridTab">
+      <attribute name="title">
+       <string>Hybrid</string>
+      </attribute>
+      <layout class="QVBoxLayout" name="verticalLayout_11">
+       <item>
+        <widget class="hybridConfig" name="hybridWidget" native="true"/>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="notifyTab">
+      <attribute name="title">
+       <string>Notifications</string>
+      </attribute>
+      <layout class="QVBoxLayout" name="verticalLayout_11a">
+       <item>
+        <widget class="hybridNotifyConfig" name="hybridNotifyWidget" native="true"/>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="profilesTab">
+      <attribute name="title">
+       <string>DRM Profiles</string>
+      </attribute>
+      <layout class="QVBoxLayout" name="verticalLayout_12">
+       <item>
+        <widget class="drmProfileConfig" name="drmProfilesWidget" native="true"/>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="frequenciesTab">
+      <attribute name="title">
+       <string>Frequencies</string>
+      </attribute>
+      <layout class="QHBoxLayout" name="horizontalLayout" stretch="0">
+       <item>
+        <widget class="frequencySelectWidget" name="freqSelectWidget" native="true"/>
+       </item>
+      </layout>
+     </widget>
+    </widget>
+   </item>
+   <item>
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>soundConfig</class>
+   <extends>QWidget</extends>
+   <header>soundconfig.h</header>
+   <container>1</container>
+  </customwidget>
+  <customwidget>
+   <class>directoriesConfig</class>
+   <extends>QWidget</extends>
+   <header>directoriesconfig.h</header>
+   <container>1</container>
+  </customwidget>
+  <customwidget>
+   <class>operatorConfig</class>
+   <extends>QWidget</extends>
+   <header>operatorconfig.h</header>
+   <container>1</container>
+  </customwidget>
+  <customwidget>
+   <class>guiConfig</class>
+   <extends>QWidget</extends>
+   <header>guiconfig.h</header>
+   <container>1</container>
+  </customwidget>
+  <customwidget>
+   <class>rigConfig</class>
+   <extends>QWidget</extends>
+   <header>rigconfig.h</header>
+   <container>1</container>
+  </customwidget>
+  <customwidget>
+   <class>cwConfig</class>
+   <extends>QWidget</extends>
+   <header>cwconfig.h</header>
+   <container>1</container>
+  </customwidget>
+  <customwidget>
+   <class>repeaterConfig</class>
+   <extends>QWidget</extends>
+   <header>repeaterconfig.h</header>
+   <container>1</container>
+  </customwidget>
+  <customwidget>
+   <class>ftpConfig</class>
+   <extends>QWidget</extends>
+   <header>ftpconfig.h</header>
+   <container>1</container>
+  </customwidget>
+  <customwidget>
+   <class>waterfallConfig</class>
+   <extends>QWidget</extends>
+   <header>waterfallconfig.h</header>
+   <container>1</container>
+  </customwidget>
+  <customwidget>
+   <class>hybridConfig</class>
+   <extends>QWidget</extends>
+   <header>hybridconfig.h</header>
+   <container>1</container>
+  </customwidget>
+  <customwidget>
+   <class>drmProfileConfig</class>
+   <extends>QWidget</extends>
+   <header>drmprofileconfig.h</header>
+   <container>1</container>
+  </customwidget>
+  <customwidget>
+   <class>frequencySelectWidget</class>
+   <extends>QWidget</extends>
+   <header>frequencyselectwidget.h</header>
+   <container>1</container>
+  </customwidget>
+  <customwidget>
+   <class>hybridNotifyConfig</class>
+   <extends>QWidget</extends>
+   <header>hybridnotifyconfig.h</header>
+   <container>1</container>
+  </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>configDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>configDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/qsstv/config/configparams.h b/qsstv/config/configparams.h
new file mode 100644
index 0000000..8efe02e
--- /dev/null
+++ b/qsstv/config/configparams.h
@@ -0,0 +1,18 @@
+#ifndef CONFIGPARAMS_H
+#define CONFIGPARAMS_H
+
+#include "cwconfig.h"
+#include "directoriesconfig.h"
+#include "drmprofileconfig.h"
+#include "ftpconfig.h"
+#include "guiconfig.h"
+#include "hybridconfig.h"
+#include "hybridnotifyconfig.h"
+#include "operatorconfig.h"
+#include "repeaterconfig.h"
+#include "rigconfig.h"
+#include "soundconfig.h"
+#include "waterfallconfig.h"
+#include "frequencyselectwidget.h"
+
+#endif // CONFIGPARAMS_H
diff --git a/qsstv/config/cwconfig.cpp b/qsstv/config/cwconfig.cpp
new file mode 100644
index 0000000..d6667f9
--- /dev/null
+++ b/qsstv/config/cwconfig.cpp
@@ -0,0 +1,67 @@
+#include "cwconfig.h"
+#include "ui_cwconfig.h"
+
+QString cwText;
+int cwTone;
+int cwWPM;
+bool enableCW;
+
+cwConfig::cwConfig(QWidget *parent) :  baseConfig(parent), ui(new Ui::cwConfig)
+{
+  ui->setupUi(this);
+}
+
+cwConfig::~cwConfig()
+{
+  delete ui;
+}
+
+void cwConfig::readSettings()
+{
+  QSettings qSettings;
+  qSettings.beginGroup("CW");
+  cwText=qSettings.value("cwtext","").toString();
+  cwTone=qSettings.value("cwtone",800).toInt();
+  cwWPM=qSettings.value("cwWPM",12).toInt();
+  enableCW=qSettings.value("enableCW",false).toBool();
+  qSettings.endGroup();
+  setParams();
+}
+
+void cwConfig::writeSettings()
+{
+  QSettings qSettings;
+  getParams();
+
+  qSettings.beginGroup("CW");
+  qSettings.setValue("cwtext",cwText);
+  qSettings.setValue("cwtone",cwTone);
+  qSettings.setValue("cwWPM",cwWPM);
+  qSettings.setValue("enableCW",enableCW);
+  qSettings.endGroup();
+}
+
+void cwConfig::getParams()
+{
+  QString cwTextCopy=cwText;
+  int cwToneCopy=cwTone;
+  int cwWPMCopy=cwWPM;
+  getValue(cwText,ui->cwTextLineEdit);
+  getValue(cwTone,ui->cwToneSpinBox);
+  getValue(cwWPM,ui->cwWPMSpinBox);
+  getValue(enableCW,ui->enableCWCheckBox);
+  changed=false;
+  if(cwTextCopy!=cwText
+     || cwToneCopy!=cwTone
+     || cwWPMCopy!=cwWPM)
+    changed=true;
+}
+
+void cwConfig::setParams()
+{
+  setValue(cwText,ui->cwTextLineEdit);
+  setValue(cwTone,ui->cwToneSpinBox);
+  setValue(cwWPM,ui->cwWPMSpinBox);
+  setValue(enableCW,ui->enableCWCheckBox);
+
+}
diff --git a/qsstv/config/cwconfig.h b/qsstv/config/cwconfig.h
new file mode 100644
index 0000000..44dd9e1
--- /dev/null
+++ b/qsstv/config/cwconfig.h
@@ -0,0 +1,32 @@
+#ifndef CWCONFIG_H
+#define CWCONFIG_H
+
+#include "baseconfig.h"
+
+extern QString cwText;
+extern int cwTone;
+extern int cwWPM;
+extern bool enableCW;
+
+
+namespace Ui {
+class cwConfig;
+}
+
+class cwConfig : public baseConfig
+{
+  Q_OBJECT
+  
+public:
+  explicit cwConfig(QWidget *parent = 0);
+  ~cwConfig();
+  void readSettings();
+  void writeSettings();
+  void getParams();
+  void setParams();
+  
+private:
+  Ui::cwConfig *ui;
+};
+
+#endif // CWCONFIG_H
diff --git a/qsstv/config/cwconfig.ui b/qsstv/config/cwconfig.ui
new file mode 100644
index 0000000..a78977f
--- /dev/null
+++ b/qsstv/config/cwconfig.ui
@@ -0,0 +1,267 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>cwConfig</class>
+ <widget class="QWidget" name="cwConfig">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>539</width>
+    <height>357</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <widget class="QCheckBox" name="enableCWCheckBox">
+       <property name="layoutDirection">
+        <enum>Qt::RightToLeft</enum>
+       </property>
+       <property name="text">
+        <string>Enable CW</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="_3">
+     <property name="spacing">
+      <number>6</number>
+     </property>
+     <property name="leftMargin">
+      <number>0</number>
+     </property>
+     <property name="topMargin">
+      <number>0</number>
+     </property>
+     <property name="rightMargin">
+      <number>0</number>
+     </property>
+     <property name="bottomMargin">
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="QLabel" name="wpmLabel">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>145</width>
+         <height>25</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>Words PerMinute</string>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QSpinBox" name="cwWPMSpinBox">
+       <property name="minimum">
+        <number>4</number>
+       </property>
+       <property name="maximum">
+        <number>30</number>
+       </property>
+       <property name="value">
+        <number>12</number>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeType">
+        <enum>QSizePolicy::Expanding</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>20</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="_2" stretch="0,1,0">
+     <property name="spacing">
+      <number>6</number>
+     </property>
+     <property name="leftMargin">
+      <number>0</number>
+     </property>
+     <property name="topMargin">
+      <number>0</number>
+     </property>
+     <property name="rightMargin">
+      <number>0</number>
+     </property>
+     <property name="bottomMargin">
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="QLabel" name="textToSendLabel">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>145</width>
+         <height>25</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>Text to send</string>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="cwTextLineEdit"/>
+     </item>
+     <item>
+      <spacer>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeType">
+        <enum>QSizePolicy::Expanding</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>20</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout">
+     <property name="spacing">
+      <number>6</number>
+     </property>
+     <property name="leftMargin">
+      <number>0</number>
+     </property>
+     <property name="topMargin">
+      <number>0</number>
+     </property>
+     <property name="rightMargin">
+      <number>0</number>
+     </property>
+     <property name="bottomMargin">
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="QLabel" name="toneLabel">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>145</width>
+         <height>25</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>Tone</string>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QSpinBox" name="cwToneSpinBox">
+       <property name="minimum">
+        <number>300</number>
+       </property>
+       <property name="maximum">
+        <number>2300</number>
+       </property>
+       <property name="singleStep">
+        <number>50</number>
+       </property>
+       <property name="value">
+        <number>800</number>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeType">
+        <enum>QSizePolicy::Expanding</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>20</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <spacer name="spacer">
+     <property name="orientation">
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeType">
+      <enum>QSizePolicy::Expanding</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>20</width>
+       <height>54</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/qsstv/config/directoriesconfig.cpp b/qsstv/config/directoriesconfig.cpp
new file mode 100644
index 0000000..c0b4834
--- /dev/null
+++ b/qsstv/config/directoriesconfig.cpp
@@ -0,0 +1,184 @@
+#include "directoriesconfig.h"
+#include "ui_directoriesconfig.h"
+
+
+QString rxSSTVImagesPath;
+QString rxDRMImagesPath;
+QString txSSTVImagesPath;
+QString txDRMImagesPath;
+QString txStockImagesPath;
+QString templatesPath;
+QString audioPath;
+bool saveTXimages;
+QString docURL;
+
+
+
+directoriesConfig::directoriesConfig(QWidget *parent) :baseConfig(parent),
+  ui(new Ui::directoriesConfig)
+{
+  ui->setupUi(this);
+  connect(ui->rxSSTVImagesPathBrowseButton,SIGNAL(clicked()),SLOT(slotBrowseRxSSTVImagesPath()));
+  connect(ui->rxDRMImagesPathBrowseButton,SIGNAL(clicked()),SLOT(slotBrowseRxDRMImagesPath()));
+  connect(ui->txSSTVImagesPathBrowseButton,SIGNAL(clicked()),SLOT(slotBrowseTxSSTVImagesPath()));
+  connect(ui->txDRMImagesPathBrowseButton,SIGNAL(clicked()),SLOT(slotBrowseTxDRMImagesPath()));
+  connect(ui->txStockImagesPathBrowseButton,SIGNAL(clicked()),SLOT(slotBrowseTxStockImagesPath()));
+  connect(ui->templatesPathBrowseButton,SIGNAL(clicked()),SLOT(slotBrowseTemplatesPath()));
+  connect(ui->audioPathBrowseButton,SIGNAL(clicked()),SLOT(slotBrowseAudioPath()));
+}
+
+directoriesConfig::~directoriesConfig()
+{
+  delete ui;
+}
+
+void directoriesConfig::readSettings()
+{
+  QSettings qSettings;
+  qSettings.beginGroup("DIRECTORIES");
+  rxSSTVImagesPath=qSettings.value("rxSSTVImagesPath",QString(getenv("HOME"))+"/qsstv/rx_sstv/").toString();
+  rxDRMImagesPath=qSettings.value("rxDRMImagesPath",QString(getenv("HOME"))+"/qsstv/rx_drm/").toString();
+  txSSTVImagesPath=qSettings.value("txSSTVImagesPath",QString(getenv("HOME"))+"/qsstv/tx_sstv/").toString();
+  txDRMImagesPath=qSettings.value("txDRMImagesPath",QString(getenv("HOME"))+"/tx_drm/").toString();
+  txStockImagesPath=qSettings.value("txStockImagesPath",QString(getenv("HOME"))+"/tx_stock/").toString();
+  templatesPath=qSettings.value("templatesPath",QString(getenv("HOME"))+"/templates/").toString();
+  audioPath=qSettings.value("audioPath",QString(getenv("HOME"))+"/audio/").toString();
+  docURL=qSettings.value("docURL","http://users.telenet.be/on4qz/qsstv_9/manual").toString();
+  saveTXimages=qSettings.value("saveTXimages",false).toBool();
+  qSettings.endGroup();
+  setParams();
+}
+
+void directoriesConfig::writeSettings()
+{
+  QSettings qSettings;
+  getParams();
+  qSettings.beginGroup("DIRECTORIES");
+  qSettings.setValue("rxSSTVImagesPath",rxSSTVImagesPath);
+  qSettings.setValue("rxDRMImagesPath",rxDRMImagesPath);
+  qSettings.setValue("txSSTVImagesPath",txSSTVImagesPath);
+  qSettings.setValue("txDRMImagesPath",txDRMImagesPath);
+  qSettings.setValue("txStockImagesPath",txStockImagesPath);
+  qSettings.setValue("templatesPath",templatesPath);
+  qSettings.setValue("audioPath",audioPath);
+  qSettings.setValue("docURL",docURL);
+  qSettings.setValue("saveTXimages",saveTXimages);
+
+  qSettings.endGroup();
+}
+
+void directoriesConfig::getParams()
+{
+  QString rxSSTVImagePathSaved=rxSSTVImagesPath;
+  QString rxDRMImagePathSaved=rxDRMImagesPath;
+  QString txSSTVImagePathSaved=txSSTVImagesPath;
+  QString txDRMImagePathSaved=txDRMImagesPath;
+  QString txStockImagePathSaved=txStockImagesPath;
+  QString templatesPathSaved=templatesPath;
+  getValue(rxSSTVImagesPath,ui->rxSSTVImagesPathLineEdit);
+  getValue(rxDRMImagesPath,ui->rxDRMImagesPathLineEdit);
+  getValue(txSSTVImagesPath,ui->txSSTVImagesPathLineEdit);
+  getValue(txDRMImagesPath,ui->txDRMImagesPathLineEdit);
+  getValue(txStockImagesPath,ui->txStockImagesPathLineEdit);
+  getValue(templatesPath,ui->templatesPathLineEdit);
+  getValue(audioPath,ui->audioPathLineEdit);
+  getValue(docURL,ui->docPathLineEdit);
+  getValue(saveTXimages,ui->saveTXcheckBox);
+  changed=false;
+  if(rxSSTVImagePathSaved!=rxSSTVImagesPath || rxDRMImagePathSaved!=rxDRMImagesPath ||
+     txSSTVImagePathSaved!=txSSTVImagesPath ||
+     txDRMImagePathSaved!=txDRMImagesPath ||
+     txStockImagePathSaved!=txStockImagesPath ||
+     templatesPathSaved!=templatesPath
+     )
+    changed=true; // always save it
+}
+
+void directoriesConfig::setParams()
+{
+  setValue(rxSSTVImagesPath,ui->rxSSTVImagesPathLineEdit);
+  setValue(rxDRMImagesPath,ui->rxDRMImagesPathLineEdit);
+  setValue(txSSTVImagesPath,ui->txSSTVImagesPathLineEdit);
+  setValue(txDRMImagesPath,ui->txDRMImagesPathLineEdit);
+  setValue(txStockImagesPath,ui->txStockImagesPathLineEdit);
+  setValue(templatesPath,ui->templatesPathLineEdit);
+  setValue(audioPath,ui->audioPathLineEdit);
+  setValue(docURL,ui->docPathLineEdit);
+  setValue(saveTXimages,ui->saveTXcheckBox);
+  // create directories if not exist
+  createDir(rxSSTVImagesPath);
+  createDir(rxDRMImagesPath);
+  createDir(txSSTVImagesPath);
+  createDir(txDRMImagesPath);
+  createDir(txStockImagesPath);
+  createDir(templatesPath);
+
+  createDir(rxSSTVImagesPath+"/cache");
+  createDir(rxDRMImagesPath+"/cache");
+  createDir(txSSTVImagesPath+"/cache");
+  createDir(txDRMImagesPath+"/cache");
+  createDir(txStockImagesPath+"/cache");
+  createDir(audioPath);
+}
+
+void directoriesConfig::createDir(QString path)
+{
+  QDir dd(path);
+  if(!dd.exists())
+  {
+      dd.mkpath(path);
+  }
+}
+
+
+/**
+  Browse function for path where the rximages are stored
+*/
+
+
+void directoriesConfig::slotBrowseRxSSTVImagesPath()
+{
+  browseDir(ui->rxSSTVImagesPathLineEdit,rxSSTVImagesPath);
+}
+
+void directoriesConfig::slotBrowseRxDRMImagesPath()
+{
+  browseDir(ui->rxDRMImagesPathLineEdit,rxDRMImagesPath);
+}
+
+/**
+  Browse function for path where the tximages are stored
+*/
+
+void directoriesConfig::slotBrowseTxSSTVImagesPath()
+{
+  browseDir(ui->txSSTVImagesPathLineEdit,txSSTVImagesPath);
+}
+
+void directoriesConfig::slotBrowseTxDRMImagesPath()
+{
+  browseDir(ui->txDRMImagesPathLineEdit,txDRMImagesPath);
+}
+
+void directoriesConfig::slotBrowseTxStockImagesPath()
+{
+  browseDir(ui->txStockImagesPathLineEdit,txStockImagesPath);
+}
+
+/**
+  Browse function for path where the templates are stored
+*/
+
+void directoriesConfig::slotBrowseTemplatesPath()
+{
+  browseDir(ui->templatesPathLineEdit,templatesPath);
+}
+
+/**
+  Browse function for audio path
+*/
+
+void directoriesConfig::slotBrowseAudioPath()
+{
+  browseDir(ui->audioPathLineEdit,audioPath);
+}
diff --git a/qsstv/config/directoriesconfig.h b/qsstv/config/directoriesconfig.h
new file mode 100644
index 0000000..5fb911f
--- /dev/null
+++ b/qsstv/config/directoriesconfig.h
@@ -0,0 +1,46 @@
+#ifndef DIRECTORIES_H
+#define DIRECTORIES_H
+
+#include "baseconfig.h"
+
+extern QString rxSSTVImagesPath;
+extern QString rxDRMImagesPath;
+extern QString txSSTVImagesPath;
+extern QString txDRMImagesPath;
+extern QString txStockImagesPath;
+extern QString templatesPath;
+extern QString audioPath;
+extern bool saveTXimages;
+extern QString docURL;
+
+namespace Ui {
+class directoriesConfig;
+}
+
+class directoriesConfig : public baseConfig
+{
+  Q_OBJECT
+  
+public:
+  explicit directoriesConfig(QWidget *parent = 0);
+  ~directoriesConfig();
+  void readSettings();
+  void writeSettings();
+  void getParams();
+  void setParams();
+
+private slots:
+  void slotBrowseRxSSTVImagesPath();
+  void slotBrowseRxDRMImagesPath();
+  void slotBrowseTxSSTVImagesPath();
+  void slotBrowseTxDRMImagesPath();
+  void slotBrowseTxStockImagesPath();
+  void slotBrowseTemplatesPath();
+  void slotBrowseAudioPath();
+  
+private:
+  Ui::directoriesConfig *ui;
+  void createDir(QString path);
+};
+
+#endif // DIRECTORIES_H
diff --git a/qsstv/config/directoriesconfig.ui b/qsstv/config/directoriesconfig.ui
new file mode 100644
index 0000000..6b7610e
--- /dev/null
+++ b/qsstv/config/directoriesconfig.ui
@@ -0,0 +1,487 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>directoriesConfig</class>
+ <widget class="QWidget" name="directoriesConfig">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>700</width>
+    <height>345</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <layout class="QHBoxLayout" name="_2">
+     <property name="spacing">
+      <number>6</number>
+     </property>
+     <property name="leftMargin">
+      <number>0</number>
+     </property>
+     <property name="topMargin">
+      <number>0</number>
+     </property>
+     <property name="rightMargin">
+      <number>0</number>
+     </property>
+     <property name="bottomMargin">
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="QLabel" name="rxSSTVImLabel">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>150</width>
+         <height>25</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>RX SSTV Images</string>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="rxSSTVImagesPathLineEdit"/>
+     </item>
+     <item>
+      <widget class="QPushButton" name="rxSSTVImagesPathBrowseButton">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="text">
+        <string>Browse ...</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="_6">
+     <property name="spacing">
+      <number>6</number>
+     </property>
+     <property name="leftMargin">
+      <number>0</number>
+     </property>
+     <property name="topMargin">
+      <number>0</number>
+     </property>
+     <property name="rightMargin">
+      <number>0</number>
+     </property>
+     <property name="bottomMargin">
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="QLabel" name="rxDRMImLabel">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>150</width>
+         <height>25</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>RX DRM Images</string>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="rxDRMImagesPathLineEdit"/>
+     </item>
+     <item>
+      <widget class="QPushButton" name="rxDRMImagesPathBrowseButton">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="text">
+        <string>Browse ...</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="_7">
+     <property name="spacing">
+      <number>6</number>
+     </property>
+     <property name="leftMargin">
+      <number>0</number>
+     </property>
+     <property name="topMargin">
+      <number>0</number>
+     </property>
+     <property name="rightMargin">
+      <number>0</number>
+     </property>
+     <property name="bottomMargin">
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="QLabel" name="txImLabel_2">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>150</width>
+         <height>25</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>TX SSTV Images</string>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="txSSTVImagesPathLineEdit"/>
+     </item>
+     <item>
+      <widget class="QPushButton" name="txSSTVImagesPathBrowseButton">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="text">
+        <string>Browse ...</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="_3">
+     <property name="spacing">
+      <number>6</number>
+     </property>
+     <property name="leftMargin">
+      <number>0</number>
+     </property>
+     <property name="topMargin">
+      <number>0</number>
+     </property>
+     <property name="rightMargin">
+      <number>0</number>
+     </property>
+     <property name="bottomMargin">
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="QLabel" name="txImLabel">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>150</width>
+         <height>25</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>TX DRM Images</string>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="txDRMImagesPathLineEdit"/>
+     </item>
+     <item>
+      <widget class="QPushButton" name="txDRMImagesPathBrowseButton">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="text">
+        <string>Browse ...</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="_8">
+     <property name="spacing">
+      <number>6</number>
+     </property>
+     <property name="leftMargin">
+      <number>0</number>
+     </property>
+     <property name="topMargin">
+      <number>0</number>
+     </property>
+     <property name="rightMargin">
+      <number>0</number>
+     </property>
+     <property name="bottomMargin">
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="QLabel" name="txImLabel_3">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>150</width>
+         <height>25</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>TX Stock Images</string>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="txStockImagesPathLineEdit"/>
+     </item>
+     <item>
+      <widget class="QPushButton" name="txStockImagesPathBrowseButton">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="text">
+        <string>Browse ...</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout">
+     <property name="spacing">
+      <number>6</number>
+     </property>
+     <property name="leftMargin">
+      <number>0</number>
+     </property>
+     <property name="topMargin">
+      <number>0</number>
+     </property>
+     <property name="rightMargin">
+      <number>0</number>
+     </property>
+     <property name="bottomMargin">
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="QLabel" name="templLabel">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>150</width>
+         <height>25</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>Templates</string>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="templatesPathLineEdit"/>
+     </item>
+     <item>
+      <widget class="QPushButton" name="templatesPathBrowseButton">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="text">
+        <string>Browse ...</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="_5">
+     <property name="spacing">
+      <number>6</number>
+     </property>
+     <property name="leftMargin">
+      <number>0</number>
+     </property>
+     <property name="topMargin">
+      <number>0</number>
+     </property>
+     <property name="rightMargin">
+      <number>0</number>
+     </property>
+     <property name="bottomMargin">
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="QLabel" name="audioRecordsLabel">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>150</width>
+         <height>25</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>Audio Records</string>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="audioPathLineEdit"/>
+     </item>
+     <item>
+      <widget class="QPushButton" name="audioPathBrowseButton">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="text">
+        <string>Browse ...</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <widget class="QCheckBox" name="saveTXcheckBox">
+     <property name="text">
+      <string>Save TX images in TX SSTV or TX DRM directory</string>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <spacer name="spacer">
+     <property name="orientation">
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeType">
+      <enum>QSizePolicy::Expanding</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>20</width>
+       <height>184</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="_4">
+     <property name="spacing">
+      <number>6</number>
+     </property>
+     <property name="leftMargin">
+      <number>0</number>
+     </property>
+     <property name="topMargin">
+      <number>0</number>
+     </property>
+     <property name="rightMargin">
+      <number>0</number>
+     </property>
+     <property name="bottomMargin">
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="QLabel" name="docLabel">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>150</width>
+         <height>25</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>Documentation </string>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="docPathLineEdit"/>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/qsstv/drmprofileform.cpp b/qsstv/config/drmprofileconfig.cpp
similarity index 83%
rename from qsstv/drmprofileform.cpp
rename to qsstv/config/drmprofileconfig.cpp
index c91fa60..8bd9ea5 100644
--- a/qsstv/drmprofileform.cpp
+++ b/qsstv/config/drmprofileconfig.cpp
@@ -1,27 +1,30 @@
-#include "drmprofileform.h"
-#include "ui_drmprofileform.h"
+#include "drmprofileconfig.h"
+#include "ui_drmprofileconfig.h"
 #include "utils/supportfunctions.h"
 #include "configparams.h"
 
-drmProfileForm::drmProfileForm(QWidget *parent) :
-  QWidget(parent),
-  ui(new Ui::drmProfileForm)
+sprofile drmPFArray[NUMBEROFPROFILES];
+
+drmProfileConfig *drmProfileConfigPtr;
+
+
+drmProfileConfig::drmProfileConfig(QWidget *parent) :  baseConfig(parent),  ui(new Ui::drmProfileConfig)
 {
   ui->setupUi(this);
   readSettings();
 }
 
-drmProfileForm::~drmProfileForm()
+drmProfileConfig::~drmProfileConfig()
 {
     writeSettings();
   delete ui;
 }
 
 
-void drmProfileForm::readSettings()
+void drmProfileConfig::readSettings()
 {
   QSettings qSettings;
-  qSettings.beginGroup ("DRM Profile" );
+  qSettings.beginGroup ("DRMPROFILE" );
   drmPFArray[0].name=qSettings.value ("drmPF1Name","Profile 1").toString();
   drmPFArray[0].params.robMode=qSettings.value ("drmPF1Mode",0).toInt();
   drmPFArray[0].params.qam=qSettings.value("drmPF1QAM",0).toInt();
@@ -45,19 +48,16 @@ void drmProfileForm::readSettings()
   drmPFArray[2].params.protection=qSettings.value("drmPF3Protection",0).toInt();
   drmPFArray[2].params.interleaver=qSettings.value("drmPF3Interleave",0).toInt();
   drmPFArray[2].params.reedSolomon=qSettings.value("drmPF3ReedSolomon",0).toInt();
-
-
   qSettings.endGroup();
   setParams();
 
 }
 
-void drmProfileForm::writeSettings()
+void drmProfileConfig::writeSettings()
 {
   QSettings qSettings;
   getParams();
-  qSettings.beginGroup ("DRM Profile" );
-
+  qSettings.beginGroup ("DRMPROFILE" );
   qSettings.setValue ("drmPF1Name",drmPFArray[0].name);
   qSettings.setValue ("drmPF1Mode",drmPFArray[0].params.robMode);
   qSettings.setValue("drmPF1QAM",drmPFArray[0].params.qam);
@@ -65,7 +65,6 @@ void drmProfileForm::writeSettings()
   qSettings.setValue("drmPF1Protection",drmPFArray[0].params.protection);
   qSettings.setValue("drmPF1Interleave",drmPFArray[0].params.interleaver);
   qSettings.setValue("drmPF1ReedSolomon",drmPFArray[0].params.reedSolomon);
-
   qSettings.setValue ("drmPF2Name",drmPFArray[1].name);
   qSettings.setValue ("drmPF2Mode",drmPFArray[1].params.robMode);
   qSettings.setValue("drmPF2QAM",drmPFArray[1].params.qam);
@@ -85,8 +84,13 @@ void drmProfileForm::writeSettings()
 }
 
 
-void drmProfileForm::getParams()
+void drmProfileConfig::getParams()
 {
+  sprofile drmPFArrayCopy[NUMBEROFPROFILES];
+  drmPFArrayCopy[0]=drmPFArray[0];
+  drmPFArrayCopy[1]=drmPFArray[1];
+  drmPFArrayCopy[2]=drmPFArray[2];
+
   getValue(drmPFArray[0].name,ui->namePF1LineEdit);
   drmPFArray[0].params.callsign=myCallsign;
   getIndex(drmPFArray[0].params.robMode,ui->drmPF1ModeComboBox);
@@ -113,10 +117,28 @@ void drmProfileForm::getParams()
   getIndex(drmPFArray[2].params.protection,ui->drmPF3ProtectionComboBox);
   getIndex(drmPFArray[2].params.interleaver,ui->drmPF3InterleaveComboBox);
   getIndex(drmPFArray[2].params.reedSolomon,ui->drmPF3ReedSolomonComboBox);
+  changed=false;
+  if( diff(drmPFArrayCopy[0],drmPFArray[0])
+      || diff(drmPFArrayCopy[1],drmPFArray[1])
+      || diff(drmPFArrayCopy[2],drmPFArray[2]))
+    changed=true;
+
+}
+
+bool drmProfileConfig::diff(sprofile a,sprofile b)
+{
+  return
+      (a.name!=b.name
+      || a.params.robMode!=b.params.robMode
+      || a.params.qam!= b.params.qam
+      || a.params.bandwith!=b.params.bandwith
+      || a.params.protection!=b.params.protection
+      || a.params.interleaver!=b.params.interleaver
+      || a.params.reedSolomon!=b.params.reedSolomon);
 
 }
 
-void  drmProfileForm::setParams()
+void  drmProfileConfig::setParams()
 {
   setValue(drmPFArray[0].name,ui->namePF1LineEdit);
   setIndex(drmPFArray[0].params.robMode,ui->drmPF1ModeComboBox);
@@ -144,7 +166,7 @@ void  drmProfileForm::setParams()
 }
 
 
-bool drmProfileForm::getDRMParams(int idx,drmTxParams &d)
+bool drmProfileConfig::getDRMParams(int idx,drmTxParams &d)
 {
   if((idx<0)||(idx>=NUMBEROFPROFILES))
   {
@@ -154,7 +176,7 @@ bool drmProfileForm::getDRMParams(int idx,drmTxParams &d)
   return true;
 }
 
-bool drmProfileForm::getName(int idx, QString &n)
+bool drmProfileConfig::getName(int idx, QString &n)
 {
 
     if((idx<0)||(idx>=NUMBEROFPROFILES))
diff --git a/qsstv/config/drmprofileconfig.h b/qsstv/config/drmprofileconfig.h
new file mode 100644
index 0000000..9b6a045
--- /dev/null
+++ b/qsstv/config/drmprofileconfig.h
@@ -0,0 +1,55 @@
+#ifndef DRMPROFILECONFIG_H
+#define DRMPROFILECONFIG_H
+#include "drmtx/drmparams.h"
+
+
+#include "baseconfig.h"
+
+#define NUMBEROFPROFILES 3
+
+
+
+struct sprofile
+{
+    QString name;
+    drmTxParams params;
+
+};
+
+extern sprofile drmPFArray[NUMBEROFPROFILES];
+
+bool getDRMParams(int idx, drmTxParams &d);
+bool getName(int idx,QString &n);
+
+
+
+
+namespace Ui {
+class drmProfileConfig;
+}
+
+class drmProfileConfig : public baseConfig
+{
+    Q_OBJECT
+
+public:
+    explicit drmProfileConfig(QWidget *parent = 0);
+    ~drmProfileConfig();
+    void readSettings();
+    void writeSettings();
+    void getParams();
+    void setParams();
+    bool getDRMParams(int idx,drmTxParams &d);
+    bool getName(int idx, QString &n);
+
+private:
+    Ui::drmProfileConfig *ui;
+    bool diff(sprofile a,sprofile b);
+
+};
+
+extern drmProfileConfig *drmProfileConfigPtr;
+
+
+
+#endif // DRMPROFILECONFIG
diff --git a/qsstv/drmprofileform.ui b/qsstv/config/drmprofileconfig.ui
similarity index 99%
rename from qsstv/drmprofileform.ui
rename to qsstv/config/drmprofileconfig.ui
index a197f71..c80d6d4 100644
--- a/qsstv/drmprofileform.ui
+++ b/qsstv/config/drmprofileconfig.ui
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <ui version="4.0">
- <class>drmProfileForm</class>
- <widget class="QWidget" name="drmProfileForm">
+ <class>drmProfileConfig</class>
+ <widget class="QWidget" name="drmProfileConfig">
   <property name="geometry">
    <rect>
     <x>0</x>
@@ -14,6 +14,12 @@
    <string>Form</string>
   </property>
   <layout class="QVBoxLayout" name="verticalLayout_2">
+   <property name="spacing">
+    <number>2</number>
+   </property>
+   <property name="margin">
+    <number>1</number>
+   </property>
    <item>
     <widget class="QTabWidget" name="tabWidget">
      <property name="currentIndex">
diff --git a/qsstv/config/frequencyselectwidget.cpp b/qsstv/config/frequencyselectwidget.cpp
new file mode 100644
index 0000000..ee07cc7
--- /dev/null
+++ b/qsstv/config/frequencyselectwidget.cpp
@@ -0,0 +1,251 @@
+#include "frequencyselectwidget.h"
+#include "ui_frequencyselectwidget.h"
+
+QStringList freqList;
+QStringList modeList;
+QStringList sbModeList;
+QString additionalCommand;
+bool additionalCommandHex;
+
+frequencySelectWidget::frequencySelectWidget(QWidget *parent) :baseConfig(parent),
+  ui(new Ui::frequencySelectWidget)
+{
+  ui->setupUi(this);
+  QStringList sl;
+  sl<<"Frequencyy"<<"Mode"<<"Modulation";
+  ui->tableWidget->setAlternatingRowColors (false);
+  ui->tableWidget->setColumnCount(3);
+  ui->tableWidget->setHorizontalHeaderLabels(sl);
+  connect(ui->tableWidget,SIGNAL(itemChanged(QTableWidgetItem *)),this,SLOT(slotItemChanged()));
+  connect(ui->tableWidget,SIGNAL(cellClicked(int,int)),this,SLOT(slotCellClicked(int,int)));
+  connect(ui->addFreqPushButton,SIGNAL(clicked()),this,SLOT(slotFreqAdd()));
+  connect(ui->deleteFreqPushButton,SIGNAL(clicked()),this,SLOT(slotFreqDelete()));
+  connect(ui->moveUpFreqPushButton,SIGNAL(clicked()),this,SLOT(slotFreqUp()));
+  connect(ui->moveDownFreqPushButton,SIGNAL(clicked()),this,SLOT(slotFreqDown()));
+  lastRowSelected=-1;
+}
+
+frequencySelectWidget::~frequencySelectWidget()
+{
+  writeSettings();
+  delete ui;
+
+}
+
+void frequencySelectWidget::readSettings()
+{
+  QSettings qSettings;
+  qSettings.beginGroup("FREQSELECT");
+  freqList=qSettings.value("frequencyList",QStringList()).toStringList();
+  modeList=qSettings.value("modeList",QStringList()).toStringList();
+  sbModeList=qSettings.value("sbModeList",QStringList()).toStringList();
+  additionalCommand=qSettings.value("additionalCommand",QString()).toString();
+  additionalCommandHex=qSettings.value("additionalCommandHex",false).toBool();
+  if(modeList.count()!=freqList.count()  || sbModeList.count()!=freqList.count())
+    {
+      // invalid config
+      freqList.clear();
+      modeList.clear();
+      sbModeList.clear();
+    }
+  setParams();
+  qSettings.endGroup();
+}
+
+void frequencySelectWidget::writeSettings()
+{
+  QSettings qSettings;
+  getParams();
+  qSettings.beginGroup("FREQSELECT");
+  qSettings.setValue("frequencyList",freqList);
+  qSettings.setValue("modeList",modeList);
+  qSettings.setValue("sbModeList",sbModeList);
+  qSettings.setValue("additionalCommand",additionalCommand);
+  qSettings.setValue("additionalCommandHex",additionalCommandHex);
+  qSettings.endGroup();
+}
+
+void frequencySelectWidget::constructTable()
+{
+  int i;
+  while(ui->tableWidget->rowCount()>0)
+    {
+      ui->tableWidget->removeRow(0);
+    }
+  ui->tableWidget->setRowCount(freqList.count());
+
+  for(i=0;i<freqList.count();)
+    {
+      if(!freqList.at(i).isEmpty())
+        {
+          createEntry(i++);
+        }
+      else
+        {
+          freqList.takeAt(i);
+          modeList.takeAt(i);
+          sbModeList.takeAt(i);
+          ui->tableWidget->setRowCount(freqList.count());
+        }
+    }
+}
+
+void frequencySelectWidget:: getParams()
+{
+  int i;
+  bool ok;
+  freqList.clear();
+  modeList.clear();
+  sbModeList.clear();
+  for(i=0;i<ui->tableWidget->rowCount();i++)
+    {
+      ui->tableWidget->item(i,0)->text().toDouble(&ok);
+      {
+        if (!ok)
+          {
+            blockSignals(true);
+            ui->tableWidget->item(i,0)->setText("");
+            blockSignals(false);
+          }
+      }
+      freqList.append(ui->tableWidget->item(i,0)->text());
+      modeList.append(((QComboBox *)ui->tableWidget->cellWidget(i,1))->currentText());
+      sbModeList.append(((QComboBox *)ui->tableWidget->cellWidget(i,2))->currentText());
+    }
+  getValue(additionalCommand,ui->additionalCommandLineEdit);
+  getValue(additionalCommandHex,ui->additionalCommandHexCheckBox);
+}
+
+void frequencySelectWidget::setParams()
+{
+  constructTable();
+  setValue(additionalCommand,ui->additionalCommandLineEdit);
+  setValue(additionalCommandHex,ui->additionalCommandHexCheckBox);
+}
+
+
+
+
+
+
+
+void frequencySelectWidget::slotFreqAdd()
+{
+  freqList.append("");
+  modeList.append("SSTV");
+  sbModeList.append("LSB");
+  createEntry(freqList.count()-1);
+}
+
+void frequencySelectWidget::slotFreqDelete()
+{
+  int curRow=lastRowSelected;
+  freqList.takeAt(curRow);
+  modeList.takeAt(curRow);
+  sbModeList.takeAt(curRow);
+  constructTable();
+  if((curRow<freqList.count()) && (curRow!=0))
+    {
+      ui->tableWidget->setCurrentCell(curRow-1,0);
+      ui->tableWidget->item(curRow-1, 0)->setSelected(true);
+      setLastRowSelected();
+    }
+}
+void frequencySelectWidget::slotFreqUp()
+{
+  int curRow=lastRowSelected;
+  QString  f,m,sb;
+  if(curRow>0)
+    {
+      f=freqList.at(curRow-1);
+      m=modeList.at(curRow-1);
+      sb=sbModeList.at(curRow-1);
+      freqList[curRow-1]=freqList.at(curRow);
+      modeList[curRow-1]=modeList.at(curRow);
+      sbModeList[curRow-1]=sbModeList.at(curRow);
+      freqList[curRow]=f;
+      modeList[curRow]=m;
+      sbModeList[curRow]=sb;
+      constructTable();
+      ui->tableWidget->setCurrentCell(curRow-1,0);
+      ui->tableWidget->item(curRow-1, 0)->setSelected(true);
+      setLastRowSelected();
+
+    }
+}
+
+void frequencySelectWidget::slotFreqDown()
+{
+  int curRow=lastRowSelected;
+  QString  f,m,sb;
+  if(curRow<(ui->tableWidget->rowCount()-1) && curRow>=0)
+    {
+      f=freqList.at(curRow+1);
+      m=modeList.at(curRow+1);
+      sb=sbModeList.at(curRow+1);
+      freqList[curRow+1]=freqList.at(curRow);
+      modeList[curRow+1]=modeList.at(curRow);
+      sbModeList[curRow+1]=sbModeList.at(curRow);
+      freqList[curRow]=f;
+      modeList[curRow]=m;
+      sbModeList[curRow]=sb;
+      constructTable();
+      ui->tableWidget->setCurrentCell(curRow+1,0);
+      ui->tableWidget->item(curRow+1, 0)->setSelected(true);
+      setLastRowSelected();
+
+    }
+}
+
+void frequencySelectWidget::createEntry(int row)
+{
+  QComboBox *cb, *sb;
+  QTableWidgetItem *ct;
+  if(row>(ui->tableWidget->rowCount()-1))
+    {
+      ui->tableWidget->setRowCount(row+1);
+    }
+  ui->tableWidget-> blockSignals(true);
+  ct=new QTableWidgetItem();
+  ct->setText(freqList.at(row));
+  ui->tableWidget->setItem(row,0,ct);
+
+  cb=new QComboBox(this);
+  cb->addItem("SSTV");
+  cb->addItem("DRM");
+//  cb->setCurrentText(modeList.at(row));
+  setValue(modeList.at(row),cb);
+
+  ui->tableWidget->setCellWidget(row,1,cb);
+
+  sb=new QComboBox(this);
+  sb->addItem("LSB");
+  sb->addItem("USB");
+  sb->addItem("FM");
+  sb->addItem("AM");
+
+//  sb->setCurrentText(sbModeList.at(row));
+  setValue(sbModeList.at(row),sb);
+  ui->tableWidget->setCellWidget(row,2,sb);
+  connect(cb,SIGNAL(currentIndexChanged(int)),SLOT(slotItemChanged()));
+  connect(sb,SIGNAL(currentIndexChanged(int)),SLOT(slotItemChanged()));
+   ui->tableWidget->blockSignals(false);
+}
+
+void frequencySelectWidget::slotItemChanged()
+{
+  getParams();
+}
+
+void frequencySelectWidget::setLastRowSelected()
+{
+  lastRowSelected=ui->tableWidget->currentRow();
+  if(lastRowSelected>=ui->tableWidget->rowCount())
+    {
+      lastRowSelected=-1;
+    }
+}
+void frequencySelectWidget::slotCellClicked(int r,int)
+{
+  lastRowSelected=r;
+}
diff --git a/qsstv/config/frequencyselectwidget.h b/qsstv/config/frequencyselectwidget.h
new file mode 100644
index 0000000..9ab76ff
--- /dev/null
+++ b/qsstv/config/frequencyselectwidget.h
@@ -0,0 +1,46 @@
+#ifndef FREQUENCYSELECTWIDGET_H
+#define FREQUENCYSELECTWIDGET_H
+#include "baseconfig.h"
+
+#include <QWidget>
+
+extern QStringList freqList;
+extern QStringList modeList;
+extern QStringList sbModeList;
+extern QString additionalCommand;
+extern bool additionalCommandHex;
+
+namespace Ui {
+class frequencySelectWidget;
+}
+
+class frequencySelectWidget : public baseConfig
+{
+  Q_OBJECT
+
+public:
+  explicit frequencySelectWidget(QWidget *parent = 0);
+  ~frequencySelectWidget();
+  void readSettings();
+  void writeSettings();
+  void getParams();
+  void setParams();
+
+private slots:
+  void slotFreqAdd();
+  void slotFreqDelete();
+  void slotFreqUp();
+  void slotFreqDown();
+  void slotItemChanged();
+  void slotCellClicked(int r, int);
+
+private:
+  Ui::frequencySelectWidget *ui;
+  void constructTable();
+  void createEntry(int row);
+  void setLastRowSelected();
+  int lastRowSelected;
+
+};
+
+#endif // FREQUENCYSELECTWIDGET_H
diff --git a/qsstv/config/frequencyselectwidget.ui b/qsstv/config/frequencyselectwidget.ui
new file mode 100644
index 0000000..699a1dd
--- /dev/null
+++ b/qsstv/config/frequencyselectwidget.ui
@@ -0,0 +1,149 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>frequencySelectWidget</class>
+ <widget class="QWidget" name="frequencySelectWidget">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>788</width>
+    <height>473</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout" stretch="2,0">
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout" stretch="1,0,0,0">
+     <item>
+      <widget class="QTableWidget" name="tableWidget"/>
+     </item>
+     <item>
+      <layout class="QVBoxLayout" name="verticalLayout_13">
+       <item>
+        <widget class="QPushButton" name="addFreqPushButton">
+         <property name="text">
+          <string>Add</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QPushButton" name="deleteFreqPushButton">
+         <property name="text">
+          <string>Delete</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <spacer name="verticalSpacer">
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>20</width>
+           <height>13</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item>
+        <widget class="QPushButton" name="moveUpFreqPushButton">
+         <property name="focusPolicy">
+          <enum>Qt::StrongFocus</enum>
+         </property>
+         <property name="text">
+          <string/>
+         </property>
+         <property name="icon">
+          <iconset resource="../qsstv.qrc">
+           <normaloff>:/icons/up.png</normaloff>:/icons/up.png</iconset>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <spacer name="verticalSpacer_2">
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>20</width>
+           <height>18</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item>
+        <widget class="QPushButton" name="moveDownFreqPushButton">
+         <property name="focusPolicy">
+          <enum>Qt::StrongFocus</enum>
+         </property>
+         <property name="text">
+          <string/>
+         </property>
+         <property name="icon">
+          <iconset resource="../qsstv.qrc">
+           <normaloff>:/icons/down.png</normaloff>:/icons/down.png</iconset>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QPlainTextEdit" name="plainTextEdit">
+       <property name="readOnly">
+        <bool>true</bool>
+       </property>
+       <property name="plainText">
+        <string>Enter the frequency in MHz and select the mode.
+Example:
+14.230   SSTV USB
+7.058     DRM LSB</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout_2">
+     <item>
+      <widget class="QLabel" name="label">
+       <property name="text">
+        <string>Hamlib Data Command</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="additionalCommandLineEdit"/>
+     </item>
+     <item>
+      <widget class="QCheckBox" name="additionalCommandHexCheckBox">
+       <property name="text">
+        <string>Hex</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources>
+  <include location="../qsstv.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/qsstv/config/ftpconfig.cpp b/qsstv/config/ftpconfig.cpp
new file mode 100644
index 0000000..8f23c71
--- /dev/null
+++ b/qsstv/config/ftpconfig.cpp
@@ -0,0 +1,151 @@
+#include "ftpconfig.h"
+#include "ui_ftpconfig.h"
+#include "ftp.h"
+
+#include <QImageWriter>
+#include <QMessageBox>
+
+
+bool enableFTP;
+int ftpPort;
+QString ftpRemoteHost;
+QString ftpRemoteSSTVDirectory;
+QString ftpRemoteDRMDirectory;
+QString ftpLogin;
+QString ftpPassword;
+QString ftpDefaultImageFormat;
+eftpSaveFormat ftpSaveFormat;
+int ftpNumImages;
+
+ftpConfig::ftpConfig(QWidget *parent) :  baseConfig (parent),  ui(new Ui::ftpConfig)
+{
+  ui->setupUi(this);
+  foreach (QByteArray format, QImageWriter::supportedImageFormats())
+    {
+      QString text = tr("%1").arg(QString(format));
+      ui->ftpDefaultImageFormatComboBox->addItem(text);
+    }
+  connect(ui->testFTPPushButton,SIGNAL(clicked()),SLOT(slotTestFTPPushButton()));
+}
+
+ftpConfig::~ftpConfig()
+{
+  delete ui;
+}
+
+void ftpConfig::readSettings()
+{
+  QSettings qSettings;
+  qSettings.beginGroup("FTPCONFIG");
+  enableFTP=qSettings.value("enableFTP",false).toBool();
+  ftpPort=qSettings.value("ftpPort",21).toInt();
+  ftpRemoteHost=qSettings.value("ftpRemoteHost","").toString();
+  ftpRemoteSSTVDirectory=qSettings.value("ftpRemoteSSTVDirectory","").toString();
+  ftpRemoteDRMDirectory=qSettings.value("ftpRemoteDRMDirectory","").toString();
+  ftpLogin=qSettings.value("ftpLogin","").toString();
+  ftpPassword=qSettings.value("ftpPassword","").toString();
+  ftpDefaultImageFormat=qSettings.value("ftpDefaultImageFormat","png").toString();
+  ftpSaveFormat=(eftpSaveFormat)qSettings.value("ftpSaveFormat",0).toInt();
+  ftpNumImages=qSettings.value("ftpNumImages",30).toInt();
+  qSettings.endGroup();
+  setParams();
+}
+
+void ftpConfig::writeSettings()
+{
+  QSettings qSettings;
+  getParams();
+  qSettings.beginGroup("FTPCONFIG");
+  qSettings.setValue("enableFTP",enableFTP);
+  qSettings.setValue("ftpPort",ftpPort);
+  qSettings.setValue("ftpRemoteHost",ftpRemoteHost);
+  qSettings.setValue("ftpRemoteSSTVDirectory",ftpRemoteSSTVDirectory);
+  qSettings.setValue("ftpRemoteDRMDirectory",ftpRemoteDRMDirectory);
+  qSettings.setValue("ftpLogin",ftpLogin);
+  qSettings.setValue("ftpPassword",ftpPassword);
+  qSettings.setValue("ftpDefaultImageFormat",ftpDefaultImageFormat);
+  qSettings.setValue("ftpSaveFormat",(int)ftpSaveFormat);
+  qSettings.setValue("ftpNumImages",ftpNumImages);
+  qSettings.endGroup();
+}
+
+void ftpConfig::getParams()
+{
+  bool enableFTPCopy=enableFTP;
+  int ftpPortCopy=ftpPort;
+  QString ftpRemoteHostCopy=ftpRemoteHost;
+  QString ftpRemoteSSTVDirectoryCopy=ftpRemoteSSTVDirectory;
+  QString ftpRemoteDRMDirectoryCopy=ftpRemoteDRMDirectory;
+  QString ftpLoginCopy=ftpLogin;
+  QString ftpPasswordCopy=ftpPassword;
+  QString ftpDefaultImageFormatCopy=ftpDefaultImageFormat;
+  eftpSaveFormat ftpSaveFormatCopy=ftpSaveFormat;
+
+
+  getValue(enableFTP,ui->enableFTPCheckBox);
+  getValue(ftpPort,ui->ftpPortSpinBox);
+  getValue(ftpRemoteHost,ui->remoteHostLineEdit);
+  getValue(ftpNumImages,ui->ftpNumImagesSpinBox);
+  getValue(ftpRemoteSSTVDirectory,ui->remoteSSTVDirectoryLineEdit);
+  getValue(ftpRemoteDRMDirectory,ui->remoteDRMDirectoryLineEdit);
+  getValue(ftpLogin,ui->ftpLoginLineEdit);
+  getValue(ftpPassword,ui->ftpPasswordLineEdit);
+  getValue(ftpDefaultImageFormat,ui->ftpDefaultImageFormatComboBox);
+  if(ui->imageRadioButton->isChecked())
+    {
+      ftpSaveFormat=FTPIM;
+    }
+  else
+    {
+      ftpSaveFormat=FTPFILE;
+    }
+  changed=false;
+  if(enableFTPCopy!=enableFTP
+     || ftpPortCopy!=ftpPort
+     || ftpRemoteHostCopy!=ftpRemoteHost
+     || ftpRemoteSSTVDirectoryCopy!=ftpRemoteSSTVDirectory
+     || ftpRemoteDRMDirectoryCopy!=ftpRemoteDRMDirectory
+     || ftpLoginCopy!=ftpLogin
+     || ftpPasswordCopy!=ftpPassword
+     || ftpDefaultImageFormatCopy!=ftpDefaultImageFormat
+     || ftpSaveFormatCopy!=ftpSaveFormat)
+    changed=true;
+}
+
+void ftpConfig::setParams()
+{
+  setValue(enableFTP,ui->enableFTPCheckBox);
+  setValue(ftpPort,ui->ftpPortSpinBox);
+  setValue(ftpRemoteHost,ui->remoteHostLineEdit);
+  setValue(ftpNumImages,ui->ftpNumImagesSpinBox);
+  setValue(ftpRemoteSSTVDirectory,ui->remoteSSTVDirectoryLineEdit);
+  setValue(ftpRemoteDRMDirectory,ui->remoteDRMDirectoryLineEdit);
+  setValue(ftpLogin,ui->ftpLoginLineEdit);
+  setValue(ftpPassword,ui->ftpPasswordLineEdit);
+  if(ftpSaveFormat==FTPIM)
+    {
+      ui->imageRadioButton->setChecked(true);
+    }
+  else
+    {
+      ui->filenameRadioButton->setChecked(true);
+    }
+  setValue(ftpDefaultImageFormat,ui->ftpDefaultImageFormatComboBox);
+}
+
+
+void ftpConfig::slotTestFTPPushButton()
+{
+  QString r1,r2;
+  ftpInterface fInt("TestUploadConnection");
+  ui->testFTPPushButton->setDisabled(true);
+  getParams();
+  fInt.setupConnection(ftpRemoteHost,ftpPort,ftpLogin,ftpPassword,ftpRemoteSSTVDirectory);
+  r1=fInt.execFTPTest();
+  fInt.init();
+  fInt.setupConnection(ftpRemoteHost,ftpPort,ftpLogin,ftpPassword,ftpRemoteDRMDirectory);
+  r2=fInt.execFTPTest();
+  ui->testFTPPushButton->setDisabled(false);
+  QMessageBox::information(this,"Testing Connection","test",QString("SSTV: %1\nDRM: %2").arg(r1).arg(r2));
+}
+
diff --git a/qsstv/config/ftpconfig.h b/qsstv/config/ftpconfig.h
new file mode 100644
index 0000000..9539d8d
--- /dev/null
+++ b/qsstv/config/ftpconfig.h
@@ -0,0 +1,48 @@
+#ifndef FTPCONFIG_H
+#define FTPCONFIG_H
+
+
+#include "baseconfig.h"
+
+
+#define NUMFTPRXIMAGES 30
+
+enum eftpSaveFormat {FTPIM,FTPFILE};
+
+extern bool enableFTP;
+extern int ftpPort;
+extern QString ftpRemoteHost;
+extern QString ftpRemoteSSTVDirectory;
+extern QString ftpRemoteDRMDirectory;
+extern QString ftpLogin;
+extern QString ftpPassword;
+extern QString ftpFilename;
+extern QString ftpDefaultImageFormat;
+extern eftpSaveFormat ftpSaveFormat;
+extern int ftpNumImages;
+
+
+namespace Ui {
+class ftpConfig;
+}
+
+class ftpConfig : public baseConfig
+{
+  Q_OBJECT
+  
+public:
+  explicit ftpConfig(QWidget *parent = 0);
+  ~ftpConfig();
+  void readSettings();
+  void writeSettings();
+  void getParams();
+  void setParams();
+
+private slots:
+  void slotTestFTPPushButton();
+  
+private:
+  Ui::ftpConfig *ui;
+};
+
+#endif // FTPCONFIG_H
diff --git a/qsstv/config/ftpconfig.ui b/qsstv/config/ftpconfig.ui
new file mode 100644
index 0000000..5218a9d
--- /dev/null
+++ b/qsstv/config/ftpconfig.ui
@@ -0,0 +1,471 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ftpConfig</class>
+ <widget class="QWidget" name="ftpConfig">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>751</width>
+    <height>517</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <layout class="QHBoxLayout" name="_2">
+     <property name="spacing">
+      <number>6</number>
+     </property>
+     <property name="margin">
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="QCheckBox" name="enableFTPCheckBox">
+       <property name="text">
+        <string>Enable File Upload to FTP Server</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeType">
+        <enum>QSizePolicy::Expanding</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>20</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QLabel" name="ftpPortLabel">
+       <property name="text">
+        <string>FTP Port</string>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QSpinBox" name="ftpPortSpinBox">
+       <property name="minimum">
+        <number>1</number>
+       </property>
+       <property name="maximum">
+        <number>10000</number>
+       </property>
+       <property name="value">
+        <number>21</number>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeType">
+        <enum>QSizePolicy::Expanding</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>20</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QLabel" name="defaultImageModeLabel">
+       <property name="text">
+        <string>Default Image Format</string>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QComboBox" name="ftpDefaultImageFormatComboBox"/>
+     </item>
+     <item>
+      <spacer>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeType">
+        <enum>QSizePolicy::Preferred</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>20</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="_4">
+     <property name="spacing">
+      <number>6</number>
+     </property>
+     <property name="margin">
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="QLabel" name="remoteHostLabel">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>145</width>
+         <height>25</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>Host</string>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="remoteHostLineEdit"/>
+     </item>
+     <item>
+      <spacer>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeType">
+        <enum>QSizePolicy::Preferred</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>20</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="_3">
+     <property name="spacing">
+      <number>6</number>
+     </property>
+     <property name="margin">
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="QLabel" name="ftploginLabel">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>145</width>
+         <height>25</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>Login</string>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="ftpLoginLineEdit"/>
+     </item>
+     <item>
+      <spacer>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeType">
+        <enum>QSizePolicy::Preferred</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>20</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout">
+     <property name="spacing">
+      <number>6</number>
+     </property>
+     <property name="margin">
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="QLabel" name="passwordLabel">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>145</width>
+         <height>25</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>Password</string>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="ftpPasswordLineEdit">
+       <property name="echoMode">
+        <enum>QLineEdit::Password</enum>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeType">
+        <enum>QSizePolicy::Preferred</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>20</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="_5">
+     <property name="spacing">
+      <number>6</number>
+     </property>
+     <property name="margin">
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="QLabel" name="remoteSSTVDirectoryLabel">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>145</width>
+         <height>25</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>Directory SSTV</string>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="remoteSSTVDirectoryLineEdit"/>
+     </item>
+     <item>
+      <spacer>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeType">
+        <enum>QSizePolicy::Preferred</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>20</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="_6">
+     <property name="spacing">
+      <number>6</number>
+     </property>
+     <property name="margin">
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="QLabel" name="remoteDRMDirectoryLabel">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>145</width>
+         <height>25</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>Directory DRM</string>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="remoteDRMDirectoryLineEdit"/>
+     </item>
+     <item>
+      <spacer>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeType">
+        <enum>QSizePolicy::Preferred</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>20</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <widget class="QGroupBox" name="groupBox">
+     <property name="title">
+      <string>Image store</string>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout_2">
+      <item>
+       <layout class="QHBoxLayout" name="horizontalLayout_3">
+        <item>
+         <widget class="QRadioButton" name="imageRadioButton">
+          <property name="text">
+           <string>image1 to image</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QSpinBox" name="ftpNumImagesSpinBox">
+          <property name="minimum">
+           <number>1</number>
+          </property>
+          <property name="maximum">
+           <number>50</number>
+          </property>
+          <property name="value">
+           <number>30</number>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <spacer name="horizontalSpacer">
+          <property name="orientation">
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>40</width>
+            <height>20</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+       </layout>
+      </item>
+      <item>
+       <widget class="QRadioButton" name="filenameRadioButton">
+        <property name="text">
+         <string>filename</string>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0">
+     <item>
+      <widget class="QLabel" name="label_2">
+       <property name="text">
+        <string>This ftp server is used to upload your received pictures. You can save them as a rotating sequence of images (image1 being the latest and image30 being the oldest) or simply under their own filename.</string>
+       </property>
+       <property name="wordWrap">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="testFTPPushButton">
+       <property name="text">
+        <string>Test connection</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <spacer name="spacer">
+     <property name="orientation">
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeType">
+      <enum>QSizePolicy::Expanding</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>20</width>
+       <height>6</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/qsstv/config/guiconfig.cpp b/qsstv/config/guiconfig.cpp
new file mode 100644
index 0000000..96cc46b
--- /dev/null
+++ b/qsstv/config/guiconfig.cpp
@@ -0,0 +1,114 @@
+#include "guiconfig.h"
+#include "ui_guiconfig.h"
+#include <QImageWriter>
+#include <QColorDialog>
+
+
+int galleryRows;
+int galleryColumns;
+bool imageStretch;
+QColor backGroundColor;
+QColor imageBackGroundColor;
+bool slowCPU;
+
+guiConfig::guiConfig(QWidget *parent) : baseConfig(parent),  ui(new Ui::guiConfig)
+{
+  ui->setupUi(this);
+  backGroundColorChanged=false;
+  connect(ui->backgroundColorPushButton,SIGNAL(clicked()),SLOT(slotBGColorSelect()));
+  connect(ui->imageBackgroundColorPushButton,SIGNAL(clicked()),SLOT(slotIBGColorSelect()));
+}
+
+guiConfig::~guiConfig()
+{
+  delete ui;
+}
+
+void guiConfig::readSettings()
+{
+  QSettings qSettings;
+  qSettings.beginGroup("GUI");
+  galleryRows=qSettings.value("galleryRows",4).toInt();
+  galleryColumns=qSettings.value("galleryColumns",4).toInt();
+  imageStretch=qSettings.value("imageStretch",true).toBool();
+  backGroundColor=qSettings.value("backGroundColor",QColor(128,128,128)).value<QColor>();
+  imageBackGroundColor=qSettings.value("imageBackGroundColor",QColor(0,0,128)).value<QColor>();
+  slowCPU=qSettings.value("slowCPU",false).toBool();
+  qSettings.endGroup();
+  setParams();
+}
+
+void guiConfig::writeSettings()
+{
+  QSettings qSettings;
+  getParams();
+  qSettings.beginGroup("GUI");
+  qSettings.setValue("galleryRows",galleryRows);
+  qSettings.setValue("galleryColumns",galleryColumns);
+  qSettings.setValue("imageStretch",imageStretch);
+  qSettings.setValue("backGroundColor",backGroundColor);
+  qSettings.setValue("imageBackGroundColor",imageBackGroundColor);
+  qSettings.setValue("slowCPU",slowCPU);
+  qSettings.endGroup();
+}
+
+void guiConfig::getParams()
+{
+  int galleryRowsCopy=galleryRows;
+  int galleryColumnsCopy=galleryColumns;
+  getValue(galleryRows,ui->rowsSpinBox);
+  getValue(galleryColumns, ui->columnsSpinBox);
+  changed=false;
+  if( galleryRowsCopy!=galleryRows || galleryColumnsCopy!=galleryColumns)
+    changed=true;
+  getValue(imageStretch,ui->stretchCheckBox);
+  getValue(slowCPU,ui->slowCPUCheckBox);
+}
+
+void guiConfig::setParams()
+{
+  setValue(galleryRows,ui->rowsSpinBox);
+  setValue(galleryColumns, ui->columnsSpinBox);
+  setValue(imageStretch,ui->stretchCheckBox);
+  setColorLabel(backGroundColor,false);
+  setColorLabel(imageBackGroundColor,true);
+  setValue(slowCPU,ui->slowCPUCheckBox);
+}
+
+
+void guiConfig::slotBGColorSelect()
+{
+  QColor c;
+  c=QColorDialog::getColor(backGroundColor,this,"",QColorDialog::ShowAlphaChannel);
+  setColorLabel(c,false);
+}
+
+void guiConfig::slotIBGColorSelect()
+{
+  QColor c;
+  c=QColorDialog::getColor(imageBackGroundColor,this,"",QColorDialog::ShowAlphaChannel);
+  setColorLabel(c,true);
+}
+
+
+void guiConfig::setColorLabel(QColor c,bool image)
+{
+if (c.isValid())
+  {
+    if(!image)
+      {
+        backGroundColorChanged=true;
+        QPalette palette = ui->backGroundColorLabel->palette();
+        palette.setColor(ui->backGroundColorLabel->backgroundRole(), c);
+        ui->backGroundColorLabel->setPalette(palette);
+        backGroundColor=c;
+      }
+    else
+      {
+        QPalette palette = ui->imageBackGroundColorLabel->palette();
+        palette.setColor(ui->imageBackGroundColorLabel->backgroundRole(), c);
+        ui->imageBackGroundColorLabel->setPalette(palette);
+        imageBackGroundColor=c;
+      }
+   }
+}
diff --git a/qsstv/config/guiconfig.h b/qsstv/config/guiconfig.h
new file mode 100644
index 0000000..41cb178
--- /dev/null
+++ b/qsstv/config/guiconfig.h
@@ -0,0 +1,42 @@
+#ifndef GUICONFIG_H
+#define GUICONFIG_H
+
+#include <QWidget>
+#include "baseconfig.h"
+
+extern int galleryRows;
+extern int galleryColumns;
+extern bool imageStretch;
+extern QString defaultImageFormat;
+extern QColor backGroundColor;
+extern QColor imageBackGroundColor;
+extern bool slowCPU;
+
+namespace Ui
+{
+class guiConfig;
+}
+
+class guiConfig :public baseConfig
+{
+  Q_OBJECT
+  
+public:
+  explicit guiConfig(QWidget *parent = 0);
+  ~guiConfig();
+  void readSettings();
+  void writeSettings();
+  void getParams();
+  void setParams();
+  bool backGroundColorChanged;
+private slots:
+  void slotBGColorSelect();
+  void slotIBGColorSelect();
+
+private:
+  Ui::guiConfig *ui;
+  void setColorLabel(QColor c, bool image);
+
+};
+
+#endif // GUICONFIG_H
diff --git a/qsstv/config/guiconfig.ui b/qsstv/config/guiconfig.ui
new file mode 100644
index 0000000..7de332a
--- /dev/null
+++ b/qsstv/config/guiconfig.ui
@@ -0,0 +1,198 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>guiConfig</class>
+ <widget class="QWidget" name="guiConfig">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>578</width>
+    <height>484</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout_5">
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout_2">
+     <item>
+      <layout class="QVBoxLayout" name="verticalLayout_3">
+       <item>
+        <widget class="QGroupBox" name="groupBox_2">
+         <property name="title">
+          <string>Images</string>
+         </property>
+         <layout class="QVBoxLayout" name="verticalLayout_2">
+          <item>
+           <layout class="QGridLayout" name="gridLayout_2">
+            <item row="1" column="0">
+             <widget class="QPushButton" name="backgroundColorPushButton">
+              <property name="text">
+               <string>Background Color</string>
+              </property>
+             </widget>
+            </item>
+            <item row="0" column="0">
+             <widget class="QCheckBox" name="stretchCheckBox">
+              <property name="layoutDirection">
+               <enum>Qt::RightToLeft</enum>
+              </property>
+              <property name="text">
+               <string>Stretch</string>
+              </property>
+             </widget>
+            </item>
+            <item row="2" column="0">
+             <widget class="QPushButton" name="imageBackgroundColorPushButton">
+              <property name="text">
+               <string>Image Background color</string>
+              </property>
+             </widget>
+            </item>
+            <item row="1" column="1">
+             <widget class="QLabel" name="backGroundColorLabel">
+              <property name="minimumSize">
+               <size>
+                <width>60</width>
+                <height>0</height>
+               </size>
+              </property>
+              <property name="autoFillBackground">
+               <bool>true</bool>
+              </property>
+              <property name="frameShape">
+               <enum>QFrame::Box</enum>
+              </property>
+              <property name="frameShadow">
+               <enum>QFrame::Sunken</enum>
+              </property>
+              <property name="lineWidth">
+               <number>3</number>
+              </property>
+              <property name="text">
+               <string/>
+              </property>
+             </widget>
+            </item>
+            <item row="2" column="1">
+             <widget class="QLabel" name="imageBackGroundColorLabel">
+              <property name="minimumSize">
+               <size>
+                <width>60</width>
+                <height>0</height>
+               </size>
+              </property>
+              <property name="autoFillBackground">
+               <bool>true</bool>
+              </property>
+              <property name="frameShape">
+               <enum>QFrame::Box</enum>
+              </property>
+              <property name="frameShadow">
+               <enum>QFrame::Sunken</enum>
+              </property>
+              <property name="lineWidth">
+               <number>3</number>
+              </property>
+              <property name="text">
+               <string/>
+              </property>
+             </widget>
+            </item>
+           </layout>
+          </item>
+         </layout>
+        </widget>
+       </item>
+       <item>
+        <widget class="QGroupBox" name="groupBox">
+         <property name="title">
+          <string>Gallery</string>
+         </property>
+         <layout class="QVBoxLayout" name="verticalLayout">
+          <item>
+           <layout class="QGridLayout" name="gridLayout">
+            <item row="0" column="0">
+             <widget class="QLabel" name="label">
+              <property name="text">
+               <string>Rows</string>
+              </property>
+             </widget>
+            </item>
+            <item row="1" column="1">
+             <widget class="QSpinBox" name="columnsSpinBox"/>
+            </item>
+            <item row="0" column="1">
+             <widget class="QSpinBox" name="rowsSpinBox"/>
+            </item>
+            <item row="1" column="0">
+             <widget class="QLabel" name="label_2">
+              <property name="text">
+               <string>Columns</string>
+              </property>
+             </widget>
+            </item>
+           </layout>
+          </item>
+         </layout>
+        </widget>
+       </item>
+       <item>
+        <widget class="QGroupBox" name="groupBox_3">
+         <property name="title">
+          <string>Performance</string>
+         </property>
+         <layout class="QVBoxLayout" name="verticalLayout_4">
+          <item>
+           <layout class="QHBoxLayout" name="horizontalLayout">
+            <item>
+             <widget class="QCheckBox" name="slowCPUCheckBox">
+              <property name="layoutDirection">
+               <enum>Qt::RightToLeft</enum>
+              </property>
+              <property name="text">
+               <string>Check if slow CPU</string>
+              </property>
+             </widget>
+            </item>
+            <item>
+             <spacer name="horizontalSpacer_2">
+              <property name="orientation">
+               <enum>Qt::Horizontal</enum>
+              </property>
+              <property name="sizeHint" stdset="0">
+               <size>
+                <width>40</width>
+                <height>20</height>
+               </size>
+              </property>
+             </spacer>
+            </item>
+           </layout>
+          </item>
+         </layout>
+        </widget>
+       </item>
+      </layout>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/qsstv/config/hybridconfig.cpp b/qsstv/config/hybridconfig.cpp
new file mode 100644
index 0000000..34971d2
--- /dev/null
+++ b/qsstv/config/hybridconfig.cpp
@@ -0,0 +1,121 @@
+#include "hybridconfig.h"
+#include "ui_hybridconfig.h"
+#include "ftp.h"
+#include "hybridcrypt.h"
+
+#include <QMessageBox>
+
+bool enableHybridRx;
+bool enableSpecialServer;
+int hybridFtpPort;
+QString hybridFtpRemoteHost;
+QString hybridFtpRemoteDirectory;
+QString hybridFtpLogin;
+QString hybridFtpPassword;
+QString hybridFtpHybridFilesDirectory;
+
+
+hybridConfig::hybridConfig(QWidget *parent) :baseConfig(parent), ui(new Ui::hybridConfig)
+{
+    ui->setupUi(this);
+    //  connect(testFTPPushButton,SIGNAL(clicked()),SLOT(slotTestFTPPushButton()));
+    connect(ui->testHybridPushButton,SIGNAL(clicked()),SLOT(slotTestHybridPushButton()));
+}
+
+hybridConfig::~hybridConfig()
+{
+    delete ui;
+}
+
+void hybridConfig::readSettings()
+{
+    QSettings qSettings;
+    qSettings.beginGroup("HYBRID");
+    enableHybridRx=qSettings.value("enableHybridRx",true).toBool();
+    enableSpecialServer=qSettings.value("enableSpecialServer",false).toBool();
+    hybridFtpPort=qSettings.value("hybridFtpPort",21).toInt();
+    hybridFtpRemoteHost=qSettings.value("hybridFtpRemoteHost","").toString();
+    hybridFtpRemoteDirectory=qSettings.value("hybridFtpRemoteDirectory","").toString();
+    hybridFtpLogin=qSettings.value("hybridFtpLogin","").toString();
+    hybridFtpPassword=qSettings.value("hybridFtpPassword","").toString();
+    hybridFtpHybridFilesDirectory=qSettings.value("hybridFtpHybridFilesDirectory","HybridFiles1").toString();
+
+    qSettings.endGroup();
+    setParams();
+}
+
+void hybridConfig::writeSettings()
+{
+    QSettings qSettings;
+    getParams();
+    qSettings.beginGroup("HYBRID");
+    qSettings.setValue("enableHybridRx",enableHybridRx);
+    qSettings.setValue("enableSpecialServer",enableSpecialServer);
+    qSettings.setValue("hybridFtpPort",hybridFtpPort);
+    qSettings.setValue("hybridFtpRemoteHost",hybridFtpRemoteHost);
+    qSettings.setValue("hybridFtpRemoteDirectory",hybridFtpRemoteDirectory);
+    qSettings.setValue("hybridFtpLogin",hybridFtpLogin);
+    qSettings.setValue("hybridFtpPassword",hybridFtpPassword);
+    qSettings.setValue("hybridFtpHybridFilesDirectory",hybridFtpHybridFilesDirectory);
+    qSettings.endGroup();
+}
+
+void hybridConfig::getParams()
+{
+    bool enableHybridRxCopy=enableHybridRx;
+    bool enableSpecialServerCopy=enableSpecialServer;
+    int hybridFtpPortCopy=hybridFtpPort;
+    QString hybridFtpRemoteHostCopy=hybridFtpRemoteHost;
+    QString hybridFtpRemoteDirectoryCopy=hybridFtpRemoteDirectory;
+    QString hybridFtpLoginCopy=hybridFtpLogin;
+    QString hybridFtpPasswordCopy=hybridFtpPassword;
+
+
+    getValue(enableHybridRx,ui->enableHybridRxCheckBox);
+    getValue(enableSpecialServer,ui->enableSpecialServerCheckBox);
+    getValue(hybridFtpPort,ui->hybridFtpPortSpinBox);
+    getValue(hybridFtpRemoteHost,ui->hybridRemoteHostLineEdit);
+    getValue(hybridFtpRemoteDirectory,ui->hybridRemoteDirectoryLineEdit);
+    getValue(hybridFtpLogin,ui->hybridFtpLoginLineEdit);
+    getValue(hybridFtpPassword,ui->hybridFtpPasswordLineEdit);
+    getValue(hybridFtpHybridFilesDirectory,ui->hybridFilesDirectoryLineEdit);
+    changed=false;
+    if(  enableHybridRxCopy!=enableHybridRx
+         || enableSpecialServerCopy!=enableSpecialServer
+         || hybridFtpPortCopy!=hybridFtpPort
+         || hybridFtpRemoteHostCopy!=hybridFtpRemoteHost
+         || hybridFtpRemoteDirectoryCopy!=hybridFtpRemoteDirectory
+         || hybridFtpLoginCopy!=hybridFtpLogin
+         || hybridFtpPasswordCopy!=hybridFtpPassword)
+        changed=true;
+
+
+
+
+}
+
+void hybridConfig::setParams()
+{
+    setValue(enableHybridRx,ui->enableHybridRxCheckBox);
+    setValue(enableSpecialServer,ui->enableSpecialServerCheckBox);
+    setValue(hybridFtpPort,ui->hybridFtpPortSpinBox);
+    setValue(hybridFtpRemoteHost,ui->hybridRemoteHostLineEdit);
+    setValue(hybridFtpRemoteDirectory,ui->hybridRemoteDirectoryLineEdit);
+    setValue(hybridFtpLogin,ui->hybridFtpLoginLineEdit);
+    setValue(hybridFtpPassword,ui->hybridFtpPasswordLineEdit);
+    setValue(hybridFtpHybridFilesDirectory,ui->hybridFilesDirectoryLineEdit);
+}
+
+
+void hybridConfig::slotTestHybridPushButton()
+{
+    QString msg;
+    ftpInterface fInt("TestHybridConnection");
+    ui->testHybridPushButton->setDisabled(true);
+    getParams();
+    hybridCrypt hc;
+    fInt.setupConnection(hc.host(),hc.port(),hc.user(),hc.passwd(),hc.dir()+"/"+hybridFtpHybridFilesDirectory);
+    msg=fInt.execFTPTest();
+    ui->testHybridPushButton->setDisabled(false);
+    QMessageBox::information(this,"Test Connection",msg);
+}
diff --git a/qsstv/config/hybridconfig.h b/qsstv/config/hybridconfig.h
new file mode 100644
index 0000000..a287ea4
--- /dev/null
+++ b/qsstv/config/hybridconfig.h
@@ -0,0 +1,38 @@
+#ifndef HYBRIDCONFIG_H
+#define HYBRIDCONFIG_H
+
+#include "baseconfig.h"
+
+extern bool enableHybridRx;
+extern bool enableSpecialServer;
+extern int hybridFtpPort;
+extern QString hybridFtpRemoteHost;
+extern QString hybridFtpRemoteDirectory;
+extern QString hybridFtpLogin;
+extern QString hybridFtpPassword;
+extern QString hybridFtpHybridFilesDirectory;
+
+
+namespace Ui {
+class hybridConfig;
+}
+
+class hybridConfig : public baseConfig
+{
+  Q_OBJECT
+  
+public:
+  explicit hybridConfig(QWidget *parent = 0);
+  ~hybridConfig();
+  void readSettings();
+  void writeSettings();
+  void getParams();
+  void setParams();
+private slots:
+  void slotTestHybridPushButton();
+  
+private:
+  Ui::hybridConfig *ui;
+};
+
+#endif // HYBRIDCONFIG_H
diff --git a/qsstv/config/hybridconfig.ui b/qsstv/config/hybridconfig.ui
new file mode 100644
index 0000000..6168911
--- /dev/null
+++ b/qsstv/config/hybridconfig.ui
@@ -0,0 +1,456 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>hybridConfig</class>
+ <widget class="QWidget" name="hybridConfig">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>730</width>
+    <height>372</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QCheckBox" name="enableHybridRxCheckBox">
+     <property name="text">
+      <string>Enable Reception in Hybrid Mode </string>
+     </property>
+     <property name="checked">
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="_3">
+     <property name="spacing">
+      <number>6</number>
+     </property>
+     <property name="leftMargin">
+      <number>0</number>
+     </property>
+     <property name="topMargin">
+      <number>0</number>
+     </property>
+     <property name="rightMargin">
+      <number>0</number>
+     </property>
+     <property name="bottomMargin">
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="QCheckBox" name="enableSpecialServerCheckBox">
+       <property name="text">
+        <string>Enable Special Server</string>
+       </property>
+       <property name="checked">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeType">
+        <enum>QSizePolicy::Expanding</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>20</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QLabel" name="ftpPortLabel_2">
+       <property name="text">
+        <string>FTP Port</string>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QSpinBox" name="hybridFtpPortSpinBox">
+       <property name="minimum">
+        <number>1</number>
+       </property>
+       <property name="maximum">
+        <number>10000</number>
+       </property>
+       <property name="value">
+        <number>21</number>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeType">
+        <enum>QSizePolicy::Preferred</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>20</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="_2">
+     <property name="spacing">
+      <number>6</number>
+     </property>
+     <property name="leftMargin">
+      <number>0</number>
+     </property>
+     <property name="topMargin">
+      <number>0</number>
+     </property>
+     <property name="rightMargin">
+      <number>0</number>
+     </property>
+     <property name="bottomMargin">
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="QLabel" name="hybridRemoteHostLabel">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>145</width>
+         <height>25</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>Host</string>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="hybridRemoteHostLineEdit"/>
+     </item>
+     <item>
+      <spacer>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeType">
+        <enum>QSizePolicy::Preferred</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>20</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="_7">
+     <property name="spacing">
+      <number>6</number>
+     </property>
+     <property name="leftMargin">
+      <number>0</number>
+     </property>
+     <property name="topMargin">
+      <number>0</number>
+     </property>
+     <property name="rightMargin">
+      <number>0</number>
+     </property>
+     <property name="bottomMargin">
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="QLabel" name="hybridFtpLoginLabel">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>145</width>
+         <height>25</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>Login</string>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="hybridFtpLoginLineEdit"/>
+     </item>
+     <item>
+      <spacer>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeType">
+        <enum>QSizePolicy::Preferred</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>20</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="_6">
+     <property name="spacing">
+      <number>6</number>
+     </property>
+     <property name="leftMargin">
+      <number>0</number>
+     </property>
+     <property name="topMargin">
+      <number>0</number>
+     </property>
+     <property name="rightMargin">
+      <number>0</number>
+     </property>
+     <property name="bottomMargin">
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="QLabel" name="hybridPasswordLabel">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>145</width>
+         <height>25</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>Password</string>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="hybridFtpPasswordLineEdit">
+       <property name="echoMode">
+        <enum>QLineEdit::Password</enum>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeType">
+        <enum>QSizePolicy::Preferred</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>20</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="_8">
+     <property name="spacing">
+      <number>6</number>
+     </property>
+     <property name="leftMargin">
+      <number>0</number>
+     </property>
+     <property name="topMargin">
+      <number>0</number>
+     </property>
+     <property name="rightMargin">
+      <number>0</number>
+     </property>
+     <property name="bottomMargin">
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="QLabel" name="hybridRemoteDirectoryLabel">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>145</width>
+         <height>25</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>Directory</string>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="hybridRemoteDirectoryLineEdit"/>
+     </item>
+     <item>
+      <spacer>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeType">
+        <enum>QSizePolicy::Preferred</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>20</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="_9">
+     <property name="spacing">
+      <number>6</number>
+     </property>
+     <property name="leftMargin">
+      <number>0</number>
+     </property>
+     <property name="topMargin">
+      <number>0</number>
+     </property>
+     <property name="rightMargin">
+      <number>0</number>
+     </property>
+     <property name="bottomMargin">
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="QLabel" name="hybridRemoteDirectoryLabel_2">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>145</width>
+         <height>25</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>Hybrid Files Directory</string>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="hybridFilesDirectoryLineEdit"/>
+     </item>
+     <item>
+      <spacer>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeType">
+        <enum>QSizePolicy::Preferred</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>20</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout_2" stretch="1,0">
+     <item>
+      <widget class="QLabel" name="label">
+       <property name="text">
+        <string>By default all hybrid files are uploaded to a default server ("Enable Special Server"  not checked). If you wish to use your own server for sending in Hybrid mode then  you need to check "Enable Special Server" and fill in the details. See manual for more information.</string>
+       </property>
+       <property name="wordWrap">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="testHybridPushButton">
+       <property name="text">
+        <string>Test connection</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <spacer name="spacer">
+     <property name="orientation">
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeType">
+      <enum>QSizePolicy::Expanding</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>20</width>
+       <height>38</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/qsstv/config/hybridnotifyconfig.cpp b/qsstv/config/hybridnotifyconfig.cpp
new file mode 100644
index 0000000..dc68b6c
--- /dev/null
+++ b/qsstv/config/hybridnotifyconfig.cpp
@@ -0,0 +1,123 @@
+#include "hybridnotifyconfig.h"
+#include "ui_hybridnotifyconfig.h"
+#include "ftp.h"
+
+#include <QMessageBox>
+
+bool enableHybridNotify;
+bool enableHybridNotifySpecialServer;
+int hybridNotifyPort;
+QString hybridNotifyRemoteHost;
+QString hybridNotifyRemoteDir;
+QString hybridNotifyLogin;
+QString hybridNotifyPassword;
+QString hybridNotifyDir;
+
+
+hybridNotifyConfig::hybridNotifyConfig(QWidget *parent) :baseConfig(parent), ui(new Ui::hybridNotifyConfig)
+{
+  ui->setupUi(this);
+//  connect(testFTPPushButton,SIGNAL(clicked()),SLOT(slotTestFTPPushButton()));
+  connect(ui->testNotifyPushButton,SIGNAL(clicked()),SLOT(slotTestNotifyPushButton()));
+}
+
+hybridNotifyConfig::~hybridNotifyConfig()
+{
+  delete ui;
+}
+
+void hybridNotifyConfig::readSettings()
+{
+  QSettings qSettings;
+  qSettings.beginGroup("HYBRID_NOTIFY");
+  enableHybridNotify=qSettings.value("enableHybridNotify",true).toBool();
+  enableHybridNotifySpecialServer=qSettings.value("enableHybridNotifySpecialServer",false).toBool();
+  hybridNotifyPort=qSettings.value("hybridNotifyPort",21).toInt();
+  hybridNotifyRemoteHost=qSettings.value("hybridNotifyRemoteHost","").toString();
+  hybridNotifyRemoteDir=qSettings.value("hybridNotifyRemoteDir","").toString();
+  hybridNotifyLogin=qSettings.value("hybridNotifyLogin","").toString();
+  hybridNotifyPassword=qSettings.value("hybridNotifyPassword","").toString();
+  hybridNotifyDir=qSettings.value("hybridNotifyDirectory","RxOkNotifications1").toString();
+  
+  qSettings.endGroup();
+  setParams();
+}
+
+void hybridNotifyConfig::writeSettings()
+{
+  QSettings qSettings;
+  getParams();
+  qSettings.beginGroup("HYBRID_NOTIFY");
+  qSettings.setValue("enableHybridNotify",enableHybridNotify);
+  qSettings.setValue("enableHybridNotifySpecialServer",enableHybridNotifySpecialServer);
+  qSettings.setValue("hybridNotifyPort",hybridNotifyPort);
+  qSettings.setValue("hybridNotifyRemoteHost",hybridNotifyRemoteHost);
+  qSettings.setValue("hybridNotifyRemoteDir",hybridNotifyRemoteDir);
+  qSettings.setValue("hybridNotifyLogin",hybridNotifyLogin);
+  qSettings.setValue("hybridNotifyPassword",hybridNotifyPassword);
+  qSettings.setValue("hybridNotifyDir",hybridNotifyDir);
+  qSettings.endGroup();
+}
+
+void hybridNotifyConfig::getParams()
+{
+  bool enableHybridNotifyCopy=enableHybridNotify;
+  bool enableHybridNotifySpecialServerCopy=enableHybridNotifySpecialServer;
+  int hybridNotifyPortCopy=hybridNotifyPort;
+  QString hybridNotifyRemoteHostCopy=hybridNotifyRemoteHost;
+  QString hybridNotifyRemoteDirCopy=hybridNotifyRemoteDir;
+  QString hybridNotifyDirCopy=hybridNotifyDir;
+  QString hybridNotifyLoginCopy=hybridNotifyLogin;
+  QString hybridNotifyPasswordCopy=hybridNotifyPassword;
+
+
+  getValue(enableHybridNotify,ui->enableHybridNotifyCheckBox);
+  getValue(enableHybridNotifySpecialServer,ui->enableHybridNotifySpecialServerCheckBox);
+  getValue(hybridNotifyPort,ui->hybridNotifyPortSpinBox);
+  getValue(hybridNotifyRemoteHost,ui->hybridNotifyRemoteHostLineEdit);
+  getValue(hybridNotifyRemoteDir,ui->hybridNotifyRemoteDirLineEdit);
+  getValue(hybridNotifyLogin,ui->hybridNotifyLoginLineEdit);
+  getValue(hybridNotifyPassword,ui->hybridNotifyPasswordLineEdit);
+  getValue(hybridNotifyDir,ui->hybridNotifyDirLineEdit);
+  changed=false;
+  if(  enableHybridNotifyCopy!=enableHybridNotify
+       || enableHybridNotifySpecialServerCopy!=enableHybridNotifySpecialServer
+       || hybridNotifyPortCopy!=hybridNotifyPort
+       || hybridNotifyRemoteHostCopy!=hybridNotifyRemoteHost
+       || hybridNotifyRemoteDirCopy!=hybridNotifyRemoteDir
+       || hybridNotifyDirCopy!=hybridNotifyDir
+       || hybridNotifyLoginCopy!=hybridNotifyLogin
+       || hybridNotifyPasswordCopy!=hybridNotifyPassword)
+    changed=true;
+
+
+
+
+}
+
+void hybridNotifyConfig::setParams()
+{
+  setValue(enableHybridNotify,ui->enableHybridNotifyCheckBox);
+  setValue(enableHybridNotifySpecialServer,ui->enableHybridNotifySpecialServerCheckBox);
+  setValue(hybridNotifyPort,ui->hybridNotifyPortSpinBox);
+  setValue(hybridNotifyRemoteHost,ui->hybridNotifyRemoteHostLineEdit);
+  setValue(hybridNotifyRemoteDir,ui->hybridNotifyRemoteDirLineEdit);
+  setValue(hybridNotifyLogin,ui->hybridNotifyLoginLineEdit);
+  setValue(hybridNotifyPassword,ui->hybridNotifyPasswordLineEdit);
+  setValue(hybridNotifyDir,ui->hybridNotifyDirLineEdit);
+}
+
+
+void hybridNotifyConfig::slotTestNotifyPushButton()
+{
+  QString msg;
+  ftpInterface fInt("TestNotifyConnection");
+  ui->testNotifyPushButton->setDisabled(true);
+  getParams();
+  fInt.setupConnection(hybridNotifyRemoteHost,hybridNotifyPort,
+          hybridNotifyLogin,hybridNotifyPassword,hybridNotifyRemoteDir+"/"+hybridNotifyDir);
+  msg=fInt.execFTPTest();
+  ui->testNotifyPushButton->setDisabled(false);
+  
+  QMessageBox::information(this,"Test Connection",msg);
+}
diff --git a/qsstv/config/hybridnotifyconfig.h b/qsstv/config/hybridnotifyconfig.h
new file mode 100644
index 0000000..74b0911
--- /dev/null
+++ b/qsstv/config/hybridnotifyconfig.h
@@ -0,0 +1,38 @@
+#ifndef HYBRIDNOTIFYCONFIG_H
+#define HYBRIDNOTIFYCONFIG_H
+
+#include "baseconfig.h"
+
+extern bool enableHybridNotify;
+extern bool enableHybridNotifySpecialServer;
+extern int hybridNotifyPort;
+extern QString hybridNotifyRemoteHost;
+extern QString hybridNotifyRemoteDir;
+extern QString hybridNotifyLogin;
+extern QString hybridNotifyPassword;
+extern QString hybridNotifyDir;
+
+
+namespace Ui {
+class hybridNotifyConfig;
+}
+
+class hybridNotifyConfig : public baseConfig
+{
+  Q_OBJECT
+  
+public:
+  explicit hybridNotifyConfig(QWidget *parent = 0);
+  ~hybridNotifyConfig();
+  void readSettings();
+  void writeSettings();
+  void getParams();
+  void setParams();
+private slots:
+  void slotTestNotifyPushButton();
+  
+private:
+  Ui::hybridNotifyConfig *ui;
+};
+
+#endif // HYBRIDNOTIFYCONFIG_H
diff --git a/qsstv/config/hybridnotifyconfig.ui b/qsstv/config/hybridnotifyconfig.ui
new file mode 100644
index 0000000..d2df05c
--- /dev/null
+++ b/qsstv/config/hybridnotifyconfig.ui
@@ -0,0 +1,456 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>hybridNotifyConfig</class>
+ <widget class="QWidget" name="hybridNotifyConfig">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>730</width>
+    <height>372</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QCheckBox" name="enableHybridNotifyCheckBox">
+     <property name="text">
+      <string>Enable Notifications in Hybrid Mode </string>
+     </property>
+     <property name="checked">
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="_3">
+     <property name="spacing">
+      <number>6</number>
+     </property>
+     <property name="leftMargin">
+      <number>0</number>
+     </property>
+     <property name="topMargin">
+      <number>0</number>
+     </property>
+     <property name="rightMargin">
+      <number>0</number>
+     </property>
+     <property name="bottomMargin">
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="QCheckBox" name="enableHybridNotifySpecialServerCheckBox">
+       <property name="text">
+        <string>Enable Special Server</string>
+       </property>
+       <property name="checked">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeType">
+        <enum>QSizePolicy::Expanding</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>20</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QLabel" name="ftpPortLabel_2">
+       <property name="text">
+        <string>FTP Port</string>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QSpinBox" name="hybridNotifyPortSpinBox">
+       <property name="minimum">
+        <number>1</number>
+       </property>
+       <property name="maximum">
+        <number>10000</number>
+       </property>
+       <property name="value">
+        <number>21</number>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeType">
+        <enum>QSizePolicy::Preferred</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>20</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="_2">
+     <property name="spacing">
+      <number>6</number>
+     </property>
+     <property name="leftMargin">
+      <number>0</number>
+     </property>
+     <property name="topMargin">
+      <number>0</number>
+     </property>
+     <property name="rightMargin">
+      <number>0</number>
+     </property>
+     <property name="bottomMargin">
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="QLabel" name="hybridNotifyRemoteHostLabel">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>145</width>
+         <height>25</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>Host</string>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="hybridNotifyRemoteHostLineEdit"/>
+     </item>
+     <item>
+      <spacer>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeType">
+        <enum>QSizePolicy::Preferred</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>20</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="_7">
+     <property name="spacing">
+      <number>6</number>
+     </property>
+     <property name="leftMargin">
+      <number>0</number>
+     </property>
+     <property name="topMargin">
+      <number>0</number>
+     </property>
+     <property name="rightMargin">
+      <number>0</number>
+     </property>
+     <property name="bottomMargin">
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="QLabel" name="hybridNotifyLoginLabel">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>145</width>
+         <height>25</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>Login</string>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="hybridNotifyLoginLineEdit"/>
+     </item>
+     <item>
+      <spacer>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeType">
+        <enum>QSizePolicy::Preferred</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>20</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="_6">
+     <property name="spacing">
+      <number>6</number>
+     </property>
+     <property name="leftMargin">
+      <number>0</number>
+     </property>
+     <property name="topMargin">
+      <number>0</number>
+     </property>
+     <property name="rightMargin">
+      <number>0</number>
+     </property>
+     <property name="bottomMargin">
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="QLabel" name="hybridNotifyPasswordLabel">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>145</width>
+         <height>25</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>Password</string>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="hybridNotifyPasswordLineEdit">
+       <property name="echoMode">
+        <enum>QLineEdit::Password</enum>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeType">
+        <enum>QSizePolicy::Preferred</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>20</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="_8">
+     <property name="spacing">
+      <number>6</number>
+     </property>
+     <property name="leftMargin">
+      <number>0</number>
+     </property>
+     <property name="topMargin">
+      <number>0</number>
+     </property>
+     <property name="rightMargin">
+      <number>0</number>
+     </property>
+     <property name="bottomMargin">
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="QLabel" name="hybridNotifyRemoteDirLabel">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>145</width>
+         <height>25</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>Directory</string>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="hybridNotifyRemoteDirLineEdit"/>
+     </item>
+     <item>
+      <spacer>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeType">
+        <enum>QSizePolicy::Preferred</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>20</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="_9">
+     <property name="spacing">
+      <number>6</number>
+     </property>
+     <property name="leftMargin">
+      <number>0</number>
+     </property>
+     <property name="topMargin">
+      <number>0</number>
+     </property>
+     <property name="rightMargin">
+      <number>0</number>
+     </property>
+     <property name="bottomMargin">
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="QLabel" name="hybridNotifyDirLabel_2">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>145</width>
+         <height>25</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>Notifications Directory</string>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="hybridNotifyDirLineEdit"/>
+     </item>
+     <item>
+      <spacer>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeType">
+        <enum>QSizePolicy::Preferred</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>20</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout_2" stretch="1,0">
+     <item>
+      <widget class="QLabel" name="label">
+       <property name="text">
+        <string><html><head/><body><p>By default all RxNotification files are uploaded to a default server (&quot;Enable Special Server&quot;  not checked). If you wish to use your own server for RxNotifications in Hybrid mode then  you need to check &quot;Enable Special Server&quot; and fill in the details. See manual for more information.</p></body></html></string>
+       </property>
+       <property name="wordWrap">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="testNotifyPushButton">
+       <property name="text">
+        <string>Test connection</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <spacer name="spacer">
+     <property name="orientation">
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeType">
+      <enum>QSizePolicy::Expanding</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>20</width>
+       <height>38</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/qsstv/config/operatorconfig.cpp b/qsstv/config/operatorconfig.cpp
new file mode 100644
index 0000000..702a589
--- /dev/null
+++ b/qsstv/config/operatorconfig.cpp
@@ -0,0 +1,77 @@
+#include "operatorconfig.h"
+#include "ui_operatorconfig.h"
+
+QString myCallsign;
+QString myQth;
+QString myLocator;
+QString myLastname;
+QString myFirstname;
+QString lastReceivedCall;
+
+operatorConfig::operatorConfig(QWidget *parent) :  baseConfig(parent), ui(new Ui::operatorConfig)
+{
+  ui->setupUi(this);
+}
+
+operatorConfig::~operatorConfig()
+{
+  delete ui;
+}
+
+void operatorConfig::readSettings()
+{
+  QSettings qSettings;
+  qSettings.beginGroup("PERSONAL");
+  myCallsign=qSettings.value("callsign",QString("NOCALL")).toString();
+  myQth=qSettings.value("qth",QString("NOWHERE")).toString();
+  myLastname=qSettings.value("lastname",QString("NONAME")).toString();
+  myFirstname=qSettings.value("firstname",QString("NOFIRSTNAME")).toString();
+  myLocator=qSettings.value("locator",QString("NOLOCATOR")).toString();
+  qSettings.endGroup();
+  setParams();
+}
+
+void operatorConfig::writeSettings()
+{
+  QSettings qSettings;
+  getParams();
+  qSettings.beginGroup("PERSONAL");
+  qSettings.setValue("callsign",myCallsign);
+  qSettings.setValue("qth",myQth);
+  qSettings.setValue("locator",myLocator);
+  qSettings.setValue("lastname",myLastname);
+  qSettings.setValue("firstname",myFirstname);
+  qSettings.endGroup();
+}
+
+void operatorConfig::getParams()
+{
+  QString myCallsignCopy=myCallsign;
+  QString myQthCopy=myQth;
+  QString myLocatorCopy= myLocator;
+  QString myLastnameCopy=myLastname;
+  QString myFirstnameCopy=myFirstname;
+
+  getValue(myCallsign,ui->callsignLineEdit);
+  getValue(myLastname,ui->lastnameLineEdit);
+  getValue(myFirstname,ui->firstnameLineEdit);
+  getValue(myQth,ui->qthLineEdit);
+  getValue(myLocator,ui->locatorLineEdit);
+  changed=false;
+  if( myCallsignCopy!=myCallsign
+     || myQthCopy!=myQth
+     || myLocatorCopy!= myLocator
+     || myLastnameCopy!=myLastname
+     || myFirstnameCopy!=myFirstname)
+    changed=true;
+}
+
+void operatorConfig::setParams()
+{
+  setValue(myCallsign,ui->callsignLineEdit);
+  setValue(myLastname,ui->lastnameLineEdit);
+  setValue(myFirstname,ui->firstnameLineEdit);
+  setValue(myQth,ui->qthLineEdit);
+  setValue(myLocator,ui->locatorLineEdit);
+
+}
diff --git a/qsstv/config/operatorconfig.h b/qsstv/config/operatorconfig.h
new file mode 100644
index 0000000..88acd56
--- /dev/null
+++ b/qsstv/config/operatorconfig.h
@@ -0,0 +1,33 @@
+#ifndef OPERATORCONFIG_H
+#define OPERATORCONFIG_H
+#include "baseconfig.h"
+
+extern QString myCallsign;
+extern QString myQth;
+extern QString myLocator;
+extern QString myLastname;
+extern QString myFirstname;
+extern QString lastReceivedCall;
+
+
+namespace Ui {
+class operatorConfig;
+}
+
+class operatorConfig : public baseConfig
+{
+  Q_OBJECT
+
+public:
+  explicit operatorConfig(QWidget *parent = 0);
+  ~operatorConfig();
+  void readSettings();
+  void writeSettings();
+  void getParams();
+  void setParams();
+
+private:
+  Ui::operatorConfig *ui;
+};
+
+#endif // OPERATORCONFIG_H
diff --git a/qsstv/config/operatorconfig.ui b/qsstv/config/operatorconfig.ui
new file mode 100644
index 0000000..0320960
--- /dev/null
+++ b/qsstv/config/operatorconfig.ui
@@ -0,0 +1,282 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>operatorConfig</class>
+ <widget class="QWidget" name="operatorConfig">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>588</width>
+    <height>221</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <layout class="QHBoxLayout" name="_4">
+     <item>
+      <widget class="QLabel" name="firstnameLabel">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>130</width>
+         <height>25</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>Firstname</string>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="firstnameLineEdit">
+       <property name="alignment">
+        <set>Qt::AlignRight</set>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeType">
+        <enum>QSizePolicy::Expanding</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>120</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="_3">
+     <item>
+      <widget class="QLabel" name="lastnameLabel">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>130</width>
+         <height>25</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>Lastname</string>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="lastnameLineEdit">
+       <property name="alignment">
+        <set>Qt::AlignRight</set>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeType">
+        <enum>QSizePolicy::Expanding</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>120</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="_5">
+     <item>
+      <widget class="QLabel" name="callsignLabel">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>130</width>
+         <height>25</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>Callsign</string>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="callsignLineEdit">
+       <property name="alignment">
+        <set>Qt::AlignRight</set>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeType">
+        <enum>QSizePolicy::Expanding</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>120</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="_2">
+     <item>
+      <widget class="QLabel" name="qthLabel">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>130</width>
+         <height>25</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>QTH</string>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="qthLineEdit">
+       <property name="alignment">
+        <set>Qt::AlignRight</set>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeType">
+        <enum>QSizePolicy::Expanding</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>120</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout">
+     <item>
+      <widget class="QLabel" name="locatorLabel">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>130</width>
+         <height>25</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>Locator</string>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="locatorLineEdit">
+       <property name="alignment">
+        <set>Qt::AlignRight</set>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeType">
+        <enum>QSizePolicy::Expanding</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>120</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <spacer name="spacer">
+     <property name="orientation">
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeType">
+      <enum>QSizePolicy::Expanding</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>21</width>
+       <height>30</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/qsstv/config/repeaterconfig.cpp b/qsstv/config/repeaterconfig.cpp
new file mode 100644
index 0000000..7f3e623
--- /dev/null
+++ b/qsstv/config/repeaterconfig.cpp
@@ -0,0 +1,110 @@
+#include "repeaterconfig.h"
+#include "ui_repeaterconfig.h"
+
+
+bool repeaterEnable;
+int repeaterImageInterval;
+esstvMode repeaterTxMode;
+QString repeaterImage1;
+QString repeaterImage2;
+QString repeaterImage3;
+QString repeaterImage4;
+QString repeaterAcknowledge;
+QString repeaterTemplate;
+QString idleTemplate;
+
+repeaterConfig::repeaterConfig(QWidget *parent) : baseConfig(parent),  ui(new Ui::repeaterConfig)
+{
+  ui->setupUi(this);
+}
+
+repeaterConfig::~repeaterConfig()
+{
+  delete ui;
+}
+
+void repeaterConfig::readSettings()
+{
+  QSettings qSettings;
+  qSettings.beginGroup("REPEATER");
+  repeaterImageInterval=qSettings.value("repeaterImageInterval",10).toInt();
+  repeaterEnable=qSettings.value("repeaterEnable",false).toBool();
+  repeaterTxMode=(esstvMode)qSettings.value("repeaterTxMode",0).toInt();
+  repeaterImage1=qSettings.value("repeaterImage1","").toString();
+  repeaterImage2=qSettings.value("repeaterImage2","").toString();
+  repeaterImage3=qSettings.value("repeaterImage3","").toString();
+  repeaterImage4=qSettings.value("repeaterImage4","").toString();
+  repeaterAcknowledge=qSettings.value("repeaterAcknowledge","").toString();
+  repeaterTemplate=qSettings.value("repeaterTemplate","").toString();
+  idleTemplate=qSettings.value("idleTemplate","").toString();
+  qSettings.endGroup();
+  setParams();
+}
+
+void repeaterConfig::writeSettings()
+{
+  QSettings qSettings;
+  getParams();
+  qSettings.beginGroup("REPEATER");
+  qSettings.setValue("repeaterImageInterval",repeaterImageInterval);
+  qSettings.setValue("repeaterEnable",repeaterEnable);
+  qSettings.setValue("repeaterTxMode",repeaterTxMode);
+  qSettings.setValue("repeaterImage1",repeaterImage1);
+  qSettings.setValue("repeaterImage2",repeaterImage2);
+  qSettings.setValue("repeaterImage3",repeaterImage3);
+  qSettings.setValue("repeaterImage4",repeaterImage4);
+  qSettings.setValue("repeaterAcknowledge",repeaterAcknowledge);
+  qSettings.setValue("repeaterTemplate",repeaterTemplate);
+  qSettings.setValue("idleTemplate",idleTemplate);
+  qSettings.endGroup();
+}
+
+void repeaterConfig::getParams()
+{
+  int temp;
+  bool repeaterEnableCopy=repeaterEnable;
+  int repeaterImageIntervalCopy=repeaterImageInterval;
+  esstvMode repeaterTxModeCopy=repeaterTxMode;
+  QString repeaterImage1Copy=repeaterImage1;
+  QString repeaterImage2Copy=repeaterImage2;
+  QString repeaterImage3Copy=repeaterImage3;
+  QString repeaterImage4Copy=repeaterImage4;
+  QString repeaterAcknowledgeCopy=repeaterAcknowledge;
+  QString repeaterTemplateCopy=repeaterTemplate;
+  QString idleTemplateCopy=idleTemplate;
+  getValue(repeaterImageInterval,ui->imageIntervalSpinBox);
+  getValue(repeaterEnable,ui->repeaterEnableCheckBox);
+  getIndex(temp,ui->repeaterTxModeComboBox);
+  repeaterTxMode=(esstvMode)temp;
+  getValue(repeaterImage1,ui->repeaterImage1LineEdit);
+  getValue(repeaterImage2,ui->repeaterImage2LineEdit);
+  getValue(repeaterImage3,ui->repeaterImage3LineEdit);
+  getValue(repeaterImage4,ui->repeaterImage4LineEdit);
+  getValue(idleTemplate,ui->idleTemplateLineEdit);
+  getValue(repeaterTemplate,ui->repeaterTemplateLineEdit);
+  changed=false;
+  if(  repeaterEnableCopy!=repeaterEnable
+       || repeaterImageIntervalCopy!=repeaterImageInterval
+       || repeaterTxModeCopy!=repeaterTxMode
+       || repeaterImage1Copy!=repeaterImage1
+       || repeaterImage2Copy!=repeaterImage2
+       || repeaterImage3Copy!=repeaterImage3
+       || repeaterImage4Copy!=repeaterImage4
+       || repeaterAcknowledgeCopy!=repeaterAcknowledge
+       || repeaterTemplateCopy!=repeaterTemplate
+       || idleTemplateCopy!=idleTemplate)
+    changed=true;
+}
+
+void repeaterConfig::setParams()
+{;
+  setValue(repeaterImageInterval,ui->imageIntervalSpinBox);
+  setValue(repeaterEnable,ui->repeaterEnableCheckBox);
+  setIndex(repeaterTxMode,ui->repeaterTxModeComboBox);
+  setValue(repeaterImage1,ui->repeaterImage1LineEdit);
+  setValue(repeaterImage2,ui->repeaterImage2LineEdit);
+  setValue(repeaterImage3,ui->repeaterImage3LineEdit);
+  setValue(repeaterImage4,ui->repeaterImage4LineEdit);
+  setValue(idleTemplate,ui->idleTemplateLineEdit);
+  setValue(repeaterTemplate,ui->repeaterTemplateLineEdit);
+}
diff --git a/qsstv/config/repeaterconfig.h b/qsstv/config/repeaterconfig.h
new file mode 100644
index 0000000..ec47ca6
--- /dev/null
+++ b/qsstv/config/repeaterconfig.h
@@ -0,0 +1,39 @@
+#ifndef REPEATERCONFIG_H
+#define REPEATERCONFIG_H
+
+#include "baseconfig.h"
+#include "sstv/sstvparam.h"
+
+
+extern bool repeaterEnable;
+extern int repeaterImageInterval;
+extern esstvMode repeaterTxMode;
+extern QString repeaterImage1;
+extern QString repeaterImage2;
+extern QString repeaterImage3;
+extern QString repeaterImage4;
+extern QString repeaterAcknowledge;
+extern QString repeaterTemplate;
+extern QString idleTemplate;
+
+namespace Ui {
+class repeaterConfig;
+}
+
+class repeaterConfig : public baseConfig
+{
+  Q_OBJECT
+  
+public:
+  explicit repeaterConfig(QWidget *parent = 0);
+  ~repeaterConfig();
+  void readSettings();
+  void writeSettings();
+  void getParams();
+  void setParams();
+  
+private:
+  Ui::repeaterConfig *ui;
+};
+
+#endif // REPEATERCONFIG_H
diff --git a/qsstv/config/repeaterconfig.ui b/qsstv/config/repeaterconfig.ui
new file mode 100644
index 0000000..3407ac1
--- /dev/null
+++ b/qsstv/config/repeaterconfig.ui
@@ -0,0 +1,340 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>repeaterConfig</class>
+ <widget class="QWidget" name="repeaterConfig">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>599</width>
+    <height>259</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <property name="spacing">
+    <number>2</number>
+   </property>
+   <property name="margin">
+    <number>1</number>
+   </property>
+   <item>
+    <layout class="QHBoxLayout" name="_2">
+     <item>
+      <widget class="QCheckBox" name="repeaterEnableCheckBox">
+       <property name="text">
+        <string>Enable Repeater</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeType">
+        <enum>QSizePolicy::Expanding</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>20</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <layout class="QHBoxLayout" name="_3">
+       <property name="spacing">
+        <number>6</number>
+       </property>
+       <property name="margin">
+        <number>0</number>
+       </property>
+       <item>
+        <widget class="QLabel" name="imageIntervalLabel">
+         <property name="text">
+          <string>Image Interval (min)</string>
+         </property>
+         <property name="wordWrap">
+          <bool>false</bool>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QSpinBox" name="imageIntervalSpinBox">
+         <property name="minimum">
+          <number>5</number>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </item>
+     <item>
+      <spacer>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeType">
+        <enum>QSizePolicy::Expanding</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>60</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <layout class="QHBoxLayout" name="_4">
+       <property name="spacing">
+        <number>6</number>
+       </property>
+       <property name="margin">
+        <number>0</number>
+       </property>
+       <item>
+        <widget class="QLabel" name="repeaterTxModeLabel">
+         <property name="text">
+          <string>Repeater TX mode</string>
+         </property>
+         <property name="wordWrap">
+          <bool>false</bool>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QComboBox" name="repeaterTxModeComboBox"/>
+       </item>
+      </layout>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="_6">
+     <property name="spacing">
+      <number>6</number>
+     </property>
+     <property name="margin">
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="QLabel" name="rep1Label">
+       <property name="text">
+        <string>Idle Image 1</string>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="repeaterImage1LineEdit">
+       <property name="modified">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="rp1BrowseButton">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="text">
+        <string>Browse ...</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="_5">
+     <property name="spacing">
+      <number>6</number>
+     </property>
+     <property name="margin">
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="QLabel" name="rp2Label">
+       <property name="text">
+        <string>Idle Image 2</string>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="repeaterImage2LineEdit">
+       <property name="modified">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="rp2BrowseButton">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="text">
+        <string>Browse ...</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="_7">
+     <property name="spacing">
+      <number>6</number>
+     </property>
+     <property name="margin">
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="QLabel" name="rp3Label">
+       <property name="text">
+        <string>Idle Image 3</string>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="repeaterImage3LineEdit">
+       <property name="modified">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="rp3BrowseButton">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="text">
+        <string>Browse ...</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout">
+     <property name="spacing">
+      <number>6</number>
+     </property>
+     <property name="margin">
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="QLabel" name="rp4Label">
+       <property name="text">
+        <string>Idle Image 4</string>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="repeaterImage4LineEdit">
+       <property name="modified">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="rp4BrowseButton">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="text">
+        <string>Browse ...</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout_6">
+     <item>
+      <widget class="QLabel" name="Label">
+       <property name="text">
+        <string>Idle Template</string>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="idleTemplateLineEdit"/>
+     </item>
+     <item>
+      <widget class="QPushButton" name="idleTemplateBrowseButton">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="text">
+        <string>Browse ...</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout_7">
+     <item>
+      <widget class="QLabel" name="ackLabel">
+       <property name="text">
+        <string>Repeater Template</string>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="repeaterTemplateLineEdit"/>
+     </item>
+     <item>
+      <widget class="QPushButton" name="repeaterTemplateBrowseButton">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="text">
+        <string>Browse ...</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/qsstv/rig/rigcontrolform.cpp b/qsstv/config/rigconfig.cpp
similarity index 84%
copy from qsstv/rig/rigcontrolform.cpp
copy to qsstv/config/rigconfig.cpp
index ebe9989..f39ab98 100644
--- a/qsstv/rig/rigcontrolform.cpp
+++ b/qsstv/config/rigconfig.cpp
@@ -1,16 +1,14 @@
-#include "rigcontrolform.h"
-#include "ui_rigcontrolform.h"
-#include "qsstvglobal.h"
+#include "rigconfig.h"
+#include "ui_rigconfig.h"
+#include "appglobal.h"
 #include "configparams.h"
 #include "utils/supportfunctions.h"
-#include "rigparams.h"
 #include "rigcontrol.h"
 #include <QSettings>
 #include <QMessageBox>
 
-rigControlForm::rigControlForm(QWidget *parent) :
-  QWidget(parent),
-  ui(new Ui::rigControlForm)
+
+rigConfig::rigConfig(QWidget *parent) : baseConfig(parent),  ui(new Ui::rigConfig)
 {
   ui->setupUi(this);
   connect(ui->enableCATCheckBox,SIGNAL(clicked()),SLOT(slotEnableCAT()));
@@ -22,20 +20,21 @@ rigControlForm::rigControlForm(QWidget *parent) :
   connect(ui->nRTSCheckBox,SIGNAL(clicked()),SLOT(slotCheckPTT2()));
   connect(ui->nDTRCheckBox,SIGNAL(clicked()),SLOT(slotCheckPTT3()));
   rigController=NULL;
+  cp=NULL;
 }
 
 
-rigControlForm::~rigControlForm()
+rigConfig::~rigConfig()
 {
   delete ui;
 }
 
-void rigControlForm::attachRigController(rigControl *rigCtrl)
+void rigConfig::attachRigController(rigControl *rigCtrl)
 {
   rigController=rigCtrl;
 }
 
-void rigControlForm::readSettings()
+void rigConfig::readSettings()
 {
   cp=rigController->params();
   QSettings qSettings;
@@ -55,21 +54,18 @@ void rigControlForm::readSettings()
   cp->activeDTR=qSettings.value("activeDTR",0).toBool();
   cp->nactiveRTS=qSettings.value("nactiveRTS",1).toBool();
   cp->nactiveDTR=qSettings.value("nactiveDTR",0).toBool();
-
   cp->enableXMLRPC=qSettings.value("enableXMLRPC",0).toBool();
   cp->XMLRPCPort=qSettings.value("XMLRPCPort","7362").toInt();
-
   cp->txOnDelay=qSettings.value("txOnDelay",0.0).toDouble();
-
   cp->pttType=(ptt_type_t)qSettings.value("pttType",(int)RIG_PTT_RIG).toInt();
   qSettings.endGroup();
   setParams();
 }
 
-void rigControlForm::writeSettings()
+void rigConfig::writeSettings()
 {
-  getParams();
   QSettings qSettings;
+  getParams();
   qSettings.beginGroup(cp->configLabel);
   qSettings.setValue("serialPort",cp->serialPort);
   qSettings.setValue("radioModel",cp->radioModel);
@@ -87,14 +83,62 @@ void rigControlForm::writeSettings()
   qSettings.setValue("nactiveRTS",cp->nactiveRTS);
   qSettings.setValue("nactiveDTR",cp->nactiveDTR);
   qSettings.setValue("pttType",(int) cp->pttType);
-
   qSettings.setValue("enableXMLRPC",cp->enableXMLRPC);
   qSettings.setValue("XMLRPCPort",cp->XMLRPCPort);
   qSettings.setValue("txOnDelay",cp->txOnDelay);
   qSettings.endGroup();
 }
 
-void rigControlForm::setParams()
+void rigConfig::getParams()
+{
+  scatParams *cpCopy=new scatParams;
+  *cpCopy=*cp;
+  getValue(cp->serialPort,ui->serialPortLineEdit);
+  if(ui->radioModelComboBox->count()!=0) getValue(cp->radioModel,ui->radioModelComboBox);
+  getValue(cp->civAddress,ui->civAddressLineEdit);
+  getValue(cp->baudrate,ui->baudrateComboBox);
+  getValue(cp->parity,ui->parityComboBox);
+  getValue(cp->stopbits,ui->stopbitsComboBox);
+  getValue(cp->databits,ui->databitsComboBox);
+  getValue(cp->handshake,ui->handshakeComboBox);
+  getValue(cp->enableCAT,ui->enableCATCheckBox);
+  getValue(cp->enableSerialPTT,ui->enablePTTCheckBox);
+  getValue(cp->pttSerialPort,ui->pttSerialPortLineEdit);
+  getValue(cp->activeRTS,ui->RTSCheckBox);
+  getValue(cp->activeDTR,ui->DTRCheckBox);
+  getValue(cp->nactiveRTS,ui->nRTSCheckBox);
+  getValue(cp->nactiveDTR,ui->nDTRCheckBox);
+  if(ui->catRadioButton->isChecked()) cp->pttType=RIG_PTT_RIG;
+  if(ui->rtsRadioButton->isChecked()) cp->pttType=RIG_PTT_SERIAL_RTS;
+  if(ui->dtrRadioButton->isChecked()) cp->pttType=RIG_PTT_SERIAL_DTR;
+  getValue(cp->txOnDelay,ui->txOnDelayDoubleSpinBox);
+  getValue(cp->enableXMLRPC,ui->enableXMLRPCCheckBox);
+  getValue(cp->XMLRPCPort,ui->XMLRPCPortLineEdit);
+  changed=false;
+  if( cpCopy->serialPort!=cp->serialPort
+      || cpCopy->radioModel!=cp->radioModel
+      || cpCopy->civAddress!=cp->civAddress
+      || cpCopy->baudrate!=cp->baudrate
+      || cpCopy->stopbits!=cp->stopbits
+      || cpCopy->databits!=cp->databits
+      || cpCopy->handshake!=cp->handshake
+      || cpCopy->enableCAT!=cp->enableCAT
+      || cpCopy->enableSerialPTT!=cp->enableSerialPTT
+      || cpCopy->pttSerialPort!=cp->pttSerialPort
+      || cpCopy->activeRTS!=cp->activeRTS
+      || cpCopy->activeDTR!=cp->activeDTR
+      || cpCopy->nactiveRTS!=cp->nactiveRTS
+      || cpCopy->nactiveDTR!=cp->nactiveDTR
+      || cpCopy->pttType!=cp->pttType
+      || cpCopy->enableXMLRPC!=cp->enableXMLRPC
+      || cpCopy->XMLRPCPort!=cp->XMLRPCPort
+      )
+    changed=true;
+  delete cpCopy;
+}
+
+
+void rigConfig::setParams()
 {
   if(rigController->getRadioList(ui->radioModelComboBox)) setValue(cp->radioModel,ui->radioModelComboBox);
   setValue(cp->serialPort,ui->serialPortLineEdit);
@@ -140,36 +184,11 @@ void rigControlForm::setParams()
   setValue(cp->txOnDelay,ui->txOnDelayDoubleSpinBox);
   setValue(cp->enableXMLRPC,ui->enableXMLRPCCheckBox);
   setValue(cp->XMLRPCPort,ui->XMLRPCPortLineEdit);
-
-
 }
 
-void rigControlForm::getParams()
-{
-  getValue(cp->serialPort,ui->serialPortLineEdit);
-  if(ui->radioModelComboBox->count()!=0) getValue(cp->radioModel,ui->radioModelComboBox);
-  getValue(cp->civAddress,ui->civAddressLineEdit);
-  getValue(cp->baudrate,ui->baudrateComboBox);
-  getValue(cp->parity,ui->parityComboBox);
-  getValue(cp->stopbits,ui->stopbitsComboBox);
-  getValue(cp->databits,ui->databitsComboBox);
-  getValue(cp->handshake,ui->handshakeComboBox);
-  getValue(cp->enableCAT,ui->enableCATCheckBox);
-  getValue(cp->enableSerialPTT,ui->enablePTTCheckBox);
-  getValue(cp->pttSerialPort,ui->pttSerialPortLineEdit);
-  getValue(cp->activeRTS,ui->RTSCheckBox);
-  getValue(cp->activeDTR,ui->DTRCheckBox);
-  getValue(cp->nactiveRTS,ui->nRTSCheckBox);
-  getValue(cp->nactiveDTR,ui->nDTRCheckBox);
-  if(ui->catRadioButton->isChecked()) cp->pttType=RIG_PTT_RIG;
-  if(ui->rtsRadioButton->isChecked()) cp->pttType=RIG_PTT_SERIAL_RTS;
-  if(ui->dtrRadioButton->isChecked()) cp->pttType=RIG_PTT_SERIAL_DTR;
-  getValue(cp->txOnDelay,ui->txOnDelayDoubleSpinBox);
-  getValue(cp->enableXMLRPC,ui->enableXMLRPCCheckBox);
-  getValue(cp->XMLRPCPort,ui->XMLRPCPortLineEdit);
-}
 
-void rigControlForm::slotEnableCAT()
+
+void rigConfig::slotEnableCAT()
 {
   if(ui->enableCATCheckBox->isChecked() && ui->enablePTTCheckBox->isChecked())
     {
@@ -195,7 +214,7 @@ void rigControlForm::slotEnableCAT()
 
 
 
-void rigControlForm::slotEnablePTT()
+void rigConfig::slotEnablePTT()
 {
   if(ui->enableCATCheckBox->isChecked() && ui->enablePTTCheckBox->isChecked())
     {
@@ -215,13 +234,13 @@ void rigControlForm::slotEnablePTT()
   getParams();
 }
 
-void rigControlForm::slotEnableXMLRPC()
+void rigConfig::slotEnableXMLRPC()
 {
   ui->enableCATCheckBox->setChecked(false);
   ui->enablePTTCheckBox->setChecked(false);
 }
 
-void rigControlForm::slotRestart()
+void rigConfig::slotRestart()
 {
   getParams();
   if(ui->enableCATCheckBox->isChecked())
@@ -238,23 +257,23 @@ void rigControlForm::slotRestart()
 }
 
 
-void rigControlForm::slotCheckPTT0()
+void rigConfig::slotCheckPTT0()
 {
   checkPTT(0,ui->RTSCheckBox->isChecked());
 }
-void rigControlForm::slotCheckPTT1()
+void rigConfig::slotCheckPTT1()
 {checkPTT(1,ui->DTRCheckBox->isChecked());
 }
-void rigControlForm::slotCheckPTT2()
+void rigConfig::slotCheckPTT2()
 {
   checkPTT(2,ui->nRTSCheckBox->isChecked());
 }
-void rigControlForm::slotCheckPTT3()
+void rigConfig::slotCheckPTT3()
 {
   checkPTT(3,ui->nDTRCheckBox->isChecked());
 }
 
-void rigControlForm::checkPTT(int p,bool b)
+void rigConfig::checkPTT(int p,bool b)
 {
   if(!b) return;
   switch (p)
@@ -271,7 +290,6 @@ void rigControlForm::checkPTT(int p,bool b)
     case 3:
       setValue(false,ui->DTRCheckBox);
     break;
-
     }
 }
 
diff --git a/qsstv/config/rigconfig.h b/qsstv/config/rigconfig.h
new file mode 100644
index 0000000..4f40789
--- /dev/null
+++ b/qsstv/config/rigconfig.h
@@ -0,0 +1,45 @@
+#ifndef RIGCONFIG_H
+#define RIGCONFIG_H
+
+#include "baseconfig.h"
+
+class rigControl;
+struct scatParams;
+
+
+namespace Ui {
+class rigConfig;
+}
+
+class rigConfig : public baseConfig
+{
+  Q_OBJECT
+  
+public:
+  explicit rigConfig(QWidget *parent = 0);
+  ~rigConfig();
+  void attachRigController(rigControl *rigCtrl);
+  void readSettings();
+  void writeSettings();
+  void getParams();
+  void setParams();
+
+public slots:
+  void slotEnableCAT();
+  void slotEnablePTT();
+  void slotEnableXMLRPC();
+  void slotRestart();
+  void slotCheckPTT0();
+  void slotCheckPTT1();
+  void slotCheckPTT2();
+  void slotCheckPTT3();
+  
+private:
+
+  Ui::rigConfig *ui;
+  scatParams *cp;
+  rigControl *rigController;
+  void checkPTT(int p,bool b);
+};
+
+#endif // RIGCONFIG_H
diff --git a/qsstv/config/rigconfig.ui b/qsstv/config/rigconfig.ui
new file mode 100644
index 0000000..00e7d5c
--- /dev/null
+++ b/qsstv/config/rigconfig.ui
@@ -0,0 +1,2143 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>rigConfig</class>
+ <widget class="QWidget" name="rigConfig">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>658</width>
+    <height>399</height>
+   </rect>
+  </property>
+  <property name="font">
+   <font>
+    <pointsize>9</pointsize>
+   </font>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout_5">
+   <property name="spacing">
+    <number>2</number>
+   </property>
+   <property name="margin">
+    <number>1</number>
+   </property>
+   <item>
+    <widget class="QGroupBox" name="groupBox_2">
+     <property name="palette">
+      <palette>
+       <active>
+        <colorrole role="WindowText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>0</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Button">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>208</red>
+           <green>208</green>
+           <blue>208</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Light">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>255</red>
+           <green>255</green>
+           <blue>255</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Midlight">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>231</red>
+           <green>231</green>
+           <blue>231</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Dark">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>104</red>
+           <green>104</green>
+           <blue>104</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Mid">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>139</red>
+           <green>139</green>
+           <blue>139</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Text">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>0</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="BrightText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>255</red>
+           <green>255</green>
+           <blue>255</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="ButtonText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>0</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Base">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>255</red>
+           <green>255</green>
+           <blue>255</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Window">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>208</red>
+           <green>208</green>
+           <blue>208</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Shadow">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>0</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="AlternateBase">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>231</red>
+           <green>231</green>
+           <blue>231</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="ToolTipBase">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>255</red>
+           <green>255</green>
+           <blue>220</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="ToolTipText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>0</blue>
+          </color>
+         </brush>
+        </colorrole>
+       </active>
+       <inactive>
+        <colorrole role="WindowText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>0</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Button">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>208</red>
+           <green>208</green>
+           <blue>208</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Light">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>255</red>
+           <green>255</green>
+           <blue>255</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Midlight">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>231</red>
+           <green>231</green>
+           <blue>231</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Dark">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>104</red>
+           <green>104</green>
+           <blue>104</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Mid">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>139</red>
+           <green>139</green>
+           <blue>139</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Text">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>0</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="BrightText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>255</red>
+           <green>255</green>
+           <blue>255</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="ButtonText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>0</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Base">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>255</red>
+           <green>255</green>
+           <blue>255</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Window">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>208</red>
+           <green>208</green>
+           <blue>208</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Shadow">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>0</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="AlternateBase">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>231</red>
+           <green>231</green>
+           <blue>231</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="ToolTipBase">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>255</red>
+           <green>255</green>
+           <blue>220</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="ToolTipText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>0</blue>
+          </color>
+         </brush>
+        </colorrole>
+       </inactive>
+       <disabled>
+        <colorrole role="WindowText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>104</red>
+           <green>104</green>
+           <blue>104</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Button">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>208</red>
+           <green>208</green>
+           <blue>208</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Light">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>255</red>
+           <green>255</green>
+           <blue>255</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Midlight">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>231</red>
+           <green>231</green>
+           <blue>231</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Dark">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>104</red>
+           <green>104</green>
+           <blue>104</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Mid">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>139</red>
+           <green>139</green>
+           <blue>139</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Text">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>104</red>
+           <green>104</green>
+           <blue>104</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="BrightText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>255</red>
+           <green>255</green>
+           <blue>255</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="ButtonText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>104</red>
+           <green>104</green>
+           <blue>104</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Base">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>208</red>
+           <green>208</green>
+           <blue>208</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Window">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>208</red>
+           <green>208</green>
+           <blue>208</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Shadow">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>0</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="AlternateBase">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>208</red>
+           <green>208</green>
+           <blue>208</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="ToolTipBase">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>255</red>
+           <green>255</green>
+           <blue>220</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="ToolTipText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>0</blue>
+          </color>
+         </brush>
+        </colorrole>
+       </disabled>
+      </palette>
+     </property>
+     <property name="autoFillBackground">
+      <bool>true</bool>
+     </property>
+     <property name="title">
+      <string>Special Serial Port</string>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout_2">
+      <property name="spacing">
+       <number>2</number>
+      </property>
+      <property name="margin">
+       <number>1</number>
+      </property>
+      <item>
+       <layout class="QHBoxLayout" name="horizontalLayout_10">
+        <item>
+         <widget class="QCheckBox" name="enablePTTCheckBox">
+          <property name="text">
+           <string>Enable PTT serial Interface</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <spacer name="horizontalSpacer_8">
+          <property name="orientation">
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>40</width>
+            <height>20</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+        <item>
+         <widget class="QLabel" name="serialInterfaceTextLabel_4">
+          <property name="minimumSize">
+           <size>
+            <width>60</width>
+            <height>0</height>
+           </size>
+          </property>
+          <property name="text">
+           <string>PTT Serial Port</string>
+          </property>
+          <property name="alignment">
+           <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+          </property>
+          <property name="wordWrap">
+           <bool>false</bool>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QLineEdit" name="pttSerialPortLineEdit">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <spacer name="horizontalSpacer_15">
+          <property name="orientation">
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>40</width>
+            <height>20</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+       </layout>
+      </item>
+      <item>
+       <layout class="QHBoxLayout" name="horizontalLayout_8"/>
+      </item>
+      <item>
+       <layout class="QHBoxLayout" name="horizontalLayout_7">
+        <item>
+         <widget class="QCheckBox" name="RTSCheckBox">
+          <property name="text">
+           <string>+RTS</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QCheckBox" name="DTRCheckBox">
+          <property name="text">
+           <string>+DTR</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QCheckBox" name="nRTSCheckBox">
+          <property name="text">
+           <string>-RTS</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QCheckBox" name="nDTRCheckBox">
+          <property name="text">
+           <string>-DTR</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <spacer name="horizontalSpacer_11">
+          <property name="orientation">
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>40</width>
+            <height>20</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+       </layout>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QGroupBox" name="groupBox">
+     <property name="palette">
+      <palette>
+       <active>
+        <colorrole role="WindowText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>0</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Button">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>208</red>
+           <green>208</green>
+           <blue>208</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Light">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>255</red>
+           <green>255</green>
+           <blue>255</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Midlight">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>231</red>
+           <green>231</green>
+           <blue>231</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Dark">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>104</red>
+           <green>104</green>
+           <blue>104</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Mid">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>139</red>
+           <green>139</green>
+           <blue>139</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Text">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>0</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="BrightText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>255</red>
+           <green>255</green>
+           <blue>255</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="ButtonText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>0</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Base">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>255</red>
+           <green>255</green>
+           <blue>255</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Window">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>208</red>
+           <green>208</green>
+           <blue>208</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Shadow">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>0</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="AlternateBase">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>231</red>
+           <green>231</green>
+           <blue>231</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="ToolTipBase">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>255</red>
+           <green>255</green>
+           <blue>220</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="ToolTipText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>0</blue>
+          </color>
+         </brush>
+        </colorrole>
+       </active>
+       <inactive>
+        <colorrole role="WindowText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>0</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Button">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>208</red>
+           <green>208</green>
+           <blue>208</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Light">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>255</red>
+           <green>255</green>
+           <blue>255</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Midlight">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>231</red>
+           <green>231</green>
+           <blue>231</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Dark">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>104</red>
+           <green>104</green>
+           <blue>104</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Mid">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>139</red>
+           <green>139</green>
+           <blue>139</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Text">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>0</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="BrightText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>255</red>
+           <green>255</green>
+           <blue>255</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="ButtonText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>0</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Base">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>255</red>
+           <green>255</green>
+           <blue>255</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Window">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>208</red>
+           <green>208</green>
+           <blue>208</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Shadow">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>0</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="AlternateBase">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>231</red>
+           <green>231</green>
+           <blue>231</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="ToolTipBase">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>255</red>
+           <green>255</green>
+           <blue>220</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="ToolTipText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>0</blue>
+          </color>
+         </brush>
+        </colorrole>
+       </inactive>
+       <disabled>
+        <colorrole role="WindowText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>104</red>
+           <green>104</green>
+           <blue>104</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Button">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>208</red>
+           <green>208</green>
+           <blue>208</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Light">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>255</red>
+           <green>255</green>
+           <blue>255</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Midlight">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>231</red>
+           <green>231</green>
+           <blue>231</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Dark">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>104</red>
+           <green>104</green>
+           <blue>104</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Mid">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>139</red>
+           <green>139</green>
+           <blue>139</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Text">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>104</red>
+           <green>104</green>
+           <blue>104</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="BrightText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>255</red>
+           <green>255</green>
+           <blue>255</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="ButtonText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>104</red>
+           <green>104</green>
+           <blue>104</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Base">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>208</red>
+           <green>208</green>
+           <blue>208</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Window">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>208</red>
+           <green>208</green>
+           <blue>208</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Shadow">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>0</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="AlternateBase">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>208</red>
+           <green>208</green>
+           <blue>208</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="ToolTipBase">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>255</red>
+           <green>255</green>
+           <blue>220</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="ToolTipText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>0</blue>
+          </color>
+         </brush>
+        </colorrole>
+       </disabled>
+      </palette>
+     </property>
+     <property name="autoFillBackground">
+      <bool>true</bool>
+     </property>
+     <property name="title">
+      <string>Hamlib Control</string>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout_3">
+      <property name="spacing">
+       <number>2</number>
+      </property>
+      <property name="margin">
+       <number>1</number>
+      </property>
+      <item>
+       <layout class="QVBoxLayout" name="verticalLayout">
+        <property name="spacing">
+         <number>2</number>
+        </property>
+        <item>
+         <layout class="QHBoxLayout" name="horizontalLayout_9">
+          <item>
+           <widget class="QCheckBox" name="enableCATCheckBox">
+            <property name="text">
+             <string>Enable Hamlib Cat Interface</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <spacer name="horizontalSpacer_2">
+            <property name="orientation">
+             <enum>Qt::Horizontal</enum>
+            </property>
+            <property name="sizeHint" stdset="0">
+             <size>
+              <width>40</width>
+              <height>20</height>
+             </size>
+            </property>
+           </spacer>
+          </item>
+         </layout>
+        </item>
+        <item>
+         <layout class="QHBoxLayout" name="horizontalLayout">
+          <item>
+           <layout class="QGridLayout" name="gridLayout_2">
+            <property name="spacing">
+             <number>2</number>
+            </property>
+            <item row="0" column="0">
+             <widget class="QLabel" name="serialInterfaceTextLabel_2">
+              <property name="minimumSize">
+               <size>
+                <width>60</width>
+                <height>0</height>
+               </size>
+              </property>
+              <property name="text">
+               <string>Radio Model</string>
+              </property>
+              <property name="alignment">
+               <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+              </property>
+              <property name="wordWrap">
+               <bool>false</bool>
+              </property>
+             </widget>
+            </item>
+            <item row="0" column="1">
+             <widget class="QComboBox" name="radioModelComboBox">
+              <property name="font">
+               <font>
+                <family>Ubuntu Mono</family>
+                <weight>75</weight>
+                <italic>false</italic>
+                <bold>true</bold>
+                <kerning>false</kerning>
+               </font>
+              </property>
+             </widget>
+            </item>
+            <item row="1" column="0">
+             <widget class="QLabel" name="serialInterfaceTextLabel_3">
+              <property name="minimumSize">
+               <size>
+                <width>60</width>
+                <height>0</height>
+               </size>
+              </property>
+              <property name="text">
+               <string>CIV Address</string>
+              </property>
+              <property name="alignment">
+               <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+              </property>
+              <property name="wordWrap">
+               <bool>false</bool>
+              </property>
+             </widget>
+            </item>
+            <item row="1" column="1">
+             <layout class="QHBoxLayout" name="horizontalLayout_2">
+              <item>
+               <widget class="QLineEdit" name="civAddressLineEdit">
+                <property name="maximumSize">
+                 <size>
+                  <width>50</width>
+                  <height>16777215</height>
+                 </size>
+                </property>
+               </widget>
+              </item>
+              <item>
+               <spacer name="horizontalSpacer_4">
+                <property name="orientation">
+                 <enum>Qt::Horizontal</enum>
+                </property>
+                <property name="sizeHint" stdset="0">
+                 <size>
+                  <width>40</width>
+                  <height>20</height>
+                 </size>
+                </property>
+               </spacer>
+              </item>
+             </layout>
+            </item>
+            <item row="2" column="0">
+             <widget class="QLabel" name="serialInterfaceTextLabel">
+              <property name="minimumSize">
+               <size>
+                <width>108</width>
+                <height>0</height>
+               </size>
+              </property>
+              <property name="text">
+               <string>Serial Port/Host</string>
+              </property>
+              <property name="alignment">
+               <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+              </property>
+              <property name="wordWrap">
+               <bool>false</bool>
+              </property>
+             </widget>
+            </item>
+            <item row="2" column="1">
+             <widget class="QLineEdit" name="serialPortLineEdit">
+              <property name="sizePolicy">
+               <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+                <horstretch>0</horstretch>
+                <verstretch>0</verstretch>
+               </sizepolicy>
+              </property>
+             </widget>
+            </item>
+            <item row="3" column="0">
+             <widget class="QLabel" name="serialInterfaceTextLabel_6">
+              <property name="minimumSize">
+               <size>
+                <width>60</width>
+                <height>0</height>
+               </size>
+              </property>
+              <property name="text">
+               <string>Handshake</string>
+              </property>
+              <property name="alignment">
+               <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+              </property>
+              <property name="wordWrap">
+               <bool>false</bool>
+              </property>
+             </widget>
+            </item>
+            <item row="3" column="1">
+             <layout class="QHBoxLayout" name="horizontalLayout_3" stretch="0,1">
+              <property name="spacing">
+               <number>2</number>
+              </property>
+              <item>
+               <widget class="QComboBox" name="handshakeComboBox">
+                <property name="sizePolicy">
+                 <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+                  <horstretch>0</horstretch>
+                  <verstretch>0</verstretch>
+                 </sizepolicy>
+                </property>
+                <item>
+                 <property name="text">
+                  <string>None</string>
+                 </property>
+                </item>
+                <item>
+                 <property name="text">
+                  <string>Hardware</string>
+                 </property>
+                </item>
+                <item>
+                 <property name="text">
+                  <string>XOn/XOff</string>
+                 </property>
+                </item>
+               </widget>
+              </item>
+              <item>
+               <spacer name="horizontalSpacer_3">
+                <property name="orientation">
+                 <enum>Qt::Horizontal</enum>
+                </property>
+                <property name="sizeHint" stdset="0">
+                 <size>
+                  <width>40</width>
+                  <height>20</height>
+                 </size>
+                </property>
+               </spacer>
+              </item>
+             </layout>
+            </item>
+           </layout>
+          </item>
+          <item>
+           <layout class="QGridLayout" name="gridLayout">
+            <item row="0" column="0">
+             <widget class="QLabel" name="serialInterfaceTextLabel_8">
+              <property name="minimumSize">
+               <size>
+                <width>60</width>
+                <height>0</height>
+               </size>
+              </property>
+              <property name="text">
+               <string>Parity</string>
+              </property>
+              <property name="alignment">
+               <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+              </property>
+              <property name="wordWrap">
+               <bool>false</bool>
+              </property>
+             </widget>
+            </item>
+            <item row="0" column="1">
+             <widget class="QComboBox" name="parityComboBox">
+              <property name="maximumSize">
+               <size>
+                <width>70</width>
+                <height>16777215</height>
+               </size>
+              </property>
+              <item>
+               <property name="text">
+                <string>None</string>
+               </property>
+              </item>
+              <item>
+               <property name="text">
+                <string>Odd</string>
+               </property>
+              </item>
+              <item>
+               <property name="text">
+                <string>Even</string>
+               </property>
+              </item>
+             </widget>
+            </item>
+            <item row="0" column="2">
+             <spacer name="horizontalSpacer_7">
+              <property name="orientation">
+               <enum>Qt::Horizontal</enum>
+              </property>
+              <property name="sizeHint" stdset="0">
+               <size>
+                <width>40</width>
+                <height>20</height>
+               </size>
+              </property>
+             </spacer>
+            </item>
+            <item row="1" column="0">
+             <widget class="QLabel" name="serialInterfaceTextLabel_9">
+              <property name="minimumSize">
+               <size>
+                <width>60</width>
+                <height>0</height>
+               </size>
+              </property>
+              <property name="text">
+               <string>Databits</string>
+              </property>
+              <property name="alignment">
+               <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+              </property>
+              <property name="wordWrap">
+               <bool>false</bool>
+              </property>
+             </widget>
+            </item>
+            <item row="1" column="1" colspan="2">
+             <layout class="QHBoxLayout" name="horizontalLayout_4">
+              <item>
+               <widget class="QComboBox" name="databitsComboBox">
+                <item>
+                 <property name="text">
+                  <string>7</string>
+                 </property>
+                </item>
+                <item>
+                 <property name="text">
+                  <string>8</string>
+                 </property>
+                </item>
+               </widget>
+              </item>
+              <item>
+               <spacer name="horizontalSpacer">
+                <property name="orientation">
+                 <enum>Qt::Horizontal</enum>
+                </property>
+                <property name="sizeHint" stdset="0">
+                 <size>
+                  <width>40</width>
+                  <height>20</height>
+                 </size>
+                </property>
+               </spacer>
+              </item>
+             </layout>
+            </item>
+            <item row="2" column="0">
+             <widget class="QLabel" name="serialPortTextLabel">
+              <property name="minimumSize">
+               <size>
+                <width>60</width>
+                <height>0</height>
+               </size>
+              </property>
+              <property name="text">
+               <string>Baudrate</string>
+              </property>
+              <property name="alignment">
+               <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+              </property>
+              <property name="wordWrap">
+               <bool>false</bool>
+              </property>
+             </widget>
+            </item>
+            <item row="2" column="1">
+             <widget class="QComboBox" name="baudrateComboBox">
+              <property name="maximumSize">
+               <size>
+                <width>70</width>
+                <height>16777215</height>
+               </size>
+              </property>
+              <property name="currentIndex">
+               <number>5</number>
+              </property>
+              <item>
+               <property name="text">
+                <string>300</string>
+               </property>
+              </item>
+              <item>
+               <property name="text">
+                <string>600</string>
+               </property>
+              </item>
+              <item>
+               <property name="text">
+                <string>1200</string>
+               </property>
+              </item>
+              <item>
+               <property name="text">
+                <string>2400</string>
+               </property>
+              </item>
+              <item>
+               <property name="text">
+                <string>4800</string>
+               </property>
+              </item>
+              <item>
+               <property name="text">
+                <string>9600</string>
+               </property>
+              </item>
+              <item>
+               <property name="text">
+                <string>19200</string>
+               </property>
+              </item>
+              <item>
+               <property name="text">
+                <string>38400</string>
+               </property>
+              </item>
+              <item>
+               <property name="text">
+                <string>57600</string>
+               </property>
+              </item>
+              <item>
+               <property name="text">
+                <string>115200</string>
+               </property>
+              </item>
+              <item>
+               <property name="text">
+                <string>230400</string>
+               </property>
+              </item>
+              <item>
+               <property name="text">
+                <string>460800</string>
+               </property>
+              </item>
+             </widget>
+            </item>
+            <item row="3" column="0">
+             <widget class="QLabel" name="stopbitsTextLabel">
+              <property name="minimumSize">
+               <size>
+                <width>60</width>
+                <height>0</height>
+               </size>
+              </property>
+              <property name="text">
+               <string>StopBits</string>
+              </property>
+              <property name="alignment">
+               <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+              </property>
+              <property name="wordWrap">
+               <bool>false</bool>
+              </property>
+             </widget>
+            </item>
+            <item row="3" column="1" colspan="2">
+             <layout class="QHBoxLayout" name="horizontalLayout_5">
+              <item>
+               <widget class="QComboBox" name="stopbitsComboBox">
+                <item>
+                 <property name="text">
+                  <string>1</string>
+                 </property>
+                </item>
+                <item>
+                 <property name="text">
+                  <string>2</string>
+                 </property>
+                </item>
+               </widget>
+              </item>
+              <item>
+               <spacer name="horizontalSpacer_6">
+                <property name="orientation">
+                 <enum>Qt::Horizontal</enum>
+                </property>
+                <property name="sizeHint" stdset="0">
+                 <size>
+                  <width>40</width>
+                  <height>20</height>
+                 </size>
+                </property>
+               </spacer>
+              </item>
+             </layout>
+            </item>
+           </layout>
+          </item>
+         </layout>
+        </item>
+        <item>
+         <layout class="QHBoxLayout" name="horizontalLayout_11">
+          <item>
+           <widget class="QLabel" name="label">
+            <property name="text">
+             <string>PTT Control via:</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QRadioButton" name="catRadioButton">
+            <property name="text">
+             <string>CAT Command</string>
+            </property>
+            <property name="checked">
+             <bool>true</bool>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QRadioButton" name="rtsRadioButton">
+            <property name="text">
+             <string>RTS</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QRadioButton" name="dtrRadioButton">
+            <property name="text">
+             <string>DTR</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <spacer name="horizontalSpacer_12">
+            <property name="orientation">
+             <enum>Qt::Horizontal</enum>
+            </property>
+            <property name="sizeHint" stdset="0">
+             <size>
+              <width>40</width>
+              <height>20</height>
+             </size>
+            </property>
+           </spacer>
+          </item>
+         </layout>
+        </item>
+       </layout>
+      </item>
+      <item>
+       <layout class="QHBoxLayout" name="horizontalLayout_6">
+        <item>
+         <spacer name="horizontalSpacer_9">
+          <property name="orientation">
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>40</width>
+            <height>20</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+        <item>
+         <widget class="QPushButton" name="restartPushButton">
+          <property name="text">
+           <string>Restart CAT Interface</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <spacer name="horizontalSpacer_10">
+          <property name="orientation">
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>40</width>
+            <height>20</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+       </layout>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QGroupBox" name="groupBox_3">
+     <property name="palette">
+      <palette>
+       <active>
+        <colorrole role="WindowText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>0</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Button">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>208</red>
+           <green>208</green>
+           <blue>208</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Light">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>255</red>
+           <green>255</green>
+           <blue>255</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Midlight">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>231</red>
+           <green>231</green>
+           <blue>231</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Dark">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>104</red>
+           <green>104</green>
+           <blue>104</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Mid">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>139</red>
+           <green>139</green>
+           <blue>139</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Text">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>0</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="BrightText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>255</red>
+           <green>255</green>
+           <blue>255</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="ButtonText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>0</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Base">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>255</red>
+           <green>255</green>
+           <blue>255</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Window">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>208</red>
+           <green>208</green>
+           <blue>208</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Shadow">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>0</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="AlternateBase">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>231</red>
+           <green>231</green>
+           <blue>231</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="ToolTipBase">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>255</red>
+           <green>255</green>
+           <blue>220</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="ToolTipText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>0</blue>
+          </color>
+         </brush>
+        </colorrole>
+       </active>
+       <inactive>
+        <colorrole role="WindowText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>0</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Button">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>208</red>
+           <green>208</green>
+           <blue>208</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Light">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>255</red>
+           <green>255</green>
+           <blue>255</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Midlight">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>231</red>
+           <green>231</green>
+           <blue>231</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Dark">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>104</red>
+           <green>104</green>
+           <blue>104</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Mid">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>139</red>
+           <green>139</green>
+           <blue>139</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Text">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>0</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="BrightText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>255</red>
+           <green>255</green>
+           <blue>255</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="ButtonText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>0</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Base">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>255</red>
+           <green>255</green>
+           <blue>255</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Window">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>208</red>
+           <green>208</green>
+           <blue>208</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Shadow">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>0</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="AlternateBase">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>231</red>
+           <green>231</green>
+           <blue>231</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="ToolTipBase">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>255</red>
+           <green>255</green>
+           <blue>220</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="ToolTipText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>0</blue>
+          </color>
+         </brush>
+        </colorrole>
+       </inactive>
+       <disabled>
+        <colorrole role="WindowText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>104</red>
+           <green>104</green>
+           <blue>104</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Button">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>208</red>
+           <green>208</green>
+           <blue>208</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Light">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>255</red>
+           <green>255</green>
+           <blue>255</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Midlight">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>231</red>
+           <green>231</green>
+           <blue>231</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Dark">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>104</red>
+           <green>104</green>
+           <blue>104</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Mid">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>139</red>
+           <green>139</green>
+           <blue>139</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Text">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>104</red>
+           <green>104</green>
+           <blue>104</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="BrightText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>255</red>
+           <green>255</green>
+           <blue>255</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="ButtonText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>104</red>
+           <green>104</green>
+           <blue>104</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Base">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>208</red>
+           <green>208</green>
+           <blue>208</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Window">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>208</red>
+           <green>208</green>
+           <blue>208</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Shadow">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>0</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="AlternateBase">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>208</red>
+           <green>208</green>
+           <blue>208</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="ToolTipBase">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>255</red>
+           <green>255</green>
+           <blue>220</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="ToolTipText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>0</blue>
+          </color>
+         </brush>
+        </colorrole>
+       </disabled>
+      </palette>
+     </property>
+     <property name="autoFillBackground">
+      <bool>true</bool>
+     </property>
+     <property name="title">
+      <string>XMLRPC Interface</string>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout_4">
+      <property name="spacing">
+       <number>2</number>
+      </property>
+      <property name="margin">
+       <number>1</number>
+      </property>
+      <item>
+       <layout class="QHBoxLayout" name="horizontalLayout_13">
+        <item>
+         <widget class="QCheckBox" name="enableXMLRPCCheckBox">
+          <property name="text">
+           <string>Enable XMLRPC Interface</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <spacer name="horizontalSpacer_14">
+          <property name="orientation">
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>40</width>
+            <height>20</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+        <item>
+         <widget class="QLabel" name="serialInterfaceTextLabel_5">
+          <property name="minimumSize">
+           <size>
+            <width>60</width>
+            <height>0</height>
+           </size>
+          </property>
+          <property name="text">
+           <string>Port</string>
+          </property>
+          <property name="alignment">
+           <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+          </property>
+          <property name="wordWrap">
+           <bool>false</bool>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QLineEdit" name="XMLRPCPortLineEdit">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <spacer name="horizontalSpacer_5">
+          <property name="orientation">
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>40</width>
+            <height>20</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+       </layout>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout_12">
+     <item>
+      <widget class="QLabel" name="serialPortTextLabel_2">
+       <property name="minimumSize">
+        <size>
+         <width>60</width>
+         <height>0</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>TX on Delay</string>
+       </property>
+       <property name="alignment">
+        <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QDoubleSpinBox" name="txOnDelayDoubleSpinBox">
+       <property name="decimals">
+        <number>1</number>
+       </property>
+       <property name="maximum">
+        <double>5.000000000000000</double>
+       </property>
+       <property name="singleStep">
+        <double>0.100000000000000</double>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLabel" name="serialPortTextLabel_3">
+       <property name="minimumSize">
+        <size>
+         <width>60</width>
+         <height>0</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>in seconds</string>
+       </property>
+       <property name="alignment">
+        <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer_13">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <spacer name="verticalSpacer">
+     <property name="orientation">
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>20</width>
+       <height>17</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/qsstv/config/soundconfig.cpp b/qsstv/config/soundconfig.cpp
new file mode 100644
index 0000000..a893877
--- /dev/null
+++ b/qsstv/config/soundconfig.cpp
@@ -0,0 +1,153 @@
+/**************************************************************************
+*   Copyright (C) 2000-2012 by Johan Maes                                 *
+*   on4qz at telenet.be                                                      *
+*   http://users.telenet.be/on4qz                                         *
+*                                                                         *
+*   This program is free software; you can redistribute it and/or modify  *
+*   it under the terms of the GNU General Public License as published by  *
+*   the Free Software Foundation; either version 2 of the License, or     *
+*   (at your option) any later version.                                   *
+*                                                                         *
+*   This program is distributed in the hope that it will be useful,       *
+*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+*   GNU General Public License for more details.                          *
+*                                                                         *
+*   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.,                                       *
+*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+***************************************************************************/
+#include "soundconfig.h"
+#include "ui_soundconfig.h"
+#include "configparams.h"
+#include "supportfunctions.h"
+#include "soundalsa.h"
+
+#include <QSettings>
+
+#include <math.h>
+
+int samplingrate;
+double rxClock;
+double txClock;
+bool pulseSelected;
+bool alsaSelected;
+bool pttToneRightChannel;
+QString inputAudioDevice;
+QString outputAudioDevice;
+soundBase::edataSrc soundRoutingInput;
+soundBase::edataDst soundRoutingOutput;
+
+quint32 recordingSize;
+
+
+
+soundConfig::soundConfig(QWidget *parent) :  baseConfig(parent), ui(new Ui::soundConfig)
+{
+  QStringList inputPCMList, outputPCMList;
+  ui->setupUi(this);
+  getCardList(inputPCMList, outputPCMList);
+  ui->inputPCMNameComboBox->addItems(inputPCMList);
+  ui->outputPCMNameComboBox->addItems(outputPCMList);
+}
+
+
+soundConfig::~soundConfig()
+{
+  delete ui;
+}
+
+void soundConfig::readSettings()
+{
+  QSettings qSettings;
+  qSettings.beginGroup("SOUND");
+  rxClock=qSettings.value("rxclock",BASESAMPLERATE).toDouble();
+  txClock=qSettings.value("txclock",BASESAMPLERATE).toDouble();
+  if(fabs(1-rxClock/BASESAMPLERATE)>0.002) rxClock=BASESAMPLERATE;
+  if(fabs(1-txClock/BASESAMPLERATE)>0.002) txClock=BASESAMPLERATE;
+  samplingrate=BASESAMPLERATE;
+  inputAudioDevice=qSettings.value("inputAudioDevice","default").toString();
+  outputAudioDevice=qSettings.value("outputAudioDevice","default").toString();
+  alsaSelected=qSettings.value("alsaSelected",false).toBool();
+  pulseSelected=qSettings.value("pulseSelected",false).toBool();
+  pttToneRightChannel=qSettings.value("pttToneRightChannel",false).toBool();
+  soundRoutingInput=  (soundBase::edataSrc)qSettings.value("soundRoutingInput",  0 ).toInt();
+  soundRoutingOutput= (soundBase::edataDst)qSettings.value("soundRoutingOutput", 0 ).toInt();
+  recordingSize= qSettings.value("recordingSize", 100 ).toInt();
+  qSettings.endGroup();
+  setParams();
+}
+
+void soundConfig::writeSettings()
+{
+  QSettings qSettings;
+  getParams();
+  qSettings.beginGroup("SOUND");
+  qSettings.setValue("rxclock",rxClock);
+  qSettings.setValue("txclock",txClock);
+  qSettings.setValue("inputAudioDevice",inputAudioDevice);
+  qSettings.setValue("outputAudioDevice",outputAudioDevice);
+  qSettings.setValue("alsaSelected",alsaSelected);
+  qSettings.setValue("pulseSelected",pulseSelected);
+  qSettings.setValue("pttToneRightChannel",pttToneRightChannel);
+  qSettings.setValue ("soundRoutingInput", soundRoutingInput );
+  qSettings.setValue ("soundRoutingOutput",soundRoutingOutput );
+  qSettings.setValue ("recordingSize",recordingSize );
+  qSettings.endGroup();
+}
+
+
+void soundConfig::setParams()
+{
+  setValue(rxClock,ui->inputClockLineEdit,9);
+  setValue(txClock,ui->outputClockLineEdit,9);
+  setValue(inputAudioDevice,ui->inputPCMNameComboBox);
+  setValue(outputAudioDevice,ui->outputPCMNameComboBox);
+  setValue(alsaSelected,ui->alsaRadioButton);
+  setValue(pulseSelected,ui->pulseRadioButton);
+  setValue(pttToneRightChannel,ui->pttToneCheckBox);
+  if(soundRoutingInput==soundBase::SNDINCARD) ui->inFromCard->setChecked(true);
+  else if (soundRoutingInput==soundBase::SNDINFROMFILE) ui->inFromFile->setChecked(true);
+  else ui->inRecordFromCard->setChecked(true);
+
+  if(soundRoutingOutput==soundBase::SNDOUTCARD) ui->outToCard->setChecked(true);
+  else ui->outRecord->setChecked(true);
+  setValue(recordingSize,ui->mbSpinBox);
+}
+
+void soundConfig::getParams()
+{
+  QString inputAudioDeviceCopy=inputAudioDevice;
+  QString  outputAudioDeviceCopy=outputAudioDevice;
+  bool alsaSelectedCopy=alsaSelected;
+
+
+  soundBase::edataSrc soundRoutingInputCopy=soundRoutingInput;
+  soundBase::edataDst soundRoutingOutputCopy=soundRoutingOutput;
+
+  getValue(rxClock,ui->inputClockLineEdit);
+  getValue(txClock,ui->inputClockLineEdit);
+  getValue(inputAudioDevice,ui->inputPCMNameComboBox);
+  getValue(outputAudioDevice,ui->outputPCMNameComboBox);
+  getValue(alsaSelected,ui->alsaRadioButton);
+  getValue(pulseSelected,ui->pulseRadioButton);
+  getValue(pttToneRightChannel,ui->pttToneCheckBox);
+
+  if (ui->inFromCard->isChecked()) soundRoutingInput=soundBase::SNDINCARD;
+  else if(ui->inFromFile->isChecked()) soundRoutingInput=soundBase::SNDINFROMFILE;
+  else soundRoutingInput=soundBase::SNDINCARDTOFILE;
+
+  if (ui->outToCard->isChecked()) soundRoutingOutput=soundBase::SNDOUTCARD;
+  else soundRoutingOutput=soundBase::SNDOUTTOFILE;
+  getValue(recordingSize,ui->mbSpinBox);
+  changed=false;
+  if(inputAudioDeviceCopy!=inputAudioDevice
+     || outputAudioDeviceCopy!=outputAudioDevice
+     || soundRoutingInputCopy!=soundRoutingInput
+     || soundRoutingOutputCopy!=soundRoutingOutput
+     || alsaSelectedCopy!=alsaSelected)
+  {
+    changed=true;
+  }
+}
diff --git a/qsstv/config/soundconfig.h b/qsstv/config/soundconfig.h
new file mode 100644
index 0000000..64366e9
--- /dev/null
+++ b/qsstv/config/soundconfig.h
@@ -0,0 +1,43 @@
+#ifndef soundConfig_H
+#define soundConfig_H
+
+#include "baseconfig.h"
+#include "soundbase.h"
+
+extern int samplingrate;
+extern double rxClock;
+extern double txClock;
+extern bool pulseSelected;
+extern bool alsaSelected;
+extern bool pttToneRightChannel;
+extern QString inputAudioDevice;
+extern QString outputAudioDevice;
+extern soundBase::edataSrc soundRoutingInput;
+extern soundBase::edataDst soundRoutingOutput;
+extern quint32 recordingSize;
+
+
+namespace Ui {
+  class soundConfig;
+  }
+
+class soundConfig : public baseConfig
+{
+  Q_OBJECT
+  
+public:
+  explicit soundConfig(QWidget *parent = 0);
+  ~soundConfig();
+  void readSettings();
+  void writeSettings();
+  void getParams();
+  void setParams();
+
+
+
+private:
+  Ui::soundConfig *ui;
+
+};
+
+#endif // soundConfig_H
diff --git a/qsstv/sound/soundcontrol.ui b/qsstv/config/soundconfig.ui
similarity index 66%
rename from qsstv/sound/soundcontrol.ui
rename to qsstv/config/soundconfig.ui
index ac3b712..078923e 100644
--- a/qsstv/sound/soundcontrol.ui
+++ b/qsstv/config/soundconfig.ui
@@ -1,72 +1,106 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <ui version="4.0">
- <class>soundControl</class>
- <widget class="QWidget" name="soundControl">
+ <class>soundConfig</class>
+ <widget class="QWidget" name="soundConfig">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>600</width>
-    <height>341</height>
+    <width>656</width>
+    <height>451</height>
    </rect>
   </property>
   <property name="windowTitle">
    <string>Form</string>
   </property>
-  <layout class="QVBoxLayout" name="verticalLayout_3">
+  <layout class="QVBoxLayout" name="verticalLayout_4">
+   <item>
+    <widget class="QGroupBox" name="groupBox_3">
+     <property name="title">
+      <string>Audio Interface</string>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout_3">
+      <item>
+       <layout class="QHBoxLayout" name="horizontalLayout_4">
+        <item>
+         <widget class="QRadioButton" name="alsaRadioButton">
+          <property name="text">
+           <string>ALSA</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <layout class="QGridLayout" name="gridLayout_2">
+          <item row="0" column="0">
+           <widget class="QLabel" name="inputAudioDeviceLabel">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+            <property name="minimumSize">
+             <size>
+              <width>0</width>
+              <height>25</height>
+             </size>
+            </property>
+            <property name="text">
+             <string>Input Audio Device</string>
+            </property>
+            <property name="wordWrap">
+             <bool>false</bool>
+            </property>
+           </widget>
+          </item>
+          <item row="0" column="1">
+           <widget class="QComboBox" name="inputPCMNameComboBox"/>
+          </item>
+          <item row="1" column="0">
+           <widget class="QLabel" name="outputAudioDeviceLabel">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+            <property name="minimumSize">
+             <size>
+              <width>0</width>
+              <height>25</height>
+             </size>
+            </property>
+            <property name="text">
+             <string>Output Audio Device</string>
+            </property>
+            <property name="wordWrap">
+             <bool>false</bool>
+            </property>
+           </widget>
+          </item>
+          <item row="1" column="1">
+           <widget class="QComboBox" name="outputPCMNameComboBox"/>
+          </item>
+         </layout>
+        </item>
+       </layout>
+      </item>
+      <item>
+       <widget class="QRadioButton" name="pulseRadioButton">
+        <property name="text">
+         <string>PulseAudio</string>
+        </property>
+        <property name="checked">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
    <item>
     <layout class="QGridLayout" name="gridLayout">
      <item row="0" column="0">
-      <widget class="QLabel" name="inputAudioDeviceLabel">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-         <horstretch>0</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
-       </property>
-       <property name="minimumSize">
-        <size>
-         <width>0</width>
-         <height>25</height>
-        </size>
-       </property>
-       <property name="text">
-        <string>Input Audio Device</string>
-       </property>
-       <property name="wordWrap">
-        <bool>false</bool>
-       </property>
-      </widget>
-     </item>
-     <item row="0" column="1">
-      <widget class="QComboBox" name="inputPCMNameComboBox"/>
-     </item>
-     <item row="1" column="0">
-      <widget class="QLabel" name="outputAudioDeviceLabel">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-         <horstretch>0</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
-       </property>
-       <property name="minimumSize">
-        <size>
-         <width>0</width>
-         <height>25</height>
-        </size>
-       </property>
-       <property name="text">
-        <string>Output Audio Device</string>
-       </property>
-       <property name="wordWrap">
-        <bool>false</bool>
-       </property>
-      </widget>
-     </item>
-     <item row="1" column="1">
-      <widget class="QComboBox" name="outputPCMNameComboBox"/>
-     </item>
-     <item row="2" column="0">
       <widget class="QLabel" name="inputClockLabel">
        <property name="sizePolicy">
         <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
@@ -88,7 +122,7 @@
        </property>
       </widget>
      </item>
-     <item row="2" column="1">
+     <item row="0" column="1">
       <layout class="QHBoxLayout" name="horizontalLayout_2">
        <item>
         <widget class="QLineEdit" name="inputClockLineEdit"/>
@@ -108,7 +142,7 @@
        </item>
       </layout>
      </item>
-     <item row="3" column="0">
+     <item row="1" column="0">
       <widget class="QLabel" name="outputClockLabel">
        <property name="sizePolicy">
         <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
@@ -130,7 +164,7 @@
        </property>
       </widget>
      </item>
-     <item row="3" column="1">
+     <item row="1" column="1">
       <layout class="QHBoxLayout" name="horizontalLayout_3">
        <item>
         <widget class="QLineEdit" name="outputClockLineEdit"/>
@@ -216,6 +250,13 @@
     </layout>
    </item>
    <item>
+    <widget class="QCheckBox" name="pttToneCheckBox">
+     <property name="text">
+      <string>PTT tone on right audio channel</string>
+     </property>
+    </widget>
+   </item>
+   <item>
     <layout class="QHBoxLayout" name="_5">
      <item>
       <widget class="QSpinBox" name="mbSpinBox">
diff --git a/qsstv/config/waterfallconfig.cpp b/qsstv/config/waterfallconfig.cpp
new file mode 100644
index 0000000..2b4aba3
--- /dev/null
+++ b/qsstv/config/waterfallconfig.cpp
@@ -0,0 +1,82 @@
+#include "waterfallconfig.h"
+#include "ui_waterfallconfig.h"
+#include <QFont>
+
+
+QString startPicWF;
+QString endPicWF;
+QString fixWF;
+QString bsrWF;
+QString wfFont;
+int wfFontSize;
+
+waterfallConfig::waterfallConfig(QWidget *parent) : baseConfig(parent),  ui(new Ui::waterfallConfig)
+{
+  ui->setupUi(this);
+  connect(ui->fontComboBox,SIGNAL(currentIndexChanged(QString)),SLOT(slotFontChanged()));
+  connect(ui->sizeSpinBox,SIGNAL(valueChanged(int)),SLOT(slotFontChanged()));
+}
+
+waterfallConfig::~waterfallConfig()
+{
+  delete ui;
+}
+
+
+void waterfallConfig::readSettings()
+{
+  QSettings qSettings;
+  qSettings.beginGroup("WATERFALL");
+  startPicWF=qSettings.value("startPicWF","START PIC").toString();
+  endPicWF=qSettings.value("endPicWF","END PIC").toString();
+  fixWF=qSettings.value("fixWF","FIX").toString();
+  bsrWF=qSettings.value("bsrWF","BSR").toString();
+  wfFont=qSettings.value("wfFont","Arial").toString();
+  wfFontSize=qSettings.value("wfFontSize",12).toInt();
+  qSettings.endGroup();
+  setParams();
+}
+
+void waterfallConfig::writeSettings()
+{
+  QSettings qSettings;
+  getParams();
+  qSettings.beginGroup("WATERFALL");
+  qSettings.setValue("startPicWF",startPicWF);
+  qSettings.setValue("endPicWF",endPicWF);
+  qSettings.setValue("fixWF",fixWF);
+  qSettings.setValue("bsrWF",bsrWF);
+  qSettings.setValue("wfFont",wfFont);
+  qSettings.setValue("wfFontSize",wfFontSize);
+  qSettings.endGroup();
+}
+
+void waterfallConfig::getParams()
+{
+  getValue(startPicWF,ui->startPicTextEdit);
+  getValue(endPicWF,ui->endPicTextEdit);
+  getValue(fixWF,ui->fixTextEdit);
+  getValue(bsrWF,ui->bsrTextEdit);
+  getValue(wfFont,ui->fontComboBox);
+  getValue(wfFontSize,ui->sizeSpinBox);
+}
+
+void waterfallConfig::setParams()
+{
+  setValue(startPicWF,ui->startPicTextEdit);
+  setValue(endPicWF,ui->endPicTextEdit);
+  setValue(fixWF,ui->fixTextEdit);
+  setValue(bsrWF,ui->bsrTextEdit);
+  setValue(wfFont,ui->fontComboBox);
+  setValue(wfFontSize,ui->sizeSpinBox);
+}
+
+void waterfallConfig::slotFontChanged()
+{
+  getParams();
+  QFont f(wfFont);
+  f.setPixelSize(wfFontSize);
+  ui->sampleLineEdit->setFont(f);
+}
+
+
diff --git a/qsstv/config/waterfallconfig.h b/qsstv/config/waterfallconfig.h
new file mode 100644
index 0000000..f10c94e
--- /dev/null
+++ b/qsstv/config/waterfallconfig.h
@@ -0,0 +1,37 @@
+#ifndef WATERFALLCONFIG_H
+#define WATERFALLCONFIG_H
+
+#include "baseconfig.h"
+
+extern QString startPicWF;
+extern QString endPicWF;
+extern QString fixWF;
+extern QString bsrWF;
+extern QString wfFont;
+extern int wfFontSize;
+
+
+namespace Ui {
+class waterfallConfig;
+}
+
+class waterfallConfig : public baseConfig
+{
+  Q_OBJECT
+  
+public:
+  explicit waterfallConfig(QWidget *parent = 0);
+  ~waterfallConfig();
+  void readSettings();
+  void writeSettings();
+  void getParams();
+  void setParams();
+
+public slots:
+  void slotFontChanged();
+  
+private:
+  Ui::waterfallConfig *ui;
+};
+
+#endif // WATERFALLCONFIG_H
diff --git a/qsstv/config/waterfallconfig.ui b/qsstv/config/waterfallconfig.ui
new file mode 100644
index 0000000..5ed8a19
--- /dev/null
+++ b/qsstv/config/waterfallconfig.ui
@@ -0,0 +1,200 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>waterfallConfig</class>
+ <widget class="QWidget" name="waterfallConfig">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>609</width>
+    <height>551</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <layout class="QGridLayout" name="gridLayout">
+     <item row="0" column="0">
+      <widget class="QLabel" name="pictureLabel">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>0</width>
+         <height>0</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>Start Picture</string>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item row="0" column="1">
+      <widget class="QPlainTextEdit" name="startPicTextEdit">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="lineWidth">
+        <number>2</number>
+       </property>
+       <property name="midLineWidth">
+        <number>1</number>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="0">
+      <widget class="QLabel" name="pictureLabel_2">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>0</width>
+         <height>0</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>End Picture</string>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="1">
+      <widget class="QPlainTextEdit" name="endPicTextEdit">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+      </widget>
+     </item>
+     <item row="2" column="0">
+      <widget class="QLabel" name="fixLabel">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>0</width>
+         <height>0</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>FIX</string>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item row="2" column="1">
+      <widget class="QPlainTextEdit" name="fixTextEdit">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+      </widget>
+     </item>
+     <item row="3" column="0">
+      <widget class="QLabel" name="bsrLabel">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>0</width>
+         <height>0</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>BSR</string>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item row="3" column="1">
+      <widget class="QPlainTextEdit" name="bsrTextEdit">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0,0,0,0,1">
+     <item>
+      <widget class="QLabel" name="fontLabel">
+       <property name="text">
+        <string>Font</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QFontComboBox" name="fontComboBox"/>
+     </item>
+     <item>
+      <widget class="QLabel" name="sizeLabel">
+       <property name="text">
+        <string>Size</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QSpinBox" name="sizeSpinBox">
+       <property name="minimum">
+        <number>8</number>
+       </property>
+       <property name="value">
+        <number>12</number>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLabel" name="sampleLabel">
+       <property name="text">
+        <string>Sample</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="sampleLineEdit"/>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/qsstv/configdialog.cpp b/qsstv/configdialog.cpp
deleted file mode 100644
index b650fff..0000000
--- a/qsstv/configdialog.cpp
+++ /dev/null
@@ -1,557 +0,0 @@
-/**************************************************************************
-*   Copyright (C) 2000-2012 by Johan Maes                                 *
-*   on4qz at telenet.be                                                      *
-*   http://users.telenet.be/on4qz                                         *
-*                                                                         *
-*   This program is free software; you can redistribute it and/or modify  *
-*   it under the terms of the GNU General Public License as published by  *
-*   the Free Software Foundation; either version 2 of the License, or     *
-*   (at your option) any later version.                                   *
-*                                                                         *
-*   This program is distributed in the hope that it will be useful,       *
-*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
-*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
-*   GNU General Public License for more details.                          *
-*                                                                         *
-*   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.,                                       *
-*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
-***************************************************************************/
-#include "configdialog.h"
-#include "configparams.h"
-
-#include <QPushButton>
-#include <QComboBox>
-#include <QSettings>
-#include "sstv/sstvparam.h"
-//#include <QImage>
-#include <QImageWriter>
-#include "qsstvglobal.h"
-#include "utils/supportfunctions.h"
-#include "videocapt/videocapture.h"
-#include "rig/rigcontrol.h"
-#include "mainwindow.h"
-#include "sound/soundcontrol.h"
-#include "txwidget.h"
-#include "utils/ftp.h"
-#include "utils/hybridcrypt.h"
-#include <errno.h>
-
-/**
-	\class configDialog 
-	
-	The configDialog provides access to the application-wide configuration parameters.
-*/
-
-
-
-/**
-  constructor for configDialog
-*/
-configDialog::configDialog(QWidget *, const char *) :Ui::configForm()
-{
-	setupUi(this);
-  int i=0;
-  setModal(false);
-  foreach (QByteArray format, QImageWriter::supportedImageFormats())
-    {
-      QString text = tr("%1").arg(QString(format));
-      defaultImageFormatComboBox->addItem(text);
-      ftpDefaultImageFormatComboBox->addItem(text);
-    }
-  for(i=0;i<(NUMSSTVMODES-1);i++) // exclude Calibrate
-    {
-      repeaterTxModeComboBox->addItem(getSSTVModeNameLong((esstvMode)i));
-    }
-  rigWidget->attachRigController(rigControllerR1);
-//  rigR2Widget->attachRigController(rigControllerR2);
-  readSettings();
-	connect(rxImagesPathBrowseButton,SIGNAL(clicked()),SLOT(slotBrowseRxImagesPath()));
-	connect(txImagesPathBrowseButton,SIGNAL(clicked()),SLOT(slotBrowseTxImagesPath()));
-	connect(templatesPathBrowseButton,SIGNAL(clicked()),SLOT(slotBrowseTemplatesPath()));
-  connect(audioPathBrowseButton,SIGNAL(clicked()),SLOT(slotBrowseAudioPath()));
-  connect(rp1BrowseButton,SIGNAL(clicked()),SLOT(slotRp1BrowseButton()));
-  connect(rp2BrowseButton,SIGNAL(clicked()),SLOT(slotRp2BrowseButton()));
-  connect(rp3BrowseButton,SIGNAL(clicked()),SLOT(slotRp3BrowseButton()));
-  connect(rp4BrowseButton,SIGNAL(clicked()),SLOT(slotRp4BrowseButton()));
-  connect(repeaterTemplateBrowseButton,SIGNAL(clicked()),SLOT(slotRepeaterTemplateBrowseButton()));
-  connect(idleTemplateBrowseButton,SIGNAL(clicked()),SLOT(slotIdleTemplateBrowseButton()));
-  drmProfilePtr=drmProfileWidget;
-  tabWidget->setCurrentIndex(0);
-  connect(testFTPPushButton,SIGNAL(clicked()),SLOT(slotTestFTPPushButton()));
-  connect(testHybridPushButton,SIGNAL(clicked()),SLOT(slotTestHybridPushButton()));
-}
-
-/**
-	destructor for configDialog
-*/
-configDialog::~configDialog()
-{
-}
-
-/** read variables from config file
-
-	Read the config file and initializes the variables. If not found, default values will be used.
-	\sa writeSettings
-	
-*/
-void configDialog::readSettings()
-{
-    QSettings qSettings;
-    qSettings.beginGroup("Config");
-    myCallsign=qSettings.value("callsign",QString("NOCALL")).toString();
-    myQth=qSettings.value("qth",QString("NOWHERE")).toString();
-    myLastname=qSettings.value("lastname",QString("NONAME")).toString();
-    myFirstname=qSettings.value("firstname",QString("NOFIRSTNAME")).toString();
-    myLocator=qSettings.value("locator",QString("NOLOCATOR")).toString();
-
-    rxImagesPath=qSettings.value("rxImagesPath",QString(getenv("HOME"))+"/").toString();
-    txImagesPath=qSettings.value("txImagesPath",QString(getenv("HOME"))+"/").toString();
-    templatesPath=qSettings.value("templatesPath",QString(getenv("HOME"))+"/").toString();
-    docURL=qSettings.value("docURL","http://users.telenet.be/on4qz/qsstv/manual").toString();
-    audioPath=qSettings.value("audioPath",QString(getenv("HOME"))+"/").toString();
-    defaultImageFormat=qSettings.value("defaultImageFormat","png").toString();
-    //	fontString=qSettings.value("fontString","").toString();
-    samplingrate=qSettings.value("samplingrate",11025).toInt();
-    cwText=qSettings.value("cwtext","").toString();
-    cwTone=qSettings.value("cwtone",800).toInt();
-    cwWPM=qSettings.value("cwWPM",12).toInt();
-    enableFTP=qSettings.value("enableFTP",false).toBool();
-    ftpPort=qSettings.value("ftpPort",21).toInt();
-    ftpRemoteHost=qSettings.value("ftpRemoteHost","").toString();
-    ftpRemoteDirectory=qSettings.value("ftpRemoteDirectory","").toString();
-    ftpLogin=qSettings.value("ftpLogin","").toString();
-    ftpPassword=qSettings.value("ftpPassword","").toString();
-    ftpFilename=qSettings.value("ftpFilename","").toString();
-    ftpDefaultImageFormat=qSettings.value("ftpDefaultImageFormat","png").toString();
-    ftpSaveFormat=(eftpSaveFormat)qSettings.value("ftpSaveFormat",0).toInt();
-    ftpNumImages=qSettings.value("ftpNumImages",30).toInt();
-
-
-    enableHybridRx=qSettings.value("enableHybridRx",true).toBool();
-    enableSpecialServer=qSettings.value("enableSpecialServer",false).toBool();
-    hybridFtpPort=qSettings.value("hybridFtpPort",21).toInt();
-    hybridFtpRemoteHost=qSettings.value("hybridFtpRemoteHost","").toString();
-    hybridFtpRemoteDirectory=qSettings.value("hybridFtpRemoteDirectory","").toString();
-    hybridFtpHybridFilesDirectory=qSettings.value("hybridFtpHybridFilesDirectory","HybridFiles1").toString();
-    hybridFtpLogin=qSettings.value("hybridFtpLogin","").toString();
-    hybridFtpPassword=qSettings.value("hybridFtpPassword","").toString();
-    repeaterImageInterval=qSettings.value("repeaterImageInterval",10).toInt();
-    repeaterEnable=qSettings.value("repeaterEnable",false).toBool();
-    repeaterTxMode=(esstvMode)qSettings.value("repeaterTxMode",0).toInt();
-    repeaterImage1=qSettings.value("repeaterImage1","").toString();
-    repeaterImage2=qSettings.value("repeaterImage2","").toString();
-    repeaterImage3=qSettings.value("repeaterImage3","").toString();
-    repeaterImage4=qSettings.value("repeaterImage4","").toString();
-    repeaterAcknowledge=qSettings.value("repeaterAcknowledge","").toString();
-    repeaterTemplate=qSettings.value("repeaterTemplate","").toString();
-    idleTemplate=qSettings.value("idleTemplate","").toString();
-    videoDevice=qSettings.value("videoDevice","/dev/video0").toString();
-    channelNumber=qSettings.value("channelNumber",0).toInt();
-    //	framesPerSecondIndex=qSettings.value("framesPerSecondIndex",0).toInt();
-    colorFormatIndex=qSettings.value("colorFormatIndex",0).toInt();
-    // DRM
-    startPicWF=qSettings.value("startPicWF","START PIC").toString();
-    endPicWF=qSettings.value("endPicWF","END PIC").toString();
-    fixWF=qSettings.value("fixWF","FIX").toString();
-    bsrWF=qSettings.value("bsrWF","BSR").toString();
-
-    sizeIndex=qSettings.value("sizeIndex",0).toInt();
-    qSettings.endGroup();
-    setParams();
-    soundWidget->readSettings();
-    rigWidget->readSettings();
-}
-
-/**
- write variables to config file
-        \sa readSettings
-
-*/
-void configDialog::writeSettings()
-{
-    rigWidget->writeSettings();
-    soundWidget->writeSettings();
-    getParams();
-    QSettings qSettings;
-    qSettings.beginGroup("Config");
-    qSettings.setValue("callsign",myCallsign);
-    qSettings.setValue("qth",myQth);
-    qSettings.setValue("locator",myLocator);
-    qSettings.setValue("lastname",myLastname);
-    qSettings.setValue("firstname",myFirstname);
-    qSettings.setValue("rxImagesPath",rxImagesPath);
-    qSettings.setValue("txImagesPath",txImagesPath);
-    qSettings.setValue("templatesPath",templatesPath);
-    qSettings.setValue("audioPath",audioPath);
-    qSettings.setValue("docURL",docURL);
-    qSettings.setValue("defaultImageFormat",defaultImageFormat);
-    //	qSettings.setValue("fontString",fontString);
-    qSettings.setValue("samplingrate",samplingrate);
-    qSettings.setValue("cwtext",cwText);
-    qSettings.setValue("cwtone",cwTone);
-    qSettings.setValue("cwWPM",cwWPM);
-    qSettings.setValue("enableFTP",enableFTP);
-    qSettings.setValue("ftpPort",ftpPort);
-    qSettings.setValue("ftpRemoteHost",ftpRemoteHost);
-    qSettings.setValue("ftpRemoteDirectory",ftpRemoteDirectory);
-    qSettings.setValue("ftpLogin",ftpLogin);
-    qSettings.setValue("ftpPassword",ftpPassword);
-    qSettings.setValue("ftpFilename",ftpFilename);
-    qSettings.setValue("ftpDefaultImageFormat",ftpDefaultImageFormat);
-    qSettings.setValue("ftpSaveFormat",(int)ftpSaveFormat);
-    qSettings.setValue("ftpNumImages",ftpNumImages);
-    qSettings.setValue("repeaterImageInterval",repeaterImageInterval);
-    qSettings.setValue("enableHybridRx",enableHybridRx);
-    qSettings.setValue("enableSpecialServer",enableSpecialServer);
-    qSettings.setValue("hybridFtpPort",hybridFtpPort);
-    qSettings.setValue("hybridFtpRemoteHost",hybridFtpRemoteHost);
-    qSettings.setValue("hybridFtpRemoteDirectory",hybridFtpRemoteDirectory);
-    qSettings.setValue("hybridFtpHybridFilesDirectory",hybridFtpHybridFilesDirectory);
-    qSettings.setValue("hybridFtpLogin",hybridFtpLogin);
-    qSettings.setValue("hybridFtpPassword",hybridFtpPassword);
-    qSettings.setValue("repeaterEnable",repeaterEnable);
-    qSettings.setValue("repeaterTxMode",repeaterTxMode);
-    qSettings.setValue("repeaterImage1",repeaterImage1);
-    qSettings.setValue("repeaterImage2",repeaterImage2);
-    qSettings.setValue("repeaterImage3",repeaterImage3);
-    qSettings.setValue("repeaterImage4",repeaterImage4);
-    qSettings.setValue("repeaterAcknowledge",repeaterAcknowledge);
-    qSettings.setValue("repeaterTemplate",repeaterTemplate);
-    qSettings.setValue("idleTemplate",idleTemplate);
-    qSettings.setValue("videoDevice",videoDevice);
-    qSettings.setValue("channelNumber",channelNumber);
-    //	qSettings.setValue("framesPerSecondIndex",framesPerSecondIndex);
-    qSettings.setValue("colorFormatIndex",colorFormatIndex);
-    qSettings.setValue("sizeIndex",sizeIndex);
-    qSettings.setValue("startPicWF",startPicWF);
-    qSettings.setValue("endPicWF",endPicWF);
-    qSettings.setValue("fixWF",fixWF);
-    qSettings.setValue("bsrWF",bsrWF);
-    qSettings.endGroup();
-    drmProfileWidget->writeSettings();
-}
-
-
-/**
-    Opens the configuration dialog
-*/
-
-int configDialog::exec()
-{
-    videoCapture vc;
-    int i=0;
-    colorFormatComboBox->clear();
-    sizeComboBox->clear();
-
-    if(vc.open())
-    {
-        QList <QString> description;
-        vc.getFormatList(description);
-        for(i=0;i<description.count();i++)
-        {
-            colorFormatComboBox->addItem(description[i]);
-        }
-
-        QList<QSize> sizeList(vc.getSizesList());
-
-        for(i=0;i<sizeList.count();i++)
-        {
-            sizeComboBox->addItem(QString::number(sizeList[i].width())+ " x " + QString::number(sizeList[i].height()));
-        }
-        vc.close();
-    }
-    setParams();
-    soundWidget->setParams();
-    drmProfileWidget->setParams();
-    if(QDialog::exec())
-    {
-        writeSettings();
-        txWidgetPtr->setProfileNames();
-        mainWindowPtr->setNewFont();
-        return QDialog::Accepted;
-    }
-    else
-    {
-        return QDialog::Rejected;
-    }
-}
-
-/**
- copies the values from the variables to the userinterface
-		\sa getParams
-	
-*/
-
-void configDialog::setParams()
-{
-
-    setValue(myCallsign,callsignLineEdit);
-    setValue(myLastname,lastnameLineEdit);
-    setValue(myFirstname,firstnameLineEdit);
-    setValue(myQth,qthLineEdit);
-    setValue(myLocator,locatorLineEdit);
-    setValue(rxImagesPath, rxImagesPathLineEdit);
-    setValue(txImagesPath, txImagesPathLineEdit);
-    setValue(templatesPath, templatesPathLineEdit);
-    setValue(audioPath, audioPathLineEdit);
-    setValue(docURL, docPathLineEdit);
-    setValue(defaultImageFormat, defaultImageFormatComboBox);
-
-    QFont fnt;
-    //  fnt.fromString(fontString);
-    //  fontComboBox->setCurrentFont(fnt);
-    //  setValue(fnt.pointSize(),fontSizeSpinBox);
-
-    setValue(cwText,cwTextLineEdit);
-    setValue(cwTone,cwToneSpinBox);
-    setValue(cwWPM,cwWPMSpinBox);
-    setValue(enableFTP,enableFTPCheckBox);
-    setValue(ftpPort,ftpPortSpinBox);
-    setValue(ftpRemoteHost,remoteHostLineEdit);
-    setValue(ftpRemoteDirectory,remoteDirectoryLineEdit);
-    setValue(ftpLogin,ftpLoginLineEdit);
-    setValue(ftpPassword,ftpPasswordLineEdit);
-    if(ftpSaveFormat==FTPIM)
-      {
-        imageRadioButton->setChecked(true);
-      }
-    else
-      {
-        filenameRadioButton->setChecked(true);
-      }
-    setValue(ftpNumImages,ftpNumImagesSpinBox);
-    setValue(enableHybridRx,enableHybridRxCheckBox);
-    setValue(enableSpecialServer,enableSpecialServerCheckBox);
-    setValue(hybridFtpPort,hybridFtpPortSpinBox);
-    setValue(hybridFtpRemoteHost,hybridRemoteHostLineEdit);
-    setValue(hybridFtpRemoteDirectory,hybridRemoteDirectoryLineEdit);
-    setValue(hybridFtpHybridFilesDirectory,hybridFilesDirectoryLineEdit);
-    setValue(hybridFtpLogin,hybridFtpLoginLineEdit);
-    setValue(hybridFtpPassword,hybridFtpPasswordLineEdit);
-
-    setValue(ftpDefaultImageFormat,ftpDefaultImageFormatComboBox);
-    setValue(repeaterEnable,repeaterEnableCheckBox);
-    setIndex(repeaterTxMode,repeaterTxModeComboBox);
-    setValue(repeaterImage1,repeaterImage1LineEdit);
-    setValue(repeaterImage2,repeaterImage2LineEdit);
-    setValue(repeaterImage3,repeaterImage3LineEdit);
-    setValue(repeaterImage4,repeaterImage4LineEdit);
-    setValue(idleTemplate,idleTemplateLineEdit);
-    setValue(repeaterTemplate,repeaterTemplateLineEdit);
-    setValue(videoDevice,videoDeviceLineEdit);
-    setValue(channelNumber, channelSpinBox);
-    setIndex(colorFormatIndex,colorFormatComboBox);
-    setIndex(sizeIndex,sizeComboBox);
-
-    setValue(startPicWF,startPicTextEdit);
-    setValue(endPicWF,endPicTextEdit);
-    setValue(fixWF,fixTextEdit);
-    setValue(bsrWF,bsrTextEdit);
-}
-
-/**
- copies the values from the userinterface to the variables
-
-		\sa setParams
-	
-*/
-
-void configDialog::getParams()
-{
-    getValue(myCallsign,callsignLineEdit);
-    getValue(myLastname,lastnameLineEdit);
-    getValue(myFirstname,firstnameLineEdit);
-    getValue(myQth,qthLineEdit);
-    getValue(myLocator,locatorLineEdit);
-    getValue(rxImagesPath, rxImagesPathLineEdit);
-    getValue(txImagesPath, txImagesPathLineEdit);
-    getValue(templatesPath, templatesPathLineEdit);
-    getValue(audioPath, audioPathLineEdit);
-    getValue(docURL, docPathLineEdit);
-    getValue(defaultImageFormat, defaultImageFormatComboBox);
-    //	QFont fnt(fontComboBox->currentFont());
-    //	fnt.setPointSize(fontSizeSpinBox->value());
-    //	fontString=fnt.toString();
-
-    getValue(cwText,cwTextLineEdit);
-    getValue(cwTone,cwToneSpinBox);
-    getValue(cwWPM,cwWPMSpinBox);
-    getValue(enableFTP,enableFTPCheckBox);
-    getValue(ftpPort,ftpPortSpinBox);
-    getValue(ftpRemoteHost,remoteHostLineEdit);
-    getValue(ftpRemoteDirectory,remoteDirectoryLineEdit);
-    getValue(ftpLogin,ftpLoginLineEdit);
-    getValue(ftpPassword,ftpPasswordLineEdit);
-//    getValue(ftpFilename,ftpFilenameLineEdit);
-    if(imageRadioButton->isChecked())
-      {
-       ftpSaveFormat=FTPIM;
-      }
-    else
-      {
-        ftpSaveFormat=FTPFILE;
-      }
-    getValue(ftpNumImages,ftpNumImagesSpinBox);
-
-    getValue(ftpDefaultImageFormat,ftpDefaultImageFormatComboBox);
-    getValue(enableHybridRx,enableHybridRxCheckBox);
-    getValue(enableSpecialServer,enableSpecialServerCheckBox);
-    getValue(hybridFtpPort,hybridFtpPortSpinBox);
-    getValue(hybridFtpRemoteHost,hybridRemoteHostLineEdit);
-    getValue(hybridFtpRemoteDirectory,hybridRemoteDirectoryLineEdit);
-    getValue(hybridFtpHybridFilesDirectory,hybridFilesDirectoryLineEdit);
-    getValue(hybridFtpLogin,hybridFtpLoginLineEdit);
-    getValue(hybridFtpPassword,hybridFtpPasswordLineEdit);
-
-    getValue(repeaterEnable,repeaterEnableCheckBox);
-    int temp;
-    getIndex(temp,repeaterTxModeComboBox);
-    repeaterTxMode=esstvMode(temp);
-    getValue(repeaterImage1,repeaterImage1LineEdit);
-    getValue(repeaterImage2,repeaterImage2LineEdit);
-    getValue(repeaterImage3,repeaterImage3LineEdit);
-    getValue(repeaterImage4,repeaterImage4LineEdit);
-    getValue(idleTemplate,idleTemplateLineEdit);
-    getValue(repeaterTemplate,repeaterTemplateLineEdit);
-    getValue(videoDevice,videoDeviceLineEdit);
-    getValue(channelNumber, channelSpinBox);
-    getIndex(colorFormatIndex,colorFormatComboBox);
-    getIndex(sizeIndex,sizeComboBox);
-    getValue(startPicWF,startPicTextEdit);
-    getValue(endPicWF,endPicTextEdit);
-    getValue(fixWF,fixTextEdit);
-    getValue(bsrWF,bsrTextEdit);
-}
-
-/**
-	Browse function for path where the rximages are stored
-*/
-
-
-void configDialog::slotBrowseRxImagesPath()
-{
-	browseDir(rxImagesPathLineEdit,rxImagesPath);
-}
-
-/**
-	Browse function for path where the tximages are stored
-*/
-
-void configDialog::slotBrowseTxImagesPath()
-{
-	browseDir(txImagesPathLineEdit,txImagesPath);
-}
-
-/**
-	Browse function for path where the templates are stored
-*/
-
-void configDialog::slotBrowseTemplatesPath()
-{
-	browseDir(templatesPathLineEdit,templatesPath);
-}
-
-/**
-	Browse function for audio path
-*/
-
-void configDialog::slotBrowseAudioPath()
-{
-	browseDir(audioPathLineEdit,audioPath);
-}
-
-/**
-	Browse function for documentation path
-*/
-
-
-
-void configDialog::slotRp1BrowseButton()
-{
-  browseGetFile(repeaterImage1LineEdit,txImagesPath);
-}
-
-void configDialog::slotRp2BrowseButton()
-{
-  browseGetFile(repeaterImage2LineEdit,txImagesPath);
-}
-
-void configDialog::slotRp3BrowseButton()
-{
-  browseGetFile(repeaterImage3LineEdit,txImagesPath);
-}
-
-void configDialog::slotRp4BrowseButton()
-{
-  browseGetFile(repeaterImage4LineEdit,txImagesPath);
-}
-
-void configDialog::slotRepeaterTemplateBrowseButton()
-{
-  browseGetFile(repeaterTemplateLineEdit,templatesPath);
-}
-
-void configDialog::slotIdleTemplateBrowseButton()
-{
-  browseGetFile(idleTemplateLineEdit,templatesPath);
-}
-
-
-void configDialog::slotTestFTPPushButton()
-{
-  ftpInterface fInt("TestUploadConnection");
-  getParams();
-  fInt.setupConnection(ftpRemoteHost,ftpPort,ftpLogin,ftpPassword,ftpRemoteDirectory);
-  execFTPTest(&fInt);
-}
-
-
-void configDialog::slotTestHybridPushButton()
-{
-  ftpInterface fInt("TestHybridConnection");
-  getParams();
-  hybridCrypt hc;
-  fInt.setupConnection(hc.host(),hc.port(),hc.user(),hc.passwd(),hc.dir()+"/"+hybridFtpHybridFilesDirectory);
-  execFTPTest(&fInt);
-
-
-}
-
-
-void configDialog::execFTPTest(ftpInterface *ftpPtr)
-{
-  eftpError ftpResult;
-  QString fn(QString("%1/test.txt").arg(rxImagesPath));
-  //checkConnection
-  QFile tst(fn);
-  if(tst.open(QIODevice::WriteOnly)<=0)
-    {
-      QMessageBox::critical(this, tr("File Error"),QString("").arg(strerror(errno)));
-    }
-  tst.write("connection test\n");
-  tst.close();
-  ftpResult=ftpPtr->uploadFile(fn,QString("test_%1.txt").arg( myCallsign),true);
-  switch(ftpResult)
-    {
-    case FTPCANCELED:
-      QMessageBox::information(this, tr("FTP Info"),"Connection Canceled");
-    break;
-    case FTPOK:
-      QMessageBox::information(this, tr("FTP Info"),"Connection OK");
-    break;
-    case FTPERROR:
-       QMessageBox::critical(this, tr("FTP Error"),ftpPtr->getLastError());
-    break;
-    case FTPNAMEERROR:
-     QMessageBox::critical(this, tr("FTP Error"),"Error in filename");
-    break;
-    case FTPTIMEOUT:
-      QMessageBox::critical(this, tr("FTP Error"),"FTP timed out");
-      return;
-    }
-  tst.remove();
-}
-
-
diff --git a/qsstv/configdialog.h b/qsstv/configdialog.h
deleted file mode 100644
index 146b769..0000000
--- a/qsstv/configdialog.h
+++ /dev/null
@@ -1,52 +0,0 @@
-#ifndef CONFIGDIALOG_H
-#define CONFIGDIALOG_H
-
-#include "ui_configform.h"
-
-/** @author Johan Maes - ON4QZ */
-
-
-class ftpInterface;
-
-
-
-class configForm;
-
-//! configuration Dialog
-
-class configDialog: public QDialog, private Ui::configForm
-{
-Q_OBJECT
-public:
-    configDialog(QWidget *parent = 0, const char *name = 0);
-    ~configDialog();
-		void writeSettings();
-		void readSettings();
-    int exec();
-
-		
-public slots:
-		void slotBrowseRxImagesPath();
-		void slotBrowseTxImagesPath();
-		void slotBrowseTemplatesPath();
-		void slotBrowseAudioPath();
-    void slotRp1BrowseButton();
-    void slotRp2BrowseButton();
-    void slotRp3BrowseButton();
-    void slotRp4BrowseButton();
-    void slotRepeaterTemplateBrowseButton();
-    void slotIdleTemplateBrowseButton();
-    void slotTestFTPPushButton();
-    void slotTestHybridPushButton();
-
-
-private:
-		void getParams();
-		void setParams();
-    void execFTPTest(ftpInterface *ftpPtr);
-
-};
-
-
-
-#endif
diff --git a/qsstv/configform.ui b/qsstv/configform.ui
deleted file mode 100644
index 6515cad..0000000
--- a/qsstv/configform.ui
+++ /dev/null
@@ -1,2670 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>configForm</class>
- <widget class="QDialog" name="configForm">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>733</width>
-    <height>441</height>
-   </rect>
-  </property>
-  <property name="font">
-   <font>
-    <pointsize>9</pointsize>
-   </font>
-  </property>
-  <property name="windowTitle">
-   <string>ConfigForm</string>
-  </property>
-  <layout class="QVBoxLayout">
-   <property name="spacing">
-    <number>2</number>
-   </property>
-   <property name="leftMargin">
-    <number>1</number>
-   </property>
-   <property name="topMargin">
-    <number>1</number>
-   </property>
-   <property name="rightMargin">
-    <number>1</number>
-   </property>
-   <property name="bottomMargin">
-    <number>1</number>
-   </property>
-   <item>
-    <widget class="QTabWidget" name="tabWidget">
-     <property name="enabled">
-      <bool>true</bool>
-     </property>
-     <property name="tabShape">
-      <enum>QTabWidget::Rounded</enum>
-     </property>
-     <property name="currentIndex">
-      <number>9</number>
-     </property>
-     <widget class="QWidget" name="tb1">
-      <attribute name="title">
-       <string>Personal Settings</string>
-      </attribute>
-      <layout class="QVBoxLayout">
-       <property name="spacing">
-        <number>2</number>
-       </property>
-       <property name="leftMargin">
-        <number>1</number>
-       </property>
-       <property name="topMargin">
-        <number>1</number>
-       </property>
-       <property name="rightMargin">
-        <number>1</number>
-       </property>
-       <property name="bottomMargin">
-        <number>1</number>
-       </property>
-       <item>
-        <layout class="QHBoxLayout">
-         <item>
-          <widget class="QLabel" name="callsignLabel">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="minimumSize">
-            <size>
-             <width>130</width>
-             <height>25</height>
-            </size>
-           </property>
-           <property name="text">
-            <string>Callsign</string>
-           </property>
-           <property name="wordWrap">
-            <bool>false</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QLineEdit" name="callsignLineEdit">
-           <property name="alignment">
-            <set>Qt::AlignRight</set>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <spacer>
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeType">
-            <enum>QSizePolicy::Expanding</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>120</width>
-             <height>20</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <layout class="QHBoxLayout">
-         <item>
-          <widget class="QLabel" name="firstnameLabel">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="minimumSize">
-            <size>
-             <width>130</width>
-             <height>25</height>
-            </size>
-           </property>
-           <property name="text">
-            <string>Firstname</string>
-           </property>
-           <property name="wordWrap">
-            <bool>false</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QLineEdit" name="firstnameLineEdit">
-           <property name="alignment">
-            <set>Qt::AlignRight</set>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <spacer>
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeType">
-            <enum>QSizePolicy::Expanding</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>120</width>
-             <height>20</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <layout class="QHBoxLayout">
-         <item>
-          <widget class="QLabel" name="lastnameLabel">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="minimumSize">
-            <size>
-             <width>130</width>
-             <height>25</height>
-            </size>
-           </property>
-           <property name="text">
-            <string>Lastname</string>
-           </property>
-           <property name="wordWrap">
-            <bool>false</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QLineEdit" name="lastnameLineEdit">
-           <property name="alignment">
-            <set>Qt::AlignRight</set>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <spacer>
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeType">
-            <enum>QSizePolicy::Expanding</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>120</width>
-             <height>20</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <layout class="QHBoxLayout">
-         <item>
-          <widget class="QLabel" name="qthLabel">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="minimumSize">
-            <size>
-             <width>130</width>
-             <height>25</height>
-            </size>
-           </property>
-           <property name="text">
-            <string>QTH</string>
-           </property>
-           <property name="wordWrap">
-            <bool>false</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QLineEdit" name="qthLineEdit">
-           <property name="alignment">
-            <set>Qt::AlignRight</set>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <spacer>
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeType">
-            <enum>QSizePolicy::Expanding</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>120</width>
-             <height>20</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <layout class="QHBoxLayout">
-         <item>
-          <widget class="QLabel" name="locatorLabel">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="minimumSize">
-            <size>
-             <width>130</width>
-             <height>25</height>
-            </size>
-           </property>
-           <property name="text">
-            <string>Locator</string>
-           </property>
-           <property name="wordWrap">
-            <bool>false</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QLineEdit" name="locatorLineEdit">
-           <property name="alignment">
-            <set>Qt::AlignRight</set>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <spacer>
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeType">
-            <enum>QSizePolicy::Expanding</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>120</width>
-             <height>20</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <spacer>
-         <property name="orientation">
-          <enum>Qt::Vertical</enum>
-         </property>
-         <property name="sizeType">
-          <enum>QSizePolicy::Expanding</enum>
-         </property>
-         <property name="sizeHint" stdset="0">
-          <size>
-           <width>21</width>
-           <height>30</height>
-          </size>
-         </property>
-        </spacer>
-       </item>
-      </layout>
-     </widget>
-     <widget class="QWidget" name="tb2">
-      <attribute name="title">
-       <string>Directories</string>
-      </attribute>
-      <layout class="QVBoxLayout" name="verticalLayout_4">
-       <item>
-        <layout class="QHBoxLayout">
-         <property name="spacing">
-          <number>6</number>
-         </property>
-         <property name="leftMargin">
-          <number>0</number>
-         </property>
-         <property name="topMargin">
-          <number>0</number>
-         </property>
-         <property name="rightMargin">
-          <number>0</number>
-         </property>
-         <property name="bottomMargin">
-          <number>0</number>
-         </property>
-         <item>
-          <widget class="QLabel" name="rxImLabel">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="minimumSize">
-            <size>
-             <width>150</width>
-             <height>25</height>
-            </size>
-           </property>
-           <property name="text">
-            <string>RX Images</string>
-           </property>
-           <property name="wordWrap">
-            <bool>false</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QLineEdit" name="rxImagesPathLineEdit"/>
-         </item>
-         <item>
-          <widget class="QPushButton" name="rxImagesPathBrowseButton">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="text">
-            <string>Browse ...</string>
-           </property>
-          </widget>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <layout class="QHBoxLayout">
-         <property name="spacing">
-          <number>6</number>
-         </property>
-         <property name="leftMargin">
-          <number>0</number>
-         </property>
-         <property name="topMargin">
-          <number>0</number>
-         </property>
-         <property name="rightMargin">
-          <number>0</number>
-         </property>
-         <property name="bottomMargin">
-          <number>0</number>
-         </property>
-         <item>
-          <widget class="QLabel" name="txImLabel">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="minimumSize">
-            <size>
-             <width>150</width>
-             <height>25</height>
-            </size>
-           </property>
-           <property name="text">
-            <string>TX Images</string>
-           </property>
-           <property name="wordWrap">
-            <bool>false</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QLineEdit" name="txImagesPathLineEdit"/>
-         </item>
-         <item>
-          <widget class="QPushButton" name="txImagesPathBrowseButton">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="text">
-            <string>Browse ...</string>
-           </property>
-          </widget>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <layout class="QHBoxLayout">
-         <property name="spacing">
-          <number>6</number>
-         </property>
-         <property name="leftMargin">
-          <number>0</number>
-         </property>
-         <property name="topMargin">
-          <number>0</number>
-         </property>
-         <property name="rightMargin">
-          <number>0</number>
-         </property>
-         <property name="bottomMargin">
-          <number>0</number>
-         </property>
-         <item>
-          <widget class="QLabel" name="templLabel">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="minimumSize">
-            <size>
-             <width>150</width>
-             <height>25</height>
-            </size>
-           </property>
-           <property name="text">
-            <string>Templates</string>
-           </property>
-           <property name="wordWrap">
-            <bool>false</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QLineEdit" name="templatesPathLineEdit"/>
-         </item>
-         <item>
-          <widget class="QPushButton" name="templatesPathBrowseButton">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="text">
-            <string>Browse ...</string>
-           </property>
-          </widget>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <layout class="QHBoxLayout">
-         <property name="spacing">
-          <number>6</number>
-         </property>
-         <property name="leftMargin">
-          <number>0</number>
-         </property>
-         <property name="topMargin">
-          <number>0</number>
-         </property>
-         <property name="rightMargin">
-          <number>0</number>
-         </property>
-         <property name="bottomMargin">
-          <number>0</number>
-         </property>
-         <item>
-          <widget class="QLabel" name="audioRecordsLabel">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="minimumSize">
-            <size>
-             <width>150</width>
-             <height>25</height>
-            </size>
-           </property>
-           <property name="text">
-            <string>Audio Records</string>
-           </property>
-           <property name="wordWrap">
-            <bool>false</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QLineEdit" name="audioPathLineEdit"/>
-         </item>
-         <item>
-          <widget class="QPushButton" name="audioPathBrowseButton">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="text">
-            <string>Browse ...</string>
-           </property>
-          </widget>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <layout class="QHBoxLayout" name="_4">
-         <property name="spacing">
-          <number>6</number>
-         </property>
-         <property name="leftMargin">
-          <number>0</number>
-         </property>
-         <property name="topMargin">
-          <number>0</number>
-         </property>
-         <property name="rightMargin">
-          <number>0</number>
-         </property>
-         <property name="bottomMargin">
-          <number>0</number>
-         </property>
-         <item>
-          <widget class="QLabel" name="docLabel">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="minimumSize">
-            <size>
-             <width>150</width>
-             <height>25</height>
-            </size>
-           </property>
-           <property name="text">
-            <string>Documentation </string>
-           </property>
-           <property name="wordWrap">
-            <bool>false</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QLineEdit" name="docPathLineEdit"/>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <layout class="QHBoxLayout">
-         <item>
-          <widget class="QLabel" name="defaultImageFormatLabel">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="minimumSize">
-            <size>
-             <width>150</width>
-             <height>25</height>
-            </size>
-           </property>
-           <property name="text">
-            <string>Default Image format</string>
-           </property>
-           <property name="wordWrap">
-            <bool>false</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QComboBox" name="defaultImageFormatComboBox"/>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <spacer>
-         <property name="orientation">
-          <enum>Qt::Vertical</enum>
-         </property>
-         <property name="sizeType">
-          <enum>QSizePolicy::Expanding</enum>
-         </property>
-         <property name="sizeHint" stdset="0">
-          <size>
-           <width>20</width>
-           <height>40</height>
-          </size>
-         </property>
-        </spacer>
-       </item>
-      </layout>
-     </widget>
-     <widget class="QWidget" name="tb3">
-      <attribute name="title">
-       <string>Audio</string>
-      </attribute>
-      <layout class="QVBoxLayout" name="verticalLayout_3">
-       <item>
-        <widget class="soundControl" name="soundWidget" native="true"/>
-       </item>
-      </layout>
-     </widget>
-     <widget class="QWidget" name="tb4">
-      <attribute name="title">
-       <string>CAT</string>
-      </attribute>
-      <layout class="QVBoxLayout" name="verticalLayout">
-       <item>
-        <widget class="rigControlForm" name="rigWidget" native="true"/>
-       </item>
-      </layout>
-     </widget>
-     <widget class="QWidget" name="tb5">
-      <attribute name="title">
-       <string>CW</string>
-      </attribute>
-      <layout class="QVBoxLayout">
-       <item>
-        <layout class="QHBoxLayout">
-         <property name="spacing">
-          <number>6</number>
-         </property>
-         <property name="leftMargin">
-          <number>0</number>
-         </property>
-         <property name="topMargin">
-          <number>0</number>
-         </property>
-         <property name="rightMargin">
-          <number>0</number>
-         </property>
-         <property name="bottomMargin">
-          <number>0</number>
-         </property>
-         <item>
-          <widget class="QLabel" name="toneLabel">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="minimumSize">
-            <size>
-             <width>145</width>
-             <height>25</height>
-            </size>
-           </property>
-           <property name="text">
-            <string>Tone</string>
-           </property>
-           <property name="wordWrap">
-            <bool>false</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QSpinBox" name="cwToneSpinBox">
-           <property name="minimum">
-            <number>300</number>
-           </property>
-           <property name="maximum">
-            <number>2300</number>
-           </property>
-           <property name="singleStep">
-            <number>50</number>
-           </property>
-           <property name="value">
-            <number>800</number>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <spacer>
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeType">
-            <enum>QSizePolicy::Expanding</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>20</width>
-             <height>20</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <layout class="QHBoxLayout">
-         <property name="spacing">
-          <number>6</number>
-         </property>
-         <property name="leftMargin">
-          <number>0</number>
-         </property>
-         <property name="topMargin">
-          <number>0</number>
-         </property>
-         <property name="rightMargin">
-          <number>0</number>
-         </property>
-         <property name="bottomMargin">
-          <number>0</number>
-         </property>
-         <item>
-          <widget class="QLabel" name="wpmLabel">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="minimumSize">
-            <size>
-             <width>145</width>
-             <height>25</height>
-            </size>
-           </property>
-           <property name="text">
-            <string>Words PerMinute</string>
-           </property>
-           <property name="wordWrap">
-            <bool>false</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QSpinBox" name="cwWPMSpinBox">
-           <property name="minimum">
-            <number>4</number>
-           </property>
-           <property name="maximum">
-            <number>30</number>
-           </property>
-           <property name="value">
-            <number>12</number>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <spacer>
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeType">
-            <enum>QSizePolicy::Expanding</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>20</width>
-             <height>20</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <layout class="QHBoxLayout">
-         <property name="spacing">
-          <number>6</number>
-         </property>
-         <property name="leftMargin">
-          <number>0</number>
-         </property>
-         <property name="topMargin">
-          <number>0</number>
-         </property>
-         <property name="rightMargin">
-          <number>0</number>
-         </property>
-         <property name="bottomMargin">
-          <number>0</number>
-         </property>
-         <item>
-          <widget class="QLabel" name="textToSendLabel">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="minimumSize">
-            <size>
-             <width>145</width>
-             <height>25</height>
-            </size>
-           </property>
-           <property name="text">
-            <string>Text to send</string>
-           </property>
-           <property name="wordWrap">
-            <bool>false</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QLineEdit" name="cwTextLineEdit"/>
-         </item>
-         <item>
-          <spacer>
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeType">
-            <enum>QSizePolicy::Expanding</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>20</width>
-             <height>20</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <spacer>
-         <property name="orientation">
-          <enum>Qt::Vertical</enum>
-         </property>
-         <property name="sizeType">
-          <enum>QSizePolicy::Expanding</enum>
-         </property>
-         <property name="sizeHint" stdset="0">
-          <size>
-           <width>20</width>
-           <height>160</height>
-          </size>
-         </property>
-        </spacer>
-       </item>
-      </layout>
-     </widget>
-     <widget class="QWidget" name="tb6">
-      <attribute name="title">
-       <string>Repeater</string>
-      </attribute>
-      <layout class="QVBoxLayout" name="verticalLayout_2">
-       <item>
-        <layout class="QHBoxLayout">
-         <item>
-          <widget class="QCheckBox" name="repeaterEnableCheckBox">
-           <property name="text">
-            <string>Enable Repeater</string>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <spacer>
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeType">
-            <enum>QSizePolicy::Expanding</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>20</width>
-             <height>20</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
-         <item>
-          <layout class="QHBoxLayout">
-           <property name="spacing">
-            <number>6</number>
-           </property>
-           <property name="leftMargin">
-            <number>0</number>
-           </property>
-           <property name="topMargin">
-            <number>0</number>
-           </property>
-           <property name="rightMargin">
-            <number>0</number>
-           </property>
-           <property name="bottomMargin">
-            <number>0</number>
-           </property>
-           <item>
-            <widget class="QLabel" name="imageIntervalLabel">
-             <property name="text">
-              <string>Image Interval (min)</string>
-             </property>
-             <property name="wordWrap">
-              <bool>false</bool>
-             </property>
-            </widget>
-           </item>
-           <item>
-            <widget class="QSpinBox" name="imageIntervalSpinBox">
-             <property name="minimum">
-              <number>5</number>
-             </property>
-            </widget>
-           </item>
-          </layout>
-         </item>
-         <item>
-          <spacer>
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeType">
-            <enum>QSizePolicy::Expanding</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>60</width>
-             <height>20</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
-         <item>
-          <layout class="QHBoxLayout">
-           <property name="spacing">
-            <number>6</number>
-           </property>
-           <property name="leftMargin">
-            <number>0</number>
-           </property>
-           <property name="topMargin">
-            <number>0</number>
-           </property>
-           <property name="rightMargin">
-            <number>0</number>
-           </property>
-           <property name="bottomMargin">
-            <number>0</number>
-           </property>
-           <item>
-            <widget class="QLabel" name="repeaterTxModeLabel">
-             <property name="text">
-              <string>Repeater TX mode</string>
-             </property>
-             <property name="wordWrap">
-              <bool>false</bool>
-             </property>
-            </widget>
-           </item>
-           <item>
-            <widget class="QComboBox" name="repeaterTxModeComboBox"/>
-           </item>
-          </layout>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <layout class="QHBoxLayout">
-         <property name="spacing">
-          <number>6</number>
-         </property>
-         <property name="leftMargin">
-          <number>0</number>
-         </property>
-         <property name="topMargin">
-          <number>0</number>
-         </property>
-         <property name="rightMargin">
-          <number>0</number>
-         </property>
-         <property name="bottomMargin">
-          <number>0</number>
-         </property>
-         <item>
-          <widget class="QLabel" name="rep1Label">
-           <property name="text">
-            <string>Idle Image 1</string>
-           </property>
-           <property name="wordWrap">
-            <bool>false</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QLineEdit" name="repeaterImage1LineEdit">
-           <property name="modified">
-            <bool>false</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QPushButton" name="rp1BrowseButton">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="text">
-            <string>Browse ...</string>
-           </property>
-          </widget>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <layout class="QHBoxLayout">
-         <property name="spacing">
-          <number>6</number>
-         </property>
-         <property name="leftMargin">
-          <number>0</number>
-         </property>
-         <property name="topMargin">
-          <number>0</number>
-         </property>
-         <property name="rightMargin">
-          <number>0</number>
-         </property>
-         <property name="bottomMargin">
-          <number>0</number>
-         </property>
-         <item>
-          <widget class="QLabel" name="rp2Label">
-           <property name="text">
-            <string>Idle Image 2</string>
-           </property>
-           <property name="wordWrap">
-            <bool>false</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QLineEdit" name="repeaterImage2LineEdit">
-           <property name="modified">
-            <bool>false</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QPushButton" name="rp2BrowseButton">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="text">
-            <string>Browse ...</string>
-           </property>
-          </widget>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <layout class="QHBoxLayout">
-         <property name="spacing">
-          <number>6</number>
-         </property>
-         <property name="leftMargin">
-          <number>0</number>
-         </property>
-         <property name="topMargin">
-          <number>0</number>
-         </property>
-         <property name="rightMargin">
-          <number>0</number>
-         </property>
-         <property name="bottomMargin">
-          <number>0</number>
-         </property>
-         <item>
-          <widget class="QLabel" name="rp3Label">
-           <property name="text">
-            <string>Idle Image 3</string>
-           </property>
-           <property name="wordWrap">
-            <bool>false</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QLineEdit" name="repeaterImage3LineEdit">
-           <property name="modified">
-            <bool>false</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QPushButton" name="rp3BrowseButton">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="text">
-            <string>Browse ...</string>
-           </property>
-          </widget>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <layout class="QHBoxLayout">
-         <property name="spacing">
-          <number>6</number>
-         </property>
-         <property name="leftMargin">
-          <number>0</number>
-         </property>
-         <property name="topMargin">
-          <number>0</number>
-         </property>
-         <property name="rightMargin">
-          <number>0</number>
-         </property>
-         <property name="bottomMargin">
-          <number>0</number>
-         </property>
-         <item>
-          <widget class="QLabel" name="rp4Label">
-           <property name="text">
-            <string>Idle Image 4</string>
-           </property>
-           <property name="wordWrap">
-            <bool>false</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QLineEdit" name="repeaterImage4LineEdit">
-           <property name="modified">
-            <bool>false</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QPushButton" name="rp4BrowseButton">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="text">
-            <string>Browse ...</string>
-           </property>
-          </widget>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <layout class="QHBoxLayout" name="horizontalLayout_6">
-         <item>
-          <widget class="QLabel" name="Label">
-           <property name="text">
-            <string>Idle Template</string>
-           </property>
-           <property name="wordWrap">
-            <bool>false</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QLineEdit" name="idleTemplateLineEdit"/>
-         </item>
-         <item>
-          <widget class="QPushButton" name="idleTemplateBrowseButton">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="text">
-            <string>Browse ...</string>
-           </property>
-          </widget>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <layout class="QHBoxLayout" name="horizontalLayout_7">
-         <item>
-          <widget class="QLabel" name="ackLabel">
-           <property name="text">
-            <string>Repeater Template</string>
-           </property>
-           <property name="wordWrap">
-            <bool>false</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QLineEdit" name="repeaterTemplateLineEdit"/>
-         </item>
-         <item>
-          <widget class="QPushButton" name="repeaterTemplateBrowseButton">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="text">
-            <string>Browse ...</string>
-           </property>
-          </widget>
-         </item>
-        </layout>
-       </item>
-      </layout>
-     </widget>
-     <widget class="QWidget" name="tb7">
-      <attribute name="title">
-       <string>FTP</string>
-      </attribute>
-      <layout class="QVBoxLayout" name="verticalLayout_9">
-       <item>
-        <layout class="QHBoxLayout">
-         <property name="spacing">
-          <number>6</number>
-         </property>
-         <property name="leftMargin">
-          <number>0</number>
-         </property>
-         <property name="topMargin">
-          <number>0</number>
-         </property>
-         <property name="rightMargin">
-          <number>0</number>
-         </property>
-         <property name="bottomMargin">
-          <number>0</number>
-         </property>
-         <item>
-          <widget class="QCheckBox" name="enableFTPCheckBox">
-           <property name="text">
-            <string>Enable File Upload to FTP Server</string>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <spacer>
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeType">
-            <enum>QSizePolicy::Expanding</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>20</width>
-             <height>20</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
-         <item>
-          <widget class="QLabel" name="ftpPortLabel">
-           <property name="text">
-            <string>FTP Port</string>
-           </property>
-           <property name="wordWrap">
-            <bool>false</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QSpinBox" name="ftpPortSpinBox">
-           <property name="minimum">
-            <number>1</number>
-           </property>
-           <property name="maximum">
-            <number>10000</number>
-           </property>
-           <property name="value">
-            <number>21</number>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <spacer>
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeType">
-            <enum>QSizePolicy::Expanding</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>20</width>
-             <height>20</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
-         <item>
-          <widget class="QLabel" name="defaultImageModeLabel">
-           <property name="text">
-            <string>Default Image Format</string>
-           </property>
-           <property name="wordWrap">
-            <bool>false</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QComboBox" name="ftpDefaultImageFormatComboBox"/>
-         </item>
-         <item>
-          <spacer>
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeType">
-            <enum>QSizePolicy::Preferred</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>20</width>
-             <height>20</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <layout class="QHBoxLayout">
-         <property name="spacing">
-          <number>6</number>
-         </property>
-         <property name="leftMargin">
-          <number>0</number>
-         </property>
-         <property name="topMargin">
-          <number>0</number>
-         </property>
-         <property name="rightMargin">
-          <number>0</number>
-         </property>
-         <property name="bottomMargin">
-          <number>0</number>
-         </property>
-         <item>
-          <widget class="QLabel" name="remoteHostLabel">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="minimumSize">
-            <size>
-             <width>145</width>
-             <height>25</height>
-            </size>
-           </property>
-           <property name="text">
-            <string>Remote Hostname</string>
-           </property>
-           <property name="wordWrap">
-            <bool>false</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QLineEdit" name="remoteHostLineEdit"/>
-         </item>
-         <item>
-          <spacer>
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeType">
-            <enum>QSizePolicy::Preferred</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>20</width>
-             <height>20</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <layout class="QHBoxLayout">
-         <property name="spacing">
-          <number>6</number>
-         </property>
-         <property name="leftMargin">
-          <number>0</number>
-         </property>
-         <property name="topMargin">
-          <number>0</number>
-         </property>
-         <property name="rightMargin">
-          <number>0</number>
-         </property>
-         <property name="bottomMargin">
-          <number>0</number>
-         </property>
-         <item>
-          <widget class="QLabel" name="remoteDirectoryLabel">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="minimumSize">
-            <size>
-             <width>145</width>
-             <height>25</height>
-            </size>
-           </property>
-           <property name="text">
-            <string>Remote Directory</string>
-           </property>
-           <property name="wordWrap">
-            <bool>false</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QLineEdit" name="remoteDirectoryLineEdit"/>
-         </item>
-         <item>
-          <spacer>
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeType">
-            <enum>QSizePolicy::Preferred</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>20</width>
-             <height>20</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <layout class="QHBoxLayout">
-         <property name="spacing">
-          <number>6</number>
-         </property>
-         <property name="leftMargin">
-          <number>0</number>
-         </property>
-         <property name="topMargin">
-          <number>0</number>
-         </property>
-         <property name="rightMargin">
-          <number>0</number>
-         </property>
-         <property name="bottomMargin">
-          <number>0</number>
-         </property>
-         <item>
-          <widget class="QLabel" name="ftploginLabel">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="minimumSize">
-            <size>
-             <width>145</width>
-             <height>25</height>
-            </size>
-           </property>
-           <property name="text">
-            <string>FTP Loginname</string>
-           </property>
-           <property name="wordWrap">
-            <bool>false</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QLineEdit" name="ftpLoginLineEdit"/>
-         </item>
-         <item>
-          <spacer>
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeType">
-            <enum>QSizePolicy::Preferred</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>20</width>
-             <height>20</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <layout class="QHBoxLayout">
-         <property name="spacing">
-          <number>6</number>
-         </property>
-         <property name="leftMargin">
-          <number>0</number>
-         </property>
-         <property name="topMargin">
-          <number>0</number>
-         </property>
-         <property name="rightMargin">
-          <number>0</number>
-         </property>
-         <property name="bottomMargin">
-          <number>0</number>
-         </property>
-         <item>
-          <widget class="QLabel" name="passwordLabel">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="minimumSize">
-            <size>
-             <width>145</width>
-             <height>25</height>
-            </size>
-           </property>
-           <property name="text">
-            <string>FTP Password</string>
-           </property>
-           <property name="wordWrap">
-            <bool>false</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QLineEdit" name="ftpPasswordLineEdit">
-           <property name="echoMode">
-            <enum>QLineEdit::Password</enum>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <spacer>
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeType">
-            <enum>QSizePolicy::Preferred</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>20</width>
-             <height>20</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <widget class="QGroupBox" name="groupBox">
-         <property name="title">
-          <string>Image store</string>
-         </property>
-         <layout class="QVBoxLayout" name="verticalLayout_8">
-          <item>
-           <layout class="QHBoxLayout" name="horizontalLayout_3">
-            <item>
-             <widget class="QRadioButton" name="imageRadioButton">
-              <property name="text">
-               <string>image1 to image</string>
-              </property>
-             </widget>
-            </item>
-            <item>
-             <widget class="QSpinBox" name="ftpNumImagesSpinBox">
-              <property name="minimum">
-               <number>1</number>
-              </property>
-              <property name="maximum">
-               <number>50</number>
-              </property>
-              <property name="value">
-               <number>30</number>
-              </property>
-             </widget>
-            </item>
-            <item>
-             <spacer name="horizontalSpacer">
-              <property name="orientation">
-               <enum>Qt::Horizontal</enum>
-              </property>
-              <property name="sizeHint" stdset="0">
-               <size>
-                <width>40</width>
-                <height>20</height>
-               </size>
-              </property>
-             </spacer>
-            </item>
-           </layout>
-          </item>
-          <item>
-           <widget class="QRadioButton" name="filenameRadioButton">
-            <property name="text">
-             <string>filename</string>
-            </property>
-           </widget>
-          </item>
-         </layout>
-        </widget>
-       </item>
-       <item>
-        <layout class="QHBoxLayout" name="horizontalLayout" stretch="1,0">
-         <item>
-          <widget class="QLabel" name="label_2">
-           <property name="text">
-            <string>This ftp server is used to upload your received pictures. You can save them as a rotating sequence of images (image1 being the latest and image30 being the oldest) or simply under their own filename.</string>
-           </property>
-           <property name="wordWrap">
-            <bool>true</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QPushButton" name="testFTPPushButton">
-           <property name="text">
-            <string>Test connection</string>
-           </property>
-          </widget>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <spacer>
-         <property name="orientation">
-          <enum>Qt::Vertical</enum>
-         </property>
-         <property name="sizeType">
-          <enum>QSizePolicy::Expanding</enum>
-         </property>
-         <property name="sizeHint" stdset="0">
-          <size>
-           <width>20</width>
-           <height>66</height>
-          </size>
-         </property>
-        </spacer>
-       </item>
-      </layout>
-     </widget>
-     <widget class="QWidget" name="tb8">
-      <attribute name="title">
-       <string>Camera</string>
-      </attribute>
-      <layout class="QVBoxLayout">
-       <item>
-        <layout class="QHBoxLayout">
-         <item>
-          <widget class="QLabel" name="videoDeviceLabel">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="minimumSize">
-            <size>
-             <width>145</width>
-             <height>25</height>
-            </size>
-           </property>
-           <property name="text">
-            <string>Video device</string>
-           </property>
-           <property name="wordWrap">
-            <bool>false</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QLineEdit" name="videoDeviceLineEdit"/>
-         </item>
-         <item>
-          <spacer>
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeType">
-            <enum>QSizePolicy::Expanding</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>245</width>
-             <height>20</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <layout class="QHBoxLayout">
-         <item>
-          <widget class="QLabel" name="colorFormatLabel">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="minimumSize">
-            <size>
-             <width>145</width>
-             <height>25</height>
-            </size>
-           </property>
-           <property name="text">
-            <string>Color Format</string>
-           </property>
-           <property name="alignment">
-            <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
-           </property>
-           <property name="wordWrap">
-            <bool>false</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QComboBox" name="colorFormatComboBox"/>
-         </item>
-         <item>
-          <spacer>
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeType">
-            <enum>QSizePolicy::Expanding</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>221</width>
-             <height>20</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <layout class="QHBoxLayout">
-         <item>
-          <widget class="QLabel" name="sizeLabel">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="minimumSize">
-            <size>
-             <width>145</width>
-             <height>25</height>
-            </size>
-           </property>
-           <property name="text">
-            <string>Size</string>
-           </property>
-           <property name="alignment">
-            <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
-           </property>
-           <property name="wordWrap">
-            <bool>false</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QComboBox" name="sizeComboBox"/>
-         </item>
-         <item>
-          <spacer>
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeType">
-            <enum>QSizePolicy::Expanding</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>131</width>
-             <height>20</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <layout class="QHBoxLayout">
-         <item>
-          <widget class="QLabel" name="channelLabel">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="minimumSize">
-            <size>
-             <width>145</width>
-             <height>25</height>
-            </size>
-           </property>
-           <property name="text">
-            <string>Channel</string>
-           </property>
-           <property name="alignment">
-            <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
-           </property>
-           <property name="wordWrap">
-            <bool>false</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QSpinBox" name="channelSpinBox">
-           <property name="maximum">
-            <number>8</number>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <spacer>
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeType">
-            <enum>QSizePolicy::Expanding</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>399</width>
-             <height>20</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <spacer>
-         <property name="orientation">
-          <enum>Qt::Vertical</enum>
-         </property>
-         <property name="sizeType">
-          <enum>QSizePolicy::Expanding</enum>
-         </property>
-         <property name="sizeHint" stdset="0">
-          <size>
-           <width>21</width>
-           <height>50</height>
-          </size>
-         </property>
-        </spacer>
-       </item>
-      </layout>
-     </widget>
-     <widget class="QWidget" name="tb9">
-      <attribute name="title">
-       <string>Waterfall</string>
-      </attribute>
-      <layout class="QVBoxLayout" name="verticalLayout_5">
-       <item>
-        <layout class="QHBoxLayout" name="horizontalLayout_12" stretch="0,1">
-         <item>
-          <layout class="QGridLayout" name="gridLayout">
-           <item row="0" column="0">
-            <widget class="QLabel" name="pictureLabel">
-             <property name="sizePolicy">
-              <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-               <horstretch>0</horstretch>
-               <verstretch>0</verstretch>
-              </sizepolicy>
-             </property>
-             <property name="minimumSize">
-              <size>
-               <width>145</width>
-               <height>25</height>
-              </size>
-             </property>
-             <property name="text">
-              <string>Start Picture</string>
-             </property>
-             <property name="wordWrap">
-              <bool>false</bool>
-             </property>
-            </widget>
-           </item>
-           <item row="0" column="1">
-            <widget class="QPlainTextEdit" name="startPicTextEdit"/>
-           </item>
-           <item row="1" column="0">
-            <widget class="QLabel" name="pictureLabel_2">
-             <property name="sizePolicy">
-              <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-               <horstretch>0</horstretch>
-               <verstretch>0</verstretch>
-              </sizepolicy>
-             </property>
-             <property name="minimumSize">
-              <size>
-               <width>145</width>
-               <height>25</height>
-              </size>
-             </property>
-             <property name="text">
-              <string>End Picture</string>
-             </property>
-             <property name="wordWrap">
-              <bool>false</bool>
-             </property>
-            </widget>
-           </item>
-           <item row="1" column="1">
-            <widget class="QPlainTextEdit" name="endPicTextEdit"/>
-           </item>
-           <item row="2" column="0">
-            <widget class="QLabel" name="fixLabel">
-             <property name="sizePolicy">
-              <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-               <horstretch>0</horstretch>
-               <verstretch>0</verstretch>
-              </sizepolicy>
-             </property>
-             <property name="minimumSize">
-              <size>
-               <width>145</width>
-               <height>25</height>
-              </size>
-             </property>
-             <property name="text">
-              <string>FIX</string>
-             </property>
-             <property name="wordWrap">
-              <bool>false</bool>
-             </property>
-            </widget>
-           </item>
-           <item row="2" column="1">
-            <widget class="QPlainTextEdit" name="fixTextEdit"/>
-           </item>
-           <item row="3" column="0">
-            <widget class="QLabel" name="nsrLabel">
-             <property name="sizePolicy">
-              <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-               <horstretch>0</horstretch>
-               <verstretch>0</verstretch>
-              </sizepolicy>
-             </property>
-             <property name="minimumSize">
-              <size>
-               <width>145</width>
-               <height>25</height>
-              </size>
-             </property>
-             <property name="text">
-              <string>BSR</string>
-             </property>
-             <property name="wordWrap">
-              <bool>false</bool>
-             </property>
-            </widget>
-           </item>
-           <item row="3" column="1">
-            <widget class="QPlainTextEdit" name="bsrTextEdit"/>
-           </item>
-          </layout>
-         </item>
-         <item>
-          <spacer name="horizontalSpacer_9">
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>40</width>
-             <height>20</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
-        </layout>
-       </item>
-      </layout>
-     </widget>
-     <widget class="QWidget" name="tb10">
-      <attribute name="title">
-       <string>Hybrid</string>
-      </attribute>
-      <layout class="QVBoxLayout" name="verticalLayout_6">
-       <item>
-        <widget class="QCheckBox" name="enableHybridRxCheckBox">
-         <property name="text">
-          <string>Enable Reception in Hybrid Mode </string>
-         </property>
-         <property name="checked">
-          <bool>true</bool>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <layout class="QHBoxLayout" name="_3">
-         <property name="spacing">
-          <number>6</number>
-         </property>
-         <property name="leftMargin">
-          <number>0</number>
-         </property>
-         <property name="topMargin">
-          <number>0</number>
-         </property>
-         <property name="rightMargin">
-          <number>0</number>
-         </property>
-         <property name="bottomMargin">
-          <number>0</number>
-         </property>
-         <item>
-          <widget class="QCheckBox" name="enableSpecialServerCheckBox">
-           <property name="text">
-            <string>Enable Special Server</string>
-           </property>
-           <property name="checked">
-            <bool>true</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <spacer>
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeType">
-            <enum>QSizePolicy::Expanding</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>20</width>
-             <height>20</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
-         <item>
-          <widget class="QLabel" name="ftpPortLabel_2">
-           <property name="text">
-            <string>FTP Port</string>
-           </property>
-           <property name="wordWrap">
-            <bool>false</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QSpinBox" name="hybridFtpPortSpinBox">
-           <property name="minimum">
-            <number>1</number>
-           </property>
-           <property name="maximum">
-            <number>10000</number>
-           </property>
-           <property name="value">
-            <number>21</number>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <spacer>
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeType">
-            <enum>QSizePolicy::Preferred</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>20</width>
-             <height>20</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <layout class="QHBoxLayout" name="_2">
-         <property name="spacing">
-          <number>6</number>
-         </property>
-         <property name="leftMargin">
-          <number>0</number>
-         </property>
-         <property name="topMargin">
-          <number>0</number>
-         </property>
-         <property name="rightMargin">
-          <number>0</number>
-         </property>
-         <property name="bottomMargin">
-          <number>0</number>
-         </property>
-         <item>
-          <widget class="QLabel" name="hybridRemoteHostLabel">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="minimumSize">
-            <size>
-             <width>145</width>
-             <height>25</height>
-            </size>
-           </property>
-           <property name="text">
-            <string>Remote Hostname</string>
-           </property>
-           <property name="wordWrap">
-            <bool>false</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QLineEdit" name="hybridRemoteHostLineEdit"/>
-         </item>
-         <item>
-          <spacer>
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeType">
-            <enum>QSizePolicy::Preferred</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>20</width>
-             <height>20</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <layout class="QHBoxLayout" name="_7">
-         <property name="spacing">
-          <number>6</number>
-         </property>
-         <property name="leftMargin">
-          <number>0</number>
-         </property>
-         <property name="topMargin">
-          <number>0</number>
-         </property>
-         <property name="rightMargin">
-          <number>0</number>
-         </property>
-         <property name="bottomMargin">
-          <number>0</number>
-         </property>
-         <item>
-          <widget class="QLabel" name="hybridFtpLoginLabel">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="minimumSize">
-            <size>
-             <width>145</width>
-             <height>25</height>
-            </size>
-           </property>
-           <property name="text">
-            <string>FTP Loginname</string>
-           </property>
-           <property name="wordWrap">
-            <bool>false</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QLineEdit" name="hybridFtpLoginLineEdit"/>
-         </item>
-         <item>
-          <spacer>
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeType">
-            <enum>QSizePolicy::Preferred</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>20</width>
-             <height>20</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <layout class="QHBoxLayout" name="_6">
-         <property name="spacing">
-          <number>6</number>
-         </property>
-         <property name="leftMargin">
-          <number>0</number>
-         </property>
-         <property name="topMargin">
-          <number>0</number>
-         </property>
-         <property name="rightMargin">
-          <number>0</number>
-         </property>
-         <property name="bottomMargin">
-          <number>0</number>
-         </property>
-         <item>
-          <widget class="QLabel" name="hybridPasswordLabel">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="minimumSize">
-            <size>
-             <width>145</width>
-             <height>25</height>
-            </size>
-           </property>
-           <property name="text">
-            <string>FTP Password</string>
-           </property>
-           <property name="wordWrap">
-            <bool>false</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QLineEdit" name="hybridFtpPasswordLineEdit">
-           <property name="echoMode">
-            <enum>QLineEdit::Password</enum>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <spacer>
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeType">
-            <enum>QSizePolicy::Preferred</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>20</width>
-             <height>20</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <layout class="QHBoxLayout" name="_8">
-         <property name="spacing">
-          <number>6</number>
-         </property>
-         <property name="leftMargin">
-          <number>0</number>
-         </property>
-         <property name="topMargin">
-          <number>0</number>
-         </property>
-         <property name="rightMargin">
-          <number>0</number>
-         </property>
-         <property name="bottomMargin">
-          <number>0</number>
-         </property>
-         <item>
-          <widget class="QLabel" name="hybridRemoteDirectoryLabel">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="minimumSize">
-            <size>
-             <width>145</width>
-             <height>25</height>
-            </size>
-           </property>
-           <property name="text">
-            <string>Remote Directory</string>
-           </property>
-           <property name="wordWrap">
-            <bool>false</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QLineEdit" name="hybridRemoteDirectoryLineEdit"/>
-         </item>
-         <item>
-          <spacer>
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeType">
-            <enum>QSizePolicy::Preferred</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>20</width>
-             <height>20</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <layout class="QHBoxLayout" name="_9">
-         <property name="spacing">
-          <number>6</number>
-         </property>
-         <property name="leftMargin">
-          <number>0</number>
-         </property>
-         <property name="topMargin">
-          <number>0</number>
-         </property>
-         <property name="rightMargin">
-          <number>0</number>
-         </property>
-         <property name="bottomMargin">
-          <number>0</number>
-         </property>
-         <item>
-          <widget class="QLabel" name="hybridRemoteDirectoryLabel_2">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="minimumSize">
-            <size>
-             <width>145</width>
-             <height>25</height>
-            </size>
-           </property>
-           <property name="text">
-            <string>Hybrid Files Directory</string>
-           </property>
-           <property name="wordWrap">
-            <bool>false</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QLineEdit" name="hybridFilesDirectoryLineEdit"/>
-         </item>
-         <item>
-          <spacer>
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeType">
-            <enum>QSizePolicy::Preferred</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>20</width>
-             <height>20</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <layout class="QHBoxLayout" name="horizontalLayout_2" stretch="1,0">
-         <item>
-          <widget class="QLabel" name="label">
-           <property name="text">
-            <string>By default all hybrid files are uploaded to a default server ("Enable Special Server"  not checked). If you wish to use your own server for sending in Hybrid mode then  you need to check "Enable Special Server" and fill in the details. See manual for more information.</string>
-           </property>
-           <property name="wordWrap">
-            <bool>true</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QPushButton" name="testHybridPushButton">
-           <property name="text">
-            <string>Test connection</string>
-           </property>
-          </widget>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <spacer name="spacer">
-         <property name="orientation">
-          <enum>Qt::Vertical</enum>
-         </property>
-         <property name="sizeType">
-          <enum>QSizePolicy::Expanding</enum>
-         </property>
-         <property name="sizeHint" stdset="0">
-          <size>
-           <width>20</width>
-           <height>191</height>
-          </size>
-         </property>
-        </spacer>
-       </item>
-      </layout>
-     </widget>
-     <widget class="QWidget" name="drmPFTab">
-      <attribute name="title">
-       <string>DRM Profiles</string>
-      </attribute>
-      <layout class="QVBoxLayout" name="verticalLayout_7">
-       <item>
-        <widget class="drmProfileForm" name="drmProfileWidget" native="true"/>
-       </item>
-      </layout>
-     </widget>
-    </widget>
-   </item>
-   <item>
-    <layout class="QHBoxLayout">
-     <property name="spacing">
-      <number>2</number>
-     </property>
-     <property name="leftMargin">
-      <number>0</number>
-     </property>
-     <property name="topMargin">
-      <number>0</number>
-     </property>
-     <property name="rightMargin">
-      <number>0</number>
-     </property>
-     <property name="bottomMargin">
-      <number>0</number>
-     </property>
-     <item>
-      <spacer>
-       <property name="orientation">
-        <enum>Qt::Horizontal</enum>
-       </property>
-       <property name="sizeType">
-        <enum>QSizePolicy::Expanding</enum>
-       </property>
-       <property name="sizeHint" stdset="0">
-        <size>
-         <width>20</width>
-         <height>20</height>
-        </size>
-       </property>
-      </spacer>
-     </item>
-     <item>
-      <widget class="QPushButton" name="okButton">
-       <property name="font">
-        <font/>
-       </property>
-       <property name="text">
-        <string>OK</string>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <spacer>
-       <property name="orientation">
-        <enum>Qt::Horizontal</enum>
-       </property>
-       <property name="sizeType">
-        <enum>QSizePolicy::Expanding</enum>
-       </property>
-       <property name="sizeHint" stdset="0">
-        <size>
-         <width>20</width>
-         <height>20</height>
-        </size>
-       </property>
-      </spacer>
-     </item>
-     <item>
-      <widget class="QPushButton" name="cancelButton">
-       <property name="font">
-        <font/>
-       </property>
-       <property name="text">
-        <string>Cancel</string>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <spacer>
-       <property name="orientation">
-        <enum>Qt::Horizontal</enum>
-       </property>
-       <property name="sizeType">
-        <enum>QSizePolicy::Expanding</enum>
-       </property>
-       <property name="sizeHint" stdset="0">
-        <size>
-         <width>20</width>
-         <height>20</height>
-        </size>
-       </property>
-      </spacer>
-     </item>
-    </layout>
-   </item>
-  </layout>
- </widget>
- <layoutdefault spacing="6" margin="11"/>
- <pixmapfunction>qPixmapFromMimeSource</pixmapfunction>
- <customwidgets>
-  <customwidget>
-   <class>soundControl</class>
-   <extends>QWidget</extends>
-   <header>sound/soundcontrol.h</header>
-   <container>1</container>
-  </customwidget>
-  <customwidget>
-   <class>rigControlForm</class>
-   <extends>QWidget</extends>
-   <header>rig/rigcontrolform.h</header>
-   <container>1</container>
-  </customwidget>
-  <customwidget>
-   <class>drmProfileForm</class>
-   <extends>QWidget</extends>
-   <header>drmprofileform.h</header>
-   <container>1</container>
-  </customwidget>
- </customwidgets>
- <resources/>
- <connections>
-  <connection>
-   <sender>okButton</sender>
-   <signal>clicked()</signal>
-   <receiver>configForm</receiver>
-   <slot>accept()</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>20</x>
-     <y>20</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>20</x>
-     <y>20</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
-   <sender>cancelButton</sender>
-   <signal>clicked()</signal>
-   <receiver>configForm</receiver>
-   <slot>reject()</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>20</x>
-     <y>20</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>20</x>
-     <y>20</y>
-    </hint>
-   </hints>
-  </connection>
- </connections>
-</ui>
diff --git a/qsstv/configparams.cpp b/qsstv/configparams.cpp
deleted file mode 100644
index 14bcfcb..0000000
--- a/qsstv/configparams.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-/**************************************************************************
-*   Copyright (C) 2000-2012 by Johan Maes                                 *
-*   on4qz at telenet.be                                                      *
-*   http://users.telenet.be/on4qz                                         *
-*                                                                         *
-*   This program is free software; you can redistribute it and/or modify  *
-*   it under the terms of the GNU General Public License as published by  *
-*   the Free Software Foundation; either version 2 of the License, or     *
-*   (at your option) any later version.                                   *
-*                                                                         *
-*   This program is distributed in the hope that it will be useful,       *
-*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
-*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
-*   GNU General Public License for more details.                          *
-*                                                                         *
-*   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.,                                       *
-*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
-***************************************************************************/
-#include "configparams.h"
-
-QString rxImagesPath; //!< path to the received images directory
-QString txImagesPath; //!< path to the transmit images directory
-QString templatesPath; //!< path to the templates directory
-QString audioPath; //!< directory path to the audio files
-QString docURL; //!< url of documentation
-QString defaultImageFormat; //!< the default format for to save the image in (e.g. png, jpg ..)
-//QString fontString;
-//int fontSize;
-int samplingrate; //!< samplingrate of the souncard (the nominal sampling frequency i.e. 8000, 11025 ...)
-double rxClock;   //!< adjusted receive Clock
-double txClock;	 //!< adjusted transmit Clock
-
-QString serialPort;
-QString pttSerialPort;
-QString radioModel;
-int radioModelNumber;
-int civAddress;
-int baudrate;
-QString parity;
-int stopbits;
-int databits;
-QString handshake;
-bool enableCAT;
-//bool enableSerialPTT;
-QString cwText; //!< message to send in CW after sending the image
-int cwTone; //!< frequency of the CW signal
-int cwWPM; //!< CW words per minute
-
-bool enableFTP;
-int ftpPort;
-QString ftpRemoteHost;
-QString ftpRemoteDirectory;
-QString ftpLogin;
-QString ftpPassword;
-QString ftpFilename;
-QString ftpDefaultImageFormat;
-eftpSaveFormat ftpSaveFormat;
-int ftpNumImages;
-
-
-bool enableHybridRx;
-bool enableSpecialServer;
-int hybridFtpPort;
-QString hybridFtpRemoteHost;
-QString hybridFtpRemoteDirectory;
-QString hybridFtpHybridFilesDirectory;
-QString hybridFtpLogin;
-QString hybridFtpPassword;
-bool useHybrid;
-
-int repeaterImageInterval;
-bool repeaterEnable;
-esstvMode repeaterTxMode;
-QString repeaterImage1;
-QString repeaterImage2;
-QString repeaterImage3;
-QString repeaterImage4;
-QString idleTemplate;
-QString repeaterTemplate;
-QString repeaterAcknowledge;
-
-
-
-QString myCallsign;
-QString myQth;
-QString myLocator;
-QString myLastname;
-QString myFirstname;
-
-QString startPicWF;
-QString endPicWF;
-QString fixWF;
-QString bsrWF;
-
-
-QString drmCallsign;
-drmProfileForm *drmProfilePtr;
-
-
-
-QString videoDevice;
-//int framesPerSecondIndex;
-int colorFormatIndex;
-int sizeIndex;
-int channelNumber;
-etransmissionMode transmissionModeIndex;  // SSTV or DRM or FAX
-unsigned int dataScopeOffset;
-
diff --git a/qsstv/configparams.h b/qsstv/configparams.h
deleted file mode 100644
index 8b99e30..0000000
--- a/qsstv/configparams.h
+++ /dev/null
@@ -1,91 +0,0 @@
-#ifndef CONFIGPARAMS_H
-#define CONFIGPARAMS_H
-#include "sstv/sstvparam.h"
-#include "drmprofileform.h"
-#include <QString>
-
-
-extern QString rxImagesPath;
-extern QString txImagesPath;
-extern QString templatesPath;
-extern QString audioPath;
-extern QString docURL;
-extern QString defaultImageFormat;
-//extern QString fontString;
-//extern int fontSize;
-extern int samplingrate;
-extern double rxClock;
-extern double txClock;
-extern QString serialPort; /**<  serial port device*/
-extern QString radioModel;
-extern int radioModelNumber;
-extern int civAddress;
-extern int baudrate; /**<  serial port baudrate*/
-extern QString parity;
-extern int stopbits;
-extern int databits;
-extern QString handshake;
-extern bool enableCAT;
-//extern bool enableSerialPTT;
-extern QString pttSerialPort;
-
-
-extern QString myCallsign;
-extern QString myQth;
-extern QString myLocator;
-extern QString myLastname;
-extern QString myFirstname;
-
-extern QString cwText;
-extern int cwTone;
-extern int cwWPM;
-
-
-extern bool enableFTP;
-extern int ftpPort;
-extern QString ftpRemoteHost;
-extern QString ftpRemoteDirectory;
-extern QString ftpLogin;
-extern QString ftpPassword;
-extern QString ftpFilename;
-extern QString ftpDefaultImageFormat;
-extern int ftpNumImages;
-extern bool enableHybridRx;
-extern bool enableSpecialServer;
-extern int hybridFtpPort;
-extern QString hybridFtpRemoteHost;
-extern QString hybridFtpRemoteDirectory;
-extern QString hybridFtpHybridFilesDirectory;
-
-extern QString hybridFtpLogin;
-extern QString hybridFtpPassword;
-extern bool useHybrid;
-enum eftpSaveFormat {FTPIM,FTPFILE};
-extern eftpSaveFormat ftpSaveFormat;
-extern bool repeaterEnable;
-extern int repeaterImageInterval;
-extern esstvMode repeaterTxMode;
-extern QString repeaterImage1;
-extern QString repeaterImage2;
-extern QString repeaterImage3;
-extern QString repeaterImage4;
-extern QString repeaterAcknowledge;
-extern QString repeaterTemplate;
-extern QString idleTemplate;
-
-extern QString startPicWF;
-extern QString endPicWF;
-extern QString fixWF;
-extern QString bsrWF;
-extern QString drmCallsign;
-extern drmProfileForm *drmProfilePtr;
-
-
-extern QString videoDevice;
-//extern int framesPerSecondIndex;
-extern int colorFormatIndex;
-extern int sizeIndex;
-extern int channelNumber;
-extern etransmissionMode transmissionModeIndex;  // SSTV , DRM or FAX
-extern unsigned int dataScopeOffset;
-#endif // CONFIGPARAMS_H
diff --git a/qsstv/dispatch/dispatcher.cpp b/qsstv/dispatch/dispatcher.cpp
new file mode 100644
index 0000000..c245502
--- /dev/null
+++ b/qsstv/dispatch/dispatcher.cpp
@@ -0,0 +1,445 @@
+/***************************************************************************
+ *   Copyright (C) 2000-2008 by Johan Maes                                 *
+ *   on4qz at telenet.be                                                      *
+ *   http://users.telenet.be/on4qz                                         *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   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.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+/*!
+  The dispatcher is the central system that routes all messages from the different threads.
+It also starts, stops and synchronizes the threads.
+
+*/
+#include "dispatcher.h"
+#include "appglobal.h"
+#include "configparams.h"
+#include "mainwidgets/rxwidget.h"
+#include "mainwidgets/txwidget.h"
+#include "mainwidgets/gallerywidget.h"
+#include "widgets/spectrumwidget.h"
+#include "widgets/vumeter.h"
+#include "rxfunctions.h"
+#include "mainwindow.h"
+#include "utils/ftp.h"
+#include "rigcontrol.h"
+#include "logbook/logbook.h"
+#include "dirdialog.h"
+#include <QSettings>
+#include <QMessageBox>
+
+
+
+/*!
+creates dispatcher instance
+ */
+
+dispatcher::dispatcher()
+{
+  mbox=NULL;
+
+  progressFTP=NULL;
+  lastFileName.clear();
+  prTimerIndex=0;
+}
+
+/*!
+delete dispatcher instance
+ */
+
+dispatcher::~dispatcher()
+{
+
+}
+
+void dispatcher::init()
+{
+  //  if (mbox==NULL)
+  //    {
+  ////      mbox = new QMessageBox(mainWindowPtr);
+  //      mbox = new QMessageBox(0);
+  //    }
+  editorActive=false;
+  infoTextPtr=new textDisplay(mainWindowPtr);
+  mainWindowPtr->spectrumFramePtr->init(RXSTRIPE,1,BASESAMPLERATE/SUBSAMPLINGFACTOR);
+  infoTextPtr->hide();
+
+}
+
+
+/*!
+  All communication between the threads are passed via this eventhandler.
+*/
+
+void dispatcher::customEvent( QEvent * e )
+{
+  dispatchEventType type;
+  QString fn;
+  type=(dispatchEventType)e->type();
+  addToLog(((baseEvent*)e)->description,LOGDISPATCH);
+  switch(type)
+  {
+  case displayFFT:
+    addToLog("dispatcher: displayFFT",LOGDISPATCH);
+    mainWindowPtr->spectrumFramePtr->realFFT(((displayFFTEvent*)e)->data());
+    rxWidgetPtr->vMeterPtr()->setValue(soundIOPtr->getVolumeDb());
+    //      addToLog(QString::number(soundIOPtr->getVolumeDb()),LOGALL);
+
+    break;
+  case displaySync:
+    // addToLog("dispatcher: displaySync",LOGDISPATCH);
+    uint s;
+    ((displaySyncEvent*)e)->getInfo(s);
+    rxWidgetPtr->sMeterPtr()->setValue((double)s);
+    break;
+  case rxSSTVStatus:
+    rxWidgetPtr->setSSTVStatusText(((statusMsgEvent*)e)->getStr());
+    break;
+
+  case startImageRX:
+    addToLog("dispatcher: clearing RxImage",LOGDISPATCH);
+    //      rxWidgetPtr->getImageViewerPtr()->createImage( ((startImageRXEvent*)e)->getSize(),QColor(0,0,128),imageStretch);
+    rxWidgetPtr->getImageViewerPtr()->createImage( ((startImageRXEvent*)e)->getSize(),imageBackGroundColor,imageStretch);
+    break;
+
+  case lineDisplay:
+  {
+    rxWidgetPtr->getImageViewerPtr()->displayImage();
+  }
+    break;
+  case endSSTVImageRX:
+    if(autoSave)
+    {
+      addToLog("dispatcher:endImage savingRxImage",LOGDISPATCH);
+      saveRxSSTVImage(((endImageSSTVRXEvent*)e)->getModeName());
+    }
+    break;
+
+
+  case rxDRMStatus:
+    rxWidgetPtr->setDRMStatusText(((statusMsgEvent*)e)->getStr());
+
+    break;
+  case callEditor:
+    if(editorActive) break;
+    editorActive=true;
+    ed=new editor();
+    ed->show();
+    iv=((callEditorEvent*)e)->getImageViewer();
+    addToLog (QString(" callEditorEvent imageViewPtr: %1").arg(QString::number((ulong)iv,16)),LOGDISPATCH);
+    addToLog(QString("editor: filename %1").arg(((callEditorEvent*)e)->getFilename()),LOGDISPATCH);
+    ed->openFile(((callEditorEvent*)e)->getFilename());
+    break;
+
+  case rxDRMNotify:
+    rxWidgetPtr->setDRMNotifyText(((rxDRMNotifyEvent*)e)->getStr());
+    break;
+  case rxDRMNotifyAppend:
+    rxWidgetPtr->appendDRMNotifyText(((rxDRMNotifyAppendEvent*)e)->getStr());
+    break;
+  case txDRMNotify:
+    txWidgetPtr->setDRMNotifyText(((txDRMNotifyEvent*)e)->getStr());
+    break;
+  case txDRMNotifyAppend:
+    txWidgetPtr->appendDRMNotifyText(((txDRMNotifyAppendEvent*)e)->getStr());
+    break;
+
+
+  case editorFinished:
+    if(!editorActive) break;
+    if(((editorFinishedEvent*)e)->isOK())
+    {
+      addToLog (QString(" editorFinishedEvent imageViewPtr: %1").arg(QString::number((ulong)iv,16)),LOGDISPATCH);
+      iv->reload();
+    }
+    editorActive=false;
+    delete ed;
+    break;
+
+  case templatesChanged:
+    galleryWidgetPtr->changedMatrix(imageViewer::TEMPLATETHUMB);
+    txWidgetPtr->setupTemplatesComboBox();
+    break;
+
+  case progressTX:
+    txTimeCounter=0;
+    addToLog(QString("dispatcher: progress duration=%1").arg(((progressTXEvent*)e)->getInfo()),LOGDISPATCH);
+    prTimerIndex=startTimer(((progressTXEvent*)e)->getInfo()*10); // time in seconds -> times 1000 for msec,divide by 100 for progress
+    break;
+
+  case stoppingTX:
+    addToLog("dispatcher: endTXImage",LOGDISPATCH);
+    break;
+
+  case endImageTX:
+    //addToLog("dispatcher: endTXImage",LOGDISPATCH);
+    while(soundIOPtr->isPlaying())
+    {
+      qApp->processEvents();
+    }
+    addToLog("dispatcher: endTXImage",LOGDISPATCH);
+    startRX();
+    break;
+
+  case displayDRMInfo:
+    if(!slowCPU)
+    {
+      rxWidgetPtr->mscWdg()->setConstellation(MSC);
+      rxWidgetPtr->facWdg()->setConstellation(FAC);
+    }
+    rxWidgetPtr->statusWdg()->setStatus();
+    break;
+
+  case displayDRMStat:
+    DSPFLOAT s1;
+    ((displayDRMStatEvent*)e)->getInfo(s1);
+    rxWidgetPtr->sMeterPtr()->setValue(s1);
+    break;
+
+  case loadRXImage:
+  {
+    QString fn=((loadRXImageEvent *)e)->getFilename();
+    rxWidgetPtr->getImageViewerPtr()->openImage(fn,false,false,false);
+  }
+    break;
+  case moveToTx:
+  {
+    txWidgetPtr->setImage(((moveToTxEvent *)e)->getFilename());
+  }
+    break;
+  case saveDRMImage:
+  {
+    ((saveDRMImageEvent*)e)->getFilename(fn);
+    if(!rxWidgetPtr->getImageViewerPtr()->openImage(fn,false,false,false))
+    {
+      if(mbox==NULL) delete mbox;
+      mbox = new QMessageBox(mainWindowPtr);
+      mbox->setWindowTitle("Received file");
+      mbox->setText(QString("Saved file %1").arg(fn));
+      mbox->show();
+      QTimer::singleShot(4000, mbox, SLOT(hide()));
+      break;
+    }
+    saveImage(fn);
+  }
+    break;
+
+  case prepareFix:
+    addToLog("prepareFix",LOGDISPATCH);
+    startDRMFIXTx( ((prepareFixEvent*)e)->getData());
+    break;
+  case displayText:
+    infoTextPtr->clear();
+    infoTextPtr->setWindowTitle(QString("Received from %1").arg(drmCallsign));
+    infoTextPtr->append(((displayTextEvent*)e)->getStr());
+    infoTextPtr->show();
+    break;
+
+  case displayMBox:
+    if(mbox==NULL) delete mbox;
+    mbox = new QMessageBox(mainWindowPtr);
+    mbox->setWindowTitle(((displayMBoxEvent*)e)->getTitle());
+    mbox->setText(((displayMBoxEvent*)e)->getStr());
+    mbox->show();
+    QTimer::singleShot(4000, mbox, SLOT(hide()));
+    break;
+
+  case displayProgressFTP:
+  {
+    if(((displayProgressFTPEvent*)e)->getTotal()==0)
+    {
+      delete progressFTP;
+      progressFTP=NULL;
+      break;
+    }
+    if(progressFTP==NULL)
+    {
+      progressFTP=new QProgressDialog("FTP Transfer","Cancel",0,0,mainWindowPtr);
+    }
+    progressFTP->show();
+    progressFTP->setMaximum(((displayProgressFTPEvent*)e)->getTotal());
+    progressFTP->setValue(((displayProgressFTPEvent*)e)->getBytes());
+  }
+    break;
+  default:
+    addToLog(QString("unsupported event: %1").arg(((baseEvent*)e)->description), LOGALL);
+    break;
+  }
+  ((baseEvent *)e)->setDone();
+}
+
+
+void dispatcher::idleAll()
+{
+  if(prTimerIndex>=0)
+  {
+    killTimer(prTimerIndex);
+    prTimerIndex=-1;
+    txWidgetPtr->setProgress(0);
+  }
+  rigControllerPtr->activatePTT(false);
+  rxWidgetPtr->functionsPtr()->stopAndWait();
+  txWidgetPtr->functionsPtr()->stopAndWait();
+}
+
+
+void dispatcher::startRX()
+{
+  idleAll();
+  soundIOPtr->startCapture();
+  rxWidgetPtr->functionsPtr()->startRX();
+}
+
+void dispatcher::startTX(txFunctions::etxState state)
+{
+  idleAll();
+  rigControllerPtr->activatePTT(true);
+  soundIOPtr->startPlayback();
+  txWidgetPtr->functionsPtr()->startTX(state);
+}
+
+void dispatcher::startDRMFIXTx(QByteArray ba)
+{
+  if(!txWidgetPtr->functionsPtr()->prepareFIX(ba)) return;
+  startTX(txFunctions::TXSENDDRMFIX);
+}
+
+void dispatcher::startDRMTxBinary()
+{
+  dirDialog d((QWidget *)mainWindowPtr,"Binary File");
+  QString filename=d.openFileName("","*");
+  if(filename.isEmpty()) return;
+  if(!txWidgetPtr->functionsPtr()->prepareBinary(filename)) return;
+  startTX(txFunctions::TXSENDDRMBINARY);
+}
+
+
+
+void dispatcher::logSSTV(QString call,bool fromFSKID)
+{
+  if(lastFileName.isEmpty())
+  {
+    return;
+  }
+  if(fromFSKID)
+  {
+    QDateTime dt(QDateTime::currentDateTime().toUTC());
+    int diffsec=saveTimeStamp.secsTo(dt);
+    if(diffsec<2)
+    {
+      logBookPtr->logQSO(call,"SSTV",lastFileName);
+    }
+  }
+  else
+  {
+    logBookPtr->logQSO(call,"SSTV","");
+  }
+
+}
+
+
+void dispatcher::saveRxSSTVImage(QString shortModeName)
+{
+  QString s,fileName;
+  QDateTime dt(QDateTime::currentDateTime().toUTC()); //this is compatible with QT 4.6
+  dt.setTimeSpec(Qt::UTC);
+  if (shortModeName.isEmpty())
+  {
+    lastFileName.clear();
+    return;
+  }
+  if(!autoSave)
+  {
+    lastFileName=shortModeName;
+  }
+  else
+  {
+    fileName=QString("%1/%2_%3.%4").arg(rxSSTVImagesPath).arg(shortModeName).arg(dt.toString("yyyyMMdd_HHmmss")).arg(defaultImageFormat);
+    addToLog(QString("dispatcher: saveRxImage():%1 ").arg(fileName),LOGDISPATCH);
+    rxWidgetPtr->getImageViewerPtr()->save(fileName,defaultImageFormat,true,false);
+    saveImage(fileName);
+    lastFileName=QString("%1_%2.%3").arg(shortModeName).arg(dt.toString("yyyyMMdd_HHmmss")).arg(defaultImageFormat);
+    saveTimeStamp= dt;
+  }
+}
+
+void dispatcher::saveImage(QString fileName)
+{
+  QFileInfo info(fileName);
+  eftpError ftpResult;
+  displayMBoxEvent *stmb=0;
+  QString fn="/tmp/"+info.baseName()+"."+ftpDefaultImageFormat;
+  galleryWidgetPtr->putRxImage(fileName);
+  txWidgetPtr->setPreviewWidget(fileName);
+  if(enableFTP)
+  {
+    ftpInterface ftpIntf("Save RX Image");
+
+    if(transmissionModeIndex==TRXSSTV)
+    {
+      rxWidgetPtr->getImageViewerPtr()->save(fn,ftpDefaultImageFormat,true,false);
+      ftpIntf.setupConnection(ftpRemoteHost,ftpPort,ftpLogin,ftpPassword,ftpRemoteSSTVDirectory);
+    }
+    else
+    {
+      rxWidgetPtr->getImageViewerPtr()->save(fn,ftpDefaultImageFormat,true,true);
+      ftpIntf.setupConnection(ftpRemoteHost,ftpPort,ftpLogin,ftpPassword,ftpRemoteDRMDirectory); // TO CHECK JOMA
+    }
+    ftpResult=ftpIntf.uploadToRXServer(fn);
+    switch(ftpResult)
+    {
+    case FTPOK:
+      break;
+    case FTPERROR:
+      stmb= new displayMBoxEvent("FTP Error",QString("Host: %1: %2").arg(ftpRemoteHost).arg(ftpIntf.getLastError()));
+      break;
+    case FTPNAMEERROR:
+      stmb= new displayMBoxEvent("FTP Error",QString("Host: %1, Error in filename").arg(ftpRemoteHost));
+      break;
+    case FTPCANCELED:
+      stmb= new displayMBoxEvent("FTP Error",QString("Connection to %1 Canceled").arg(ftpRemoteHost));
+      break;
+    case FTPTIMEOUT:
+      stmb= new displayMBoxEvent("FTP Error",QString("Connection to %1 timed out").arg(ftpRemoteHost));
+      break;
+    }
+    if(ftpResult!=FTPOK)
+    {
+      QApplication::postEvent( dispatcherPtr, stmb );  // Qt will delete it when done
+      return;
+    }
+
+  }
+}
+
+
+
+void dispatcher::timerEvent(QTimerEvent *event)
+{
+  if(event->timerId()==prTimerIndex)
+  {
+    txWidgetPtr->setProgress(++txTimeCounter);
+    if(txTimeCounter>=100)
+    {
+      if(prTimerIndex>=0)
+      {
+        killTimer(prTimerIndex);
+        prTimerIndex=-1;
+        txWidgetPtr->setProgress(0);
+      }
+    }
+    txWidgetPtr->setProgress(txTimeCounter);
+  }
+}
diff --git a/qsstv/dispatcher.h b/qsstv/dispatch/dispatcher.h
similarity index 78%
rename from qsstv/dispatcher.h
rename to qsstv/dispatch/dispatcher.h
index e9b4ca7..b89d16f 100644
--- a/qsstv/dispatcher.h
+++ b/qsstv/dispatch/dispatcher.h
@@ -21,9 +21,10 @@
 #ifndef DISPATCHER_H
 #define DISPATCHER_H
 #include "dispatchevents.h"
-#include "qsstvglobal.h"
+#include "appglobal.h"
 #include <QByteArray>
-#include "widgets/textdisplay.h"
+#include "textdisplay.h"
+#include "txfunctions.h"
 class editor;
 class imageViewer;
 #include <QProgressDialog>
@@ -40,30 +41,23 @@ public:
 
 	dispatcher();
 	~dispatcher();
-  QString init();
+	void init();
+  void idleAll();
+  void startRX();
+  void startTX(txFunctions::etxState state);
   void readSettings();
   void writeSettings();
   void customEvent( QEvent * e );
-  void receiveImage();
-  void restartRX();
-  void startSSTVTx();
-  void sendTone(double duration,double freq);
-  void sendWF(QString txt);
-  void startDRMTx();
-  void startDRMBSRTx(QByteArray *ba);
   void startDRMFIXTx(QByteArray ba);
-  void startDRMHybridTx(QString fn);
-  void startDRMHybridText(QString txt);
-  void sendSweepTone(double duration,double lowerFreq,double upperFreq);
-  void startRX(bool st);
-  void startTX(bool st);
-  void stopRX();
-  void stopTX();
-  void stopRXTX();
+  void startDRMTxBinary();
+//  void startDRMHybridTx(QString fn);
+//  void startDRMHybridText(QString txt);
+//  void sendSweepTone(double duration,double lowerFreq,double upperFreq);
   void saveImage(QString fileName);
+  void logSSTV(QString call, bool fromFSKID);
+
 private:
-    int serialP;
-    void saveRxSSTVImage();
+    void saveRxSSTVImage(QString shortModeName);
     void timerEvent(QTimerEvent *event);
     bool editorActive;
     editor *ed;
@@ -71,10 +65,11 @@ private:
     int txTimeCounter;
     int prTimerIndex;
     int logTimerIndex;
-    bool restartRXFlag;
     textDisplay *infoTextPtr;
     QMessageBox *mbox;
     QProgressDialog *progressFTP;
+    QString lastFileName;
+    QDateTime saveTimeStamp;
 };
 #endif
 
diff --git a/qsstv/dispatch/dispatchevents.h b/qsstv/dispatch/dispatchevents.h
new file mode 100644
index 0000000..37d8037
--- /dev/null
+++ b/qsstv/dispatch/dispatchevents.h
@@ -0,0 +1,644 @@
+/***************************************************************************
+ *   Copyright (C) 2000-2008 by Johan Maes                                 *
+ *   on4qz at telenet.be                                                      *
+ *   http://users.telenet.be/on4qz                                         *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   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.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+#ifndef DISPATCHEVENT_H
+#define DISPATCHEVENT_H
+#include <QEvent>
+#include "widgets/imageviewer.h"
+#include "appdefs.h"
+#include <unistd.h>
+
+
+/** dispatch events are used to communicate with the different threads */
+enum dispatchEventType
+{
+    info = QEvent::User, //!< send when dsp stops running
+    soundcardIdle, //!< send when soundcard stops running
+    displayFFT,
+    displaySync,
+    displayDRMStat,
+    displayDRMInfo,
+    syncDisp,				//!< synchro display event
+    lineDisplay,				//!< display 1 line
+    eraseDisp,
+    createMode,
+    startImageRX,
+    endSSTVImageRX,
+    endImageTX,
+    stoppingTX,
+    progressTX,
+    //  verticalRetrace,
+    //  syncLost,
+    outOfSync,
+    statusMsg,  	//!<  display status message
+    rxSSTVStatus,     //! shows message in sstv tab
+    rxDRMStatus,     //! shows message in drm tab
+    rxDRMNotify,	//! shows text in rx notifications box
+    rxDRMNotifyAppend,
+    txDRMNotify,  //! shows text in tx notifications box
+    txDRMNotifyAppend,
+    closeWindows,
+    callEditor,
+    templatesChanged,
+    editorFinished,
+    changeRXFilter,
+    startAutoRepeater,
+    startRepeater,
+    stopRxTx,
+    loadRXImage,
+    saveDRMImage,
+    prepareFix,
+    displayText,
+    displayMBox,
+    displayProgressFTP,
+    moveToTx
+};
+
+class baseEvent: public QEvent
+{
+public:
+    baseEvent(QEvent::Type t):QEvent(t) {doneIt=NULL;}
+    void waitFor(bool *d) {doneIt=d;}
+    void setDone()
+    {
+        if(doneIt!=NULL) *doneIt=true;
+    }
+    QString description;
+private:
+    bool *doneIt;
+
+};
+
+/**
+  this event is send when the dspfunc thread stops running
+*/
+class infoEvent : public  baseEvent
+{
+public:
+    /** create event */
+    infoEvent(QString t):baseEvent( (QEvent::Type) info ), str(t)
+    {
+        description="infoEvent";
+    }
+    /** returns info string from the event */
+    QString getStr() const { return str; }
+private:
+    QString str;
+};
+
+/**
+  this event is send when the soundcard thread goes to idle
+*/
+class soundcardIdleEvent : public baseEvent
+{
+public:
+    /** create event */
+    soundcardIdleEvent():baseEvent( (QEvent::Type) soundcardIdle )
+    {
+        {
+            description=" soudcardIdleEvent";
+        }
+    }
+};
+
+
+//class rxDataAvailableEvent : public baseEvent
+//{
+//public:
+//	/** create event */
+//	rxDataAvailableEvent(uint idx,uint numSamples):baseEvent( (QEvent::Type)rxData ), index(idx),len(numSamples) {}
+//	/** returns length and pointer  from the event */
+//  uint getIndex(uint &idx) const { idx=index; return len;}
+
+//private:
+//  uint index;
+//	uint len;
+//};
+
+
+/**
+  this event is send with teh sync quality info and the signal volume
+*/
+class displaySyncEvent : public baseEvent
+{
+public:
+    /** create event */
+    displaySyncEvent(uint s):baseEvent( (QEvent::Type) displaySync), sync(s)
+    {
+        description=" displaySyncEvent";
+    }
+    /** returns int sync value */
+    void getInfo(uint &s)  {s=sync;}
+
+private:
+    uint sync;
+    DSPFLOAT vol;
+};
+
+class displayDRMStatEvent  : public baseEvent
+{
+public:
+    /** create event */
+    displayDRMStatEvent(uint s):baseEvent( (QEvent::Type) displayDRMStat), snr(s)
+    {
+        description=" displayDRMStatEvent";
+    }
+    /** returns length and pointer  from the event */
+    void getInfo(DSPFLOAT &s)  {s=snr;}
+
+private:
+    DSPFLOAT snr;
+};
+
+class statusMsgEvent : public baseEvent
+{
+public:
+    /** create event */
+    statusMsgEvent(QString t):baseEvent( (QEvent::Type)statusMsg ), str(t)
+    {
+        description="statusMsgEvent";
+    }
+    /** returns info string from the event */
+    QString getStr() const { return str; }
+private:
+    QString str;
+};
+
+
+
+class rxSSTVStatusEvent : public baseEvent
+{
+public:
+    /** create event */
+    rxSSTVStatusEvent(QString t):baseEvent( (QEvent::Type)rxSSTVStatus ), str(t)
+    {
+        description="rxSSTVStatusEvent";
+    }
+    /** returns info string from the event */
+    QString getStr() const { return str; }
+private:
+    QString str;
+};
+
+class rxDRMStatusEvent : public baseEvent
+{
+public:
+    /** create event */
+    rxDRMStatusEvent(QString t):baseEvent( (QEvent::Type)rxDRMStatus ), str(t)
+    {
+        description="rxDRMStatusEvent";
+    }
+    /** returns info string from the event */
+    QString getStr() const { return str; }
+private:
+    QString str;
+};
+
+class rxDRMNotifyEvent : public baseEvent
+{
+public:
+  /** create event */
+  rxDRMNotifyEvent(QString t):baseEvent( (QEvent::Type)rxDRMNotify ), str(t)
+  {
+    description="rxDRMNotifyEvent";
+  }
+  /** returns info string from the event */
+  QString getStr() const { return str; }
+private:
+  QString str;
+};
+
+class rxDRMNotifyAppendEvent : public baseEvent
+{
+public:
+  /** create event */
+  rxDRMNotifyAppendEvent(QString t):baseEvent( (QEvent::Type)rxDRMNotifyAppend ), str(t)
+  {
+    description="rxDRMNotifyAppendEvent";
+  }
+  /** returns info string from the event */
+  QString getStr() const { return str; }
+private:
+  QString str;
+};
+
+class txDRMNotifyEvent : public baseEvent
+{
+public:
+  /** create event */
+  txDRMNotifyEvent(QString t):baseEvent( (QEvent::Type)txDRMNotify ), str(t)
+  {
+    description="txDRMNotifyEvent";
+  }
+  /** returns info string from the event */
+  QString getStr() const { return str; }
+private:
+  QString str;
+};
+
+class txDRMNotifyAppendEvent : public baseEvent
+{
+public:
+  /** create event */
+  txDRMNotifyAppendEvent(QString t):baseEvent( (QEvent::Type)txDRMNotifyAppend ), str(t)
+  {
+    description="txDRMNotifyAppendEvent";
+  }
+  /** returns info string from the event */
+  QString getStr() const { return str; }
+ private:
+   QString str;
+ };
+
+
+class lineDisplayEvent : public baseEvent
+{
+public:
+    /** create event */
+    lineDisplayEvent(uint lineNbr):baseEvent( (QEvent::Type)lineDisplay ), lineNumber(lineNbr)
+    {
+        description="lineDisplayEvent";
+    }
+    /** returns length and pointer  from the event */
+    void getInfo(uint &lineNbr) const { lineNbr=lineNumber;}
+
+private:
+    uint lineNumber;
+};
+
+class eraseDisplayEvent : public baseEvent
+{
+public:
+    /** create event */
+    eraseDisplayEvent():baseEvent( (QEvent::Type)eraseDisp )
+    {
+        description="eraseDisplayEvent";
+    }
+};
+
+
+
+class displayDRMInfoEvent : public baseEvent
+{
+public:
+    /** create event */
+    displayDRMInfoEvent():baseEvent( (QEvent::Type)displayDRMInfo)
+    {
+        description="displayDRMInfo";
+    }
+};
+
+class startAutoRepeaterEvent: public baseEvent
+{
+public:
+    /** create event */
+    startAutoRepeaterEvent():baseEvent( (QEvent::Type)startAutoRepeater )
+    {
+        description="startAutoRepeaterEvent";
+    }
+};
+
+class startRepeaterEvent: public baseEvent
+{
+public:
+    /** create event */
+    startRepeaterEvent():baseEvent( (QEvent::Type)startRepeater )
+    {
+        description="startRepeaterEvent";
+    }
+};
+
+
+class createModeEvent : public baseEvent
+{
+public:
+    /** create event */
+    createModeEvent(uint m,QString t):baseEvent( (QEvent::Type)createMode ), mode(m) ,str(t)
+    {
+        description="createModeEvent";
+    }
+    /** returns info string from the event */
+    void getMode(uint &m,QString &s) const { m=mode;s=str; }
+private:
+    uint mode;
+    QString str;
+};
+
+class loadRXImageEvent : public baseEvent
+{
+public:
+    loadRXImageEvent(QString fn):baseEvent( (QEvent::Type)loadRXImage),fileName(fn)
+    {
+        description="loadRXImageEvent";
+    }
+    QString getFilename() {return fileName;}
+private:
+    QString fileName;
+};
+
+
+class moveToTxEvent : public baseEvent
+{
+public:
+    moveToTxEvent(QString fn):baseEvent( (QEvent::Type)moveToTx),fileName(fn)
+    {
+        description="moveToTxEvent";
+    }
+    QString getFilename() {return fileName;}
+private:
+    QString fileName;
+};
+
+
+
+class saveDRMImageEvent : public baseEvent
+{
+public:
+    saveDRMImageEvent(QString fn):baseEvent( (QEvent::Type)saveDRMImage),fileName(fn)
+    {
+        description="saveDRMImageEvent";
+    }
+    void getFilename(QString &fn) {fn=fileName;}
+private:
+    QString fileName;
+};
+
+
+
+class startImageRXEvent : public baseEvent
+{
+public:
+    /** create event */
+    startImageRXEvent(QSize ims):baseEvent( (QEvent::Type)startImageRX ),imSize(ims)
+    {
+        description="startImageRXEvent";
+    }
+    QSize getSize()  {return imSize;}
+private:
+    QSize imSize;
+
+};
+
+class endImageSSTVRXEvent : public baseEvent
+{
+public:
+    /** create event */
+    endImageSSTVRXEvent(QString mn):baseEvent( (QEvent::Type)endSSTVImageRX ),modeName(mn)
+    {
+        description="endImageSSTVRXEvent";
+    }
+    QString getModeName() {return modeName;}
+private:
+    QString modeName;
+};
+
+class endImageTXEvent : public baseEvent
+{
+public:
+    /** create event */
+    endImageTXEvent():baseEvent( (QEvent::Type)endImageTX )
+    {
+        description="endImageTXEvent";
+    }
+};
+
+
+class stopTXEvent : public baseEvent
+{
+public:
+    /** create event */
+    stopTXEvent():baseEvent( (QEvent::Type)stoppingTX )
+    {
+        description="stopTXEvent";
+    }
+};
+
+//class verticalRetraceEvent : public baseEvent
+//{
+//public:
+//  /** create event */
+//  verticalRetraceEvent():baseEvent( (QEvent::Type) verticalRetrace )
+//  {
+//    description="verticalRetraceEvent";
+//  }
+//};
+
+//class syncLostEvent : public baseEvent
+//{
+//public:
+//  /** create event */
+//  syncLostEvent():baseEvent( (QEvent::Type) syncLost )
+//  {
+//    description="syncLostEvent";
+//  }
+//};
+
+
+
+class outOfSyncEvent : public baseEvent
+{
+public:
+    /** create event */
+    outOfSyncEvent():baseEvent( (QEvent::Type)outOfSync )
+    {
+        description="outOfSyncEvent";
+    }
+};
+
+
+
+class progressTXEvent : public baseEvent
+{
+public:
+    /** create event */
+    progressTXEvent(double tim):baseEvent( (QEvent::Type)progressTX ), txTime(tim)
+    {
+        description="progressTXEvent";
+    }
+    /** returns length and pointer  from the event */
+    double getInfo() { return txTime;}
+
+private:
+    double txTime;
+};
+
+class closeWindowsEvent : public baseEvent
+{
+public:
+    /** create event */
+    closeWindowsEvent():baseEvent( (QEvent::Type)closeWindows)
+    {
+        description="closeWindowEvent";
+    }
+    /** returns length and pointer  from the event */
+};
+
+
+
+class callEditorEvent : public baseEvent
+{
+public:
+    /** create event */
+    callEditorEvent(imageViewer *iv,QString fn):baseEvent( (QEvent::Type) callEditor ), filename(fn),imviewer(iv)
+    {
+        description="callEditorEvent";
+    }
+    /** returns info string from the event */
+    QString getFilename() const { return filename; }
+    imageViewer *getImageViewer() { return imviewer; }
+private:
+    QString filename;
+    imageViewer *imviewer;
+};
+
+
+class templatesChangedEvent : public baseEvent
+{
+public:
+    /** create event */
+    templatesChangedEvent():baseEvent( (QEvent::Type) templatesChanged )
+    {
+        description="templateChangeEvent";
+    }
+};
+
+class editorFinishedEvent : public baseEvent
+{
+public:
+    /** create event */
+    editorFinishedEvent(bool b,QString fn):baseEvent( (QEvent::Type)editorFinished),ok(b),filename(fn)
+    {
+        description="editorFinishedEvent";
+    }
+    bool isOK() { return ok;}
+    QString getFilename() const { return filename; }
+
+private:
+    bool ok;
+    QString filename;
+
+};
+
+
+class displayFFTEvent : public baseEvent
+{
+public:
+    /** create event */
+    displayFFTEvent(DSPFLOAT *buf):baseEvent( (QEvent::Type)displayFFT),buffer(buf)
+    {
+        description="displayFFTEvent";
+    }
+    DSPFLOAT *data() { return buffer;}
+private:
+    DSPFLOAT *buffer;
+
+};
+
+class filterRXChangedEvent: public baseEvent
+{
+public:
+    /** create event */
+    filterRXChangedEvent(int fIndex):baseEvent( (QEvent::Type)changeRXFilter),filterIndex(fIndex)
+    {
+        description="filterChangedEvent";
+    }
+    int index() { return filterIndex;}
+private:
+    int filterIndex;
+};
+
+class stopRxTxEvent : public baseEvent
+{
+public:
+    /** create event */
+    stopRxTxEvent():baseEvent( (QEvent::Type)stopRxTx)
+    {
+        description="stopRxTxEvent";
+    }
+};
+
+
+class prepareFixEvent: public baseEvent
+{
+public:
+    prepareFixEvent(QByteArray ba):baseEvent( (QEvent::Type)prepareFix),data(ba)
+    {
+        description="filterChangedEvent";
+    }
+    QByteArray &getData() {return data;}
+private:
+    QByteArray data;
+};
+
+
+/**
+  this event is send when the dspfunc thread stops running
+*/
+class displayTextEvent : public  baseEvent
+{
+public:
+    /** create event */
+    displayTextEvent(QString t):baseEvent( (QEvent::Type) displayText ), str(t)
+    {
+        description="displayTextEvent";
+    }
+    /** returns info string from the event */
+    QString getStr() const { return str; }
+private:
+    QString str;
+};
+
+class displayMBoxEvent : public  baseEvent
+{
+public:
+    /** create event */
+    displayMBoxEvent(QString title,QString text):baseEvent( (QEvent::Type) displayMBox ), str(text), title(title)
+    {
+        description="displayMBoxEvent";
+    }
+    /** returns info string from the event */
+    QString getStr() const { return str; }
+    QString getTitle() const { return title; }
+
+private:
+    QString str;
+    QString title;
+};
+
+
+class displayProgressFTPEvent : public  baseEvent
+{
+public:
+    /** create event */
+    displayProgressFTPEvent(quint64 byts,quint64 tot):baseEvent( (QEvent::Type) displayProgressFTP ),  bytes(byts),total(tot)
+    {
+        description="displayMBoxEvent";
+    }
+    /** returns info string from the event */
+    quint64 getTotal() const { return total; }
+    quint64 getBytes() const { return bytes; }
+
+private:
+    quint64 bytes;
+    quint64 total;
+
+};
+
+#endif
diff --git a/qsstv/dispatcher.cpp b/qsstv/dispatcher.cpp
deleted file mode 100644
index a665cc2..0000000
--- a/qsstv/dispatcher.cpp
+++ /dev/null
@@ -1,568 +0,0 @@
-/***************************************************************************
- *   Copyright (C) 2000-2008 by Johan Maes                                 *
- *   on4qz at telenet.be                                                      *
- *   http://users.telenet.be/on4qz                                         *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   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.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- ***************************************************************************/
-/*!
-  The dispatcher is the central system that routes all messages from the different threads.
-It also starts, stops and synchronizes the threads.
-
-*/
-#include "dispatcher.h"
-#include "qsstvglobal.h"
-#include "configparams.h"
-#include "rxwidget.h"
-#include "txwidget.h"
-#include "gallerywidget.h"
-#include <QSettings>
-#include "widgets/spectrumwidget.h"
-#include "widgets/vumeter.h"
-
-#include "rig/rigcontrol.h"
-#include "editor/editor.h"
-#include "sound/soundio.h"
-#include "sound/waterfalltext.h"
-#include "mainwindow.h"
-#include "drmrx/drm.h"
-#include "utils/ftp.h"
-#include "utils/hybridcrypt.h"
-
-
-
-
-
-/*!
-creates dispatcher instance
- */
-
-dispatcher::dispatcher()
-{
-  mbox = new QMessageBox(mainWindowPtr);
-  progressFTP=NULL;
-  serialP=0;
-}
-
-/*!
-delete dispatcher instance
- */
-
-dispatcher::~dispatcher()
-{
-  if(serialP!=0)
-    {
-      close(serialP);
-      serialP=0;
-    }
-}
-
-QString dispatcher::init()
-{
-  QString ret;
-  editorActive=false;
-  rxWidgetPtr->fftDisplayPtr()->init(RXSTRIPE,1,BASESAMPLERATE/SUBSAMPLINGRATIO);
-  galleryWidgetPtr->init();
-  rxWidgetPtr->init();
-  txWidgetPtr->init();
-  waterfallPtr=new waterfallText;
-  waterfallPtr->init();
-  if(!rigController->init())
-    {
-      ret=rigController->initError;
-    }
-  restartRXFlag=false;
-  infoTextPtr=new textDisplay(mainWindowPtr);
-  infoTextPtr->hide();
-  return ret;
-}
-
-
-
-void dispatcher::stopRX()
-{
-  rxWidgetPtr->start(false);
-}
-
-void dispatcher::stopTX()
-{
-  rigController->activatePTT(false);
-  txWidgetPtr->start(false);
-}
-
-void dispatcher::stopRXTX()
-{
-  stopRX();
-  stopTX();
-}
-
-void dispatcher::startRX(bool st)
-{
-  stopTX();
-  rxWidgetPtr->start(st);
-  if(st)
-    {
-      addToLog("dispatcher: starting RX",LOGDISPAT);
-    }
-  else
-    {
-      addToLog("dispatcher: stopping RX",LOGDISPAT);
-    }
-}
-
-void dispatcher::startTX(bool st)
-{
-  stopRX();
-  if(st)
-    {
-      addToLog("dispatcher: starting TX",LOGDISPAT);
-    }
-  else
-    {
-      addToLog("dispatcher: stopping TX",LOGDISPAT);
-    }
-  rigController->activatePTT(st);
-  txWidgetPtr->start(st);
-}
-
-
-
-void dispatcher::readSettings()
-{
-  QSettings qSettings;
-  logfile->readSettings(qSettings);
-}
-
-void dispatcher::writeSettings()
-{
-  QSettings qSettings;
-  logfile->writeSettings(qSettings);
-}
-
-/*!
-  All communication between the threads are passed via this eventhandler.
-*/
-
-void dispatcher::customEvent( QEvent * e )
-{
-  dispatchEventType type;
-  QString fn;
-  type=(dispatchEventType)e->type();
-  addToLog(((baseEvent*)e)->description,LOGDISPAT);
-  switch(type)
-    {
-    case displayFFT:
-      addToLog("dispatcher: displayFFT",LOGDISPAT);
-      rxWidgetPtr->fftDisplayPtr()->realFFT(((displayFFTEvent*)e)->data());
-      rxWidgetPtr->fftDisplayPtr()->repaint();
-      break;
-    case displaySync:
-      // addToLog("dispatcher: displaySync",LOGDISPAT);
-      uint s;double v;
-      ((displaySyncEvent*)e)->getInfo(s,v);
-      rxWidgetPtr->sMeterPtr()->setValue((double)s);
-      rxWidgetPtr->vMeterPtr()->setValue(v);
-      break;
-    case rxSSTVStatus:
-      rxWidgetPtr->setSSTVStatusText(((statusMsgEvent*)e)->getStr());
-      break;
-    case rxDRMStatus:
-      rxWidgetPtr->setDRMStatusText(((statusMsgEvent*)e)->getStr());
-      break;
-    case startImageRX:
-      addToLog("dispatcher: clearing RxImage",LOGDISPAT);
-      rxWidgetPtr->getImageViewerPtr()->createImage( ((startImageRXEvent*)e)->getSize(),QColor(255,255,0));
-      rxWidgetPtr->getImageViewerPtr()->clear();
-      break;
-    case lineDisplay:
-      {
-        rxWidgetPtr->getImageViewerPtr()->displayImage(false);
-      }
-      break;
-      //    case syncLost:
-      //    case verticalRetrace:
-      //      addToLog("dispatcher: verticalRetrace",LOGDISPAT);
-
-      //      if(autoSave)
-      //        {
-      //          addToLog("dispatcher: verticalRetrace savingRxImage",LOGDISPAT);
-      //          saveRxSSTVImage();
-      //        }
-      //      rxWidgetPtr->functionsPtr()->retraceVertical();
-      //    break;
-    case endImageRX:
-      if(autoSave)
-        {
-          addToLog("dispatcher:endImage savingRxImage",LOGDISPAT);
-          saveRxSSTVImage();
-        }
-      break;
-    case callEditor:
-      if(editorActive) break;
-      editorActive=true;
-      ed=new editor();
-      ed->show();
-      iv=((callEditorEvent*)e)->getImageViewer();
-      addToLog (QString(" callEditorEvent imageViewPtr: %1").arg(QString::number((ulong)iv,16)),LOGDISPAT);
-      addToLog(QString("editor: filename %1").arg(((callEditorEvent*)e)->getFilename()),LOGDISPAT);
-      ed->openFile(((callEditorEvent*)e)->getFilename());
-      break;
-
-    case editorFinished:
-      if(!editorActive) break;
-      if(((editorFinishedEvent*)e)->isOK())
-        {
-          addToLog (QString(" editorFinishedEvent imageViewPtr: %1").arg(QString::number((ulong)iv,16)),LOGDISPAT);
-          iv->reload();
-        }
-      editorActive=false;
-      delete ed;
-      break;
-
-    case templatesChanged:
-      txWidgetPtr->setupTemplatesComboBox();
-      break;
-    case progressTX:
-      txTimeCounter=0;
-      prTimerIndex=startTimer(((progressTXEvent*)e)->getInfo()*10); // time in seconds -> times 1000 for msec,divide by 100 for progress
-      break;
-    case stoppingTX:
-      addToLog("dispatcher: endTXImage",LOGDISPAT);
-      while(!soundIOPtr->stoppedPlaying())
-        {
-          qApp->processEvents();
-        }
-      rigController->activatePTT(false);
-      break;
-
-    case endImageTX:
-      addToLog("dispatcher: endTXImage",LOGDISPAT);
-      while(!soundIOPtr->stoppedPlaying())
-        {
-          qApp->processEvents();
-        }
-      rigController->activatePTT(false);
-      restartRX();
-      break;
-    case displayDRMInfo:
-      //      rxWidgetPtr->psdWdg()->setPSD();
-      rxWidgetPtr->mscWdg()->setConstellation(MSC);
-      rxWidgetPtr->facWdg()->setConstellation(FAC);
-      rxWidgetPtr->statusWdg()->setStatus();
-      break;
-
-    case displayDRMStat:
-      DSPFLOAT s1;DSPFLOAT v1;
-      ((displayDRMStatEvent*)e)->getInfo(s1,v1);
-      rxWidgetPtr->sMeterPtr()->setValue(s1);
-      rxWidgetPtr->vMeterPtr()->setValue(v1);
-      break;
-
-    case loadRXImage:
-      {
-        ((loadRXImageEvent*)e)->getFilename(fn);
-        rxWidgetPtr->getImageViewerPtr()->openImage(fn,true,false);
-      }
-      break;
-
-    case saveDRMImage:
-      {
-        ((saveDRMImageEvent*)e)->getFilename(fn);
-        rxWidgetPtr->getImageViewerPtr()->openImage(fn,true,false);
-        saveImage(fn);
-      }
-      break;
-    case prepareFix:
-      addToLog("prepareFix",LOGDISPAT);
-      startDRMFIXTx( ((prepareFixEvent*)e)->getData());
-      break;
-    case displayText:
-      infoTextPtr->clear();
-      infoTextPtr->setWindowTitle(QString("Received from %1").arg(drmCallsign));
-      infoTextPtr->append(((displayTextEvent*)e)->getStr());
-      infoTextPtr->show();
-
-      break;
-
-    case displayMBox:
-      mbox->setWindowTitle(((displayMBoxEvent*)e)->getTitle());
-      mbox->setText(((displayMBoxEvent*)e)->getStr());
-      mbox->show();
-      QTimer::singleShot(4000, mbox, SLOT(hide()));
-      break;
-    case displayProgressFTP:
-      {
-        if(((displayProgressFTPEvent*)e)->getTotal()==0)
-          {
-            delete progressFTP;
-            progressFTP=NULL;
-            break;
-          }
-        if(progressFTP==NULL)
-          {
-            progressFTP=new QProgressDialog("FTP Transfer","Cancel",0,0,mainWindowPtr);
-          }
-        progressFTP->show();
-        progressFTP->setMaximum(((displayProgressFTPEvent*)e)->getTotal());
-        progressFTP->setValue(((displayProgressFTPEvent*)e)->getBytes());
-      }
-      break;
-    default:
-      addToLog(QString("unsupported event: %1").arg(((baseEvent*)e)->description), LOGALL);
-      break;
-    }
-  ((baseEvent *)e)->setDone();
-}
-
-
-
-void dispatcher::receiveImage()
-{
-}
-
-void dispatcher::restartRX()
-{
-  txTimeCounter=9999999; //force stop timer
-  startRX(true);
-}
-
-void dispatcher::startSSTVTx()
-{
-  stopRX();
-  txWidgetPtr->start(true,false);
-  if(txWidgetPtr->functionsPtr()->getTXState()!=txFunctions::TXIDLE) return;
-  rigController->activatePTT(true);
-  txWidgetPtr->functionsPtr()->setTXState(txFunctions::TXSSTVIMAGE);
-  addToLog("send SSTV Image",LOGDISPAT);
-
-}
-
-void dispatcher::sendTone(double duration,double freq)
-{
-  stopRX();
-  txWidgetPtr->start(true,false);
-  if(txWidgetPtr->functionsPtr()->getTXState()!=txFunctions::TXIDLE) return;
-  txWidgetPtr->functionsPtr()->setToneParam(duration,freq);
-  rigController->activatePTT(true);
-  txWidgetPtr->functionsPtr()->setTXState(txFunctions::TXSENDTONE);
-  addToLog("sendTone",LOGDISPAT);
-}
-
-void dispatcher::sendWF(QString txt)
-{
-  stopRX();
-  txWidgetPtr->start(true,false);
-  if(txWidgetPtr->functionsPtr()->getTXState()!=txFunctions::TXIDLE) return;
-  waterfallPtr->setText(txt);
-  rigController->activatePTT(true);
-  txWidgetPtr->functionsPtr()->setTXState(txFunctions::TXSENDID);
-  addToLog("sendID",LOGDISPAT);
-}
-
-void dispatcher::startDRMTx()
-{
-  stopRX();
-
-  txWidgetPtr->start(true,false);
-  if(txWidgetPtr->functionsPtr()->getTXState()!=txFunctions::TXIDLE) return;
-  //  waterfallPtr->setText(pictureWF);
-  rigController->activatePTT(true);
-  txWidgetPtr->functionsPtr()->setTXState(txFunctions::TXSENDDRM);
-  addToLog("sendDRM",LOGDISPAT);
-}
-
-void dispatcher::startDRMBSRTx(QByteArray *ba)
-{
-  if(ba==NULL) return;
-  stopRX();
-  txWidgetPtr->start(true,false);
-  if(txWidgetPtr->functionsPtr()->getTXState()!=txFunctions::TXIDLE) return;
-  rigController->activatePTT(true);
-  txWidgetPtr->functionsPtr()->initDRMBSR(ba);
-  txWidgetPtr->functionsPtr()->setTXState(txFunctions::TXSENDDRMBSR);
-  addToLog("sendDRMBSR",LOGDISPAT);
-}
-
-void dispatcher::startDRMFIXTx(QByteArray ba)
-{
-  if(!txWidgetPtr->prepareFIX(ba)) return;
-  stopRX();
-  txWidgetPtr->start(true,false);
-  if(txWidgetPtr->functionsPtr()->getTXState()!=txFunctions::TXIDLE) return;
-  rigController->activatePTT(true);
-  txWidgetPtr->functionsPtr()->setTXState(txFunctions::TXSENDDRMFIX);
-  addToLog("sendDRMFIX",LOGDISPAT);
-}
-
-void dispatcher::startDRMHybridTx(QString fn)
-{
-  eftpError ftpResult;
-  QByteArray ba;
-  QTemporaryFile ftmp;
-  ftpInterface ftpIntf("HybridTX");
-  hybridCrypt hc;
-  ftpIntf.setupConnection(hc.host(),hc.port(),hc.user(),hc.passwd(),hc.dir()+"/"+hybridFtpHybridFilesDirectory);
-  //  txWidgetPtr->getImageViewerPtr()->getFilename();
-  txWidgetPtr->getImageViewerPtr()->copyToBuffer(&ba);
-  if(!ftmp.open()) return;
-  ftmp.write(ba);
-  ftmp.close();
-  ftpResult=ftpIntf.uploadFile(ftmp.fileName(),fn,true);
-  switch(ftpResult)
-    {
-    case FTPCANCELED:
-      QMessageBox::information(mainWindowPtr, tr("FTP Info"),"Connection Canceled");
-      return;
-      break;
-    case FTPOK:
-      break;
-    case FTPERROR:
-      QMessageBox::critical(mainWindowPtr, tr("FTP Error"),ftpIntf.getLastError());
-      return;
-      break;
-    case FTPNAMEERROR:
-      QMessageBox::critical(mainWindowPtr, tr("FTP Error"),"Error in filename");
-      return;
-      break;
-    case FTPTIMEOUT:
-      QMessageBox::critical(mainWindowPtr, tr("FTP Error"),"FTP timed out");
-      return;
-      break;
-    }
-  stopRX();
-  txWidgetPtr->start(true,false);
-  if(txWidgetPtr->functionsPtr()->getTXState()!=txFunctions::TXIDLE) return;
-  rigController->activatePTT(true);
-  txWidgetPtr->functionsPtr()->setTXState(txFunctions::TXSENDDRM);
-  addToLog("sendDRMHybrid",LOGDISPAT);
-}
-
-void dispatcher::startDRMHybridText(QString txt)
-{
-  if(!txWidgetPtr->prepareText(txt)) return;
-  stopRX();
-  txWidgetPtr->start(true,false);
-  if(txWidgetPtr->functionsPtr()->getTXState()!=txFunctions::TXIDLE) return;
-  rigController->activatePTT(true);
-  txWidgetPtr->functionsPtr()->setTXState(txFunctions::TXSENDDRMTXT);
-  addToLog("sendDRMTxt",LOGDISPAT);
-}
-
-
-
-void dispatcher::sendSweepTone(double duration,double lowerFreq,double upperFreq)
-{
-  stopRX();
-  txWidgetPtr->start(true,false);
-  txWidgetPtr->functionsPtr()->setToneParam(duration,lowerFreq,upperFreq);
-  rigController->activatePTT(true);
-  txWidgetPtr->functionsPtr()->setTXState(txFunctions::TXSENDTONE);
-  addToLog("sendSweepTone",LOGDISPAT);
-}
-
-
-
-
-void dispatcher::saveRxSSTVImage()
-{
-  if (rxWidgetPtr->functionsPtr()->getModeString().isEmpty()) return;
-  if(!rxWidgetPtr->functionsPtr()->saveOK()) return;
-  QString s,fileName;
-  QDateTime dt(QDateTime::currentDateTime().toUTC()); //this is compatible with QT 4.6
-  dt.setTimeSpec(Qt::UTC);
-  fileName=QString("%1/%2_%3.%4").arg(rxImagesPath).arg(rxWidgetPtr->functionsPtr()->getModeString()).arg(dt.toString("yyyyMMdd_HHmmss")).arg(defaultImageFormat);
-  addToLog(QString("dispatcher: saveRxImage():%1 ").arg(fileName),LOGDISPAT);
-  rxWidgetPtr->getImageViewerPtr()->save(fileName,defaultImageFormat,true);
-  saveImage(fileName);
-}
-
-void dispatcher::saveImage(QString fileName)
-{
-  QImage im;
-  QFileInfo info(fileName);
-  eftpError ftpResult;
-  displayMBoxEvent *stmb=0;
-  QString fn="/tmp/"+info.baseName()+"."+ftpDefaultImageFormat;
-  galleryWidgetPtr->putRxImage(fileName);
-  txWidgetPtr->setPreviewWidget(fileName);
-  if(enableFTP)
-    {
-      ftpInterface ftpIntf("Save RX Image");
-      rxWidgetPtr->getImageViewerPtr()->save(fn,ftpDefaultImageFormat,true);
-      ftpIntf.setupConnection(ftpRemoteHost,ftpPort,ftpLogin,ftpPassword,ftpRemoteDirectory);
-      ftpResult=ftpIntf.uploadToRXServer(fn);
-      switch(ftpResult)
-        {
-        case FTPOK:
-          break;
-        case FTPERROR:
-          stmb= new displayMBoxEvent("FTP Error",QString("Host: %1: %2").arg(ftpRemoteHost).arg(ftpIntf.getLastError()));
-          break;
-        case FTPNAMEERROR:
-          stmb= new displayMBoxEvent("FTP Error",QString("Host: %1, Error in filename").arg(ftpRemoteHost));
-          break;
-        case FTPCANCELED:
-          stmb= new displayMBoxEvent("FTP Error",QString("Connection to %1 Canceled").arg(ftpRemoteHost));
-          break;
-        case FTPTIMEOUT:
-          stmb= new displayMBoxEvent("FTP Error",QString("Connection to %1 timed out").arg(ftpRemoteHost));
-          break;
-        }
-      if(ftpResult!=FTPOK)
-        {
-          QApplication::postEvent( dispatcherPtr, stmb );  // Qt will delete it when done
-          return;
-        }
-
-    }
-}
-
-
-
-void dispatcher::timerEvent(QTimerEvent *event)
-{
-  if(event->timerId()==prTimerIndex)
-    {
-      txWidgetPtr->setProgress(++txTimeCounter);
-      if(txTimeCounter>=100)
-        {
-          if(prTimerIndex>=0)
-            {
-              killTimer(prTimerIndex);
-              prTimerIndex=-1;
-              txWidgetPtr->setProgress(0);
-            }
-        }
-      txWidgetPtr->setProgress(txTimeCounter);
-    }
-  else if(event->timerId()==logTimerIndex)
-    {
-      //      addToLog(QString("dumping dispatcher status"),LOGALL);
-      //      if( rxFuncPtr) rxFuncPtr->logStatus();
-      //      if( txFuncPtr)txFuncPtr->logStatus();
-      //      if( sndIO)sndIO->logStatus();
-    }
-}
-
-
-
-
-
-
-
-
-
-
diff --git a/qsstv/dispatchevents.h b/qsstv/dispatchevents.h
deleted file mode 100644
index abaeabb..0000000
--- a/qsstv/dispatchevents.h
+++ /dev/null
@@ -1,567 +0,0 @@
-/***************************************************************************
- *   Copyright (C) 2000-2008 by Johan Maes                                 *
- *   on4qz at telenet.be                                                      *
- *   http://users.telenet.be/on4qz                                         *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   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.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- ***************************************************************************/
-#ifndef DISPATCHEVENT_H
-#define DISPATCHEVENT_H
-#include <QEvent>
-#include "widgets/imageviewer.h"
-#include "qsstvdefs.h"
-#include <unistd.h>
-
-
-/** dispatch events are used to communicate with the different threads */
-enum dispatchEventType
-{
-  info = QEvent::User, //!< send when dsp stops running
-  soundcardIdle, //!< send when soundcard stops running
-  displayFFT,
-  displaySync,
-  displayDRMStat,
-  displayDRMInfo,
-  syncDisp,				//!< synchro display event
-  lineDisplay,				//!< display 1 line
-  eraseDisp,
-  createMode,
-  startImageRX,
-  endImageRX,
-  endImageTX,
-  stoppingTX,
-  progressTX,
-//  verticalRetrace,
-//  syncLost,
-  outOfSync,
-  statusMsg,  	//!<  display status message
-  rxSSTVStatus,     //! shows message in sstv tab
-  rxDRMStatus,     //! shows message in drm tab
-  closeWindows,
-  callEditor,
-  templatesChanged,
-  editorFinished,
-  changeRXFilter,
-  startAutoRepeater,
-  startRepeater,
-  stopRxTx,
-  loadRXImage,
-  saveDRMImage,
-  prepareFix,
-  displayText,
-  displayMBox,
-  displayProgressFTP
-};
-
-class baseEvent: public QEvent
-{
-public:
-  baseEvent(QEvent::Type t):QEvent(t) {doneIt=NULL;}
-  void waitFor(bool *d) {doneIt=d;}
-  void setDone()
-  {
-    if(doneIt!=NULL) *doneIt=true;
-  }
-  QString description;
-private:
-  bool *doneIt;
-
-};
-
-/**
-  this event is send when the dspfunc thread stops running
-*/
-class infoEvent : public  baseEvent
-{
-public:
-  /** create event */
-  infoEvent(QString t):baseEvent( (QEvent::Type) info ), str(t)
-  {
-    description="infoEvent";
-  }
-  /** returns info string from the event */
-  QString getStr() const { return str; }
-private:
-  QString str;
-};
-
-/**
-  this event is send when the soundcard thread goes to idle
-*/
-class soundcardIdleEvent : public baseEvent
-{
-public:
-  /** create event */
-  soundcardIdleEvent():baseEvent( (QEvent::Type) soundcardIdle )
-  {
-    {
-      description=" soudcardIdleEvent";
-    }
-  }
-};
-
-
-//class rxDataAvailableEvent : public baseEvent
-//{
-//public:
-//	/** create event */
-//	rxDataAvailableEvent(uint idx,uint numSamples):baseEvent( (QEvent::Type)rxData ), index(idx),len(numSamples) {}
-//	/** returns length and pointer  from the event */
-//  uint getIndex(uint &idx) const { idx=index; return len;}
-
-//private:
-//  uint index;
-//	uint len;
-//};
-
-
-/**
-  this event is send with teh sync quality info and the signal volume
-*/
-class displaySyncEvent : public baseEvent
-{
-public:
-  /** create event */
-  displaySyncEvent(uint s,double v):baseEvent( (QEvent::Type) displaySync), sync(s), vol(v)
-  {
-    description=" displaySyncEvent";
-  }
-  /** returns length and pointer  from the event */
-  void getInfo(uint &s,double &v)  {s=sync; v=vol;}
-
-private:
-  uint sync;
-  DSPFLOAT vol;
-};
-
-class displayDRMStatEvent  : public baseEvent
-{
-public:
-  /** create event */
-  displayDRMStatEvent(uint s,DSPFLOAT v):baseEvent( (QEvent::Type) displayDRMStat), snr(s), vol(v)
-  {
-    description=" displayDRMStatEvent";
-  }
-  /** returns length and pointer  from the event */
-  void getInfo(DSPFLOAT &s,DSPFLOAT &v)  {s=snr; v=vol;}
-
-private:
-  DSPFLOAT snr;
-  DSPFLOAT vol;
-};
-
-class statusMsgEvent : public baseEvent
-{
-public:
-  /** create event */
-  statusMsgEvent(QString t):baseEvent( (QEvent::Type)statusMsg ), str(t)
-  {
-    description="statusMsgEvent";
-  }
-  /** returns info string from the event */
-  QString getStr() const { return str; }
-private:
-  QString str;
-};
-
-
-
-class rxSSTVStatusEvent : public baseEvent
-{
-public:
-  /** create event */
-  rxSSTVStatusEvent(QString t):baseEvent( (QEvent::Type)rxSSTVStatus ), str(t)
-  {
-    description="rxSSTVStatusEvent";
-  }
-  /** returns info string from the event */
-  QString getStr() const { return str; }
-private:
-  QString str;
-};
-
-class rxDRMStatusEvent : public baseEvent
-{
-public:
-  /** create event */
-  rxDRMStatusEvent(QString t):baseEvent( (QEvent::Type)rxDRMStatus ), str(t)
-  {
-    description="rxDRMStatusEvent";
-  }
-  /** returns info string from the event */
-  QString getStr() const { return str; }
-private:
-  QString str;
-};
-
-class lineDisplayEvent : public baseEvent
-{
-public:
-  /** create event */
-  lineDisplayEvent(uint lineNbr):baseEvent( (QEvent::Type)lineDisplay ), lineNumber(lineNbr)
-  {
-    description="lineDisplayEvent";
-  }
-  /** returns length and pointer  from the event */
-  void getInfo(uint &lineNbr) const { lineNbr=lineNumber;}
-
-private:
-  uint lineNumber;
-};
-
-class eraseDisplayEvent : public baseEvent
-{
-public:
-  /** create event */
-  eraseDisplayEvent():baseEvent( (QEvent::Type)eraseDisp )
-  {
-    description="eraseDisplayEvent";
-  }
-};
-
-
-
-class displayDRMInfoEvent : public baseEvent
-{
-public:
-  /** create event */
-  displayDRMInfoEvent():baseEvent( (QEvent::Type)displayDRMInfo)
-  {
-    description="displayDRMInfo";
-  }
-};
-
-class startAutoRepeaterEvent: public baseEvent
-{
-public:
-  /** create event */
-  startAutoRepeaterEvent():baseEvent( (QEvent::Type)startAutoRepeater )
-  {
-    description="startAutoRepeaterEvent";
-  }
-};
-
-class startRepeaterEvent: public baseEvent
-{
-public:
-  /** create event */
-  startRepeaterEvent():baseEvent( (QEvent::Type)startRepeater )
-  {
-    description="startRepeaterEvent";
-  }
-};
-
-
-class createModeEvent : public baseEvent
-{
-public:
-  /** create event */
-  createModeEvent(uint m,QString t):baseEvent( (QEvent::Type)createMode ), mode(m) ,str(t)
-  {
-    description="createModeEvent";
-  }
-  /** returns info string from the event */
-  void getMode(uint &m,QString &s) const { m=mode;s=str; }
-private:
-  uint mode;
-  QString str;
-};
-
-class loadRXImageEvent : public baseEvent
-{
-public:
-  loadRXImageEvent(QString fn):baseEvent( (QEvent::Type)loadRXImage),fileName(fn)
-  {
-    description="loadRXImageEvent";
-  }
-  void getFilename(QString &fn) {fn=fileName;}
-private:
-  QString fileName;
-};
-
-
-
-class saveDRMImageEvent : public baseEvent
-{
-public:
-  saveDRMImageEvent(QString fn):baseEvent( (QEvent::Type)saveDRMImage),fileName(fn)
-  {
-    description="saveDRMImageEvent";
-  }
-  void getFilename(QString &fn) {fn=fileName;}
-private:
-  QString fileName;
-};
-
-
-
-class startImageRXEvent : public baseEvent
-{
-public:
-  /** create event */
-  startImageRXEvent(QSize ims):baseEvent( (QEvent::Type)startImageRX ),imSize(ims)
-  {
-    description="startImageRXEvent";
-  }
-  QSize getSize()  {return imSize;}
-private:
-  QSize imSize;
-
-};
-
-class endImageRXEvent : public baseEvent
-{
-public:
-  /** create event */
-  endImageRXEvent():baseEvent( (QEvent::Type)endImageRX )
-  {
-    description="endImageRXEvent";
-  }
-};
-
-class endImageTXEvent : public baseEvent
-{
-public:
-  /** create event */
-  endImageTXEvent():baseEvent( (QEvent::Type)endImageTX )
-  {
-    description="endImageTXEvent";
-  }
-};
-
-
-class stopTXEvent : public baseEvent
-{
-public:
-  /** create event */
-  stopTXEvent():baseEvent( (QEvent::Type)stoppingTX )
-  {
-    description="stopTXEvent";
-  }
-};
-
-//class verticalRetraceEvent : public baseEvent
-//{
-//public:
-//  /** create event */
-//  verticalRetraceEvent():baseEvent( (QEvent::Type) verticalRetrace )
-//  {
-//    description="verticalRetraceEvent";
-//  }
-//};
-
-//class syncLostEvent : public baseEvent
-//{
-//public:
-//  /** create event */
-//  syncLostEvent():baseEvent( (QEvent::Type) syncLost )
-//  {
-//    description="syncLostEvent";
-//  }
-//};
-
-
-
-class outOfSyncEvent : public baseEvent
-{
-public:
-  /** create event */
-  outOfSyncEvent():baseEvent( (QEvent::Type)outOfSync )
-  {
-    description="outOfSyncEvent";
-  }
-};
-
-
-
-class progressTXEvent : public baseEvent
-{
-public:
-  /** create event */
-  progressTXEvent(double tim):baseEvent( (QEvent::Type)progressTX ), txTime(tim)
-  {
-    description="progressTXEvent";
-  }
-  /** returns length and pointer  from the event */
-  double getInfo() { return txTime;}
-
-private:
-  double txTime;
-};
-
-class closeWindowsEvent : public baseEvent
-{
-public:
-  /** create event */
-  closeWindowsEvent():baseEvent( (QEvent::Type)closeWindows)
-  {
-    description="closeWindowEvent";
-  }
-  /** returns length and pointer  from the event */
-};
-
-
-
-class callEditorEvent : public baseEvent
-{
-public:
-  /** create event */
-  callEditorEvent(imageViewer *iv,QString fn):baseEvent( (QEvent::Type) callEditor ), filename(fn),imviewer(iv)
-  {
-    description="callEditorEvent";
-  }
-  /** returns info string from the event */
-  QString getFilename() const { return filename; }
-  imageViewer *getImageViewer() { return imviewer; }
-private:
-  QString filename;
-  imageViewer *imviewer;
-};
-
-
-class templatesChangedEvent : public baseEvent
-{
-public:
-  /** create event */
-  templatesChangedEvent():baseEvent( (QEvent::Type) templatesChanged )
-  {
-    description="templateChangeEvent";
-  }
-};
-
-class editorFinishedEvent : public baseEvent
-{
-public:
-  /** create event */
-  editorFinishedEvent(bool b,QString fn):baseEvent( (QEvent::Type)editorFinished),ok(b),filename(fn)
-  {
-    description="editorFinishedEvent";
-  }
-  bool isOK() { return ok;}
-  QString getFilename() const { return filename; }
-
-private:
-  bool ok;
-  QString filename;
-
-};
-
-
-class displayFFTEvent : public baseEvent
-{
-public:
-  /** create event */
-  displayFFTEvent(DSPFLOAT *buf):baseEvent( (QEvent::Type)displayFFT),buffer(buf)
-  {
-    description="displayFFTEvent";
-  }
-  DSPFLOAT *data() { return buffer;}
-private:
-  DSPFLOAT *buffer;
-
-};
-
-class filterRXChangedEvent: public baseEvent
-{
-public:
-  /** create event */
-  filterRXChangedEvent(int fIndex):baseEvent( (QEvent::Type)changeRXFilter),filterIndex(fIndex)
-  {
-    description="filterChangedEvent";
-  }
-  int index() { return filterIndex;}
-private:
-  int filterIndex;
-};
-
-class stopRxTxEvent : public baseEvent
-{
-public:
-  /** create event */
-  stopRxTxEvent():baseEvent( (QEvent::Type)stopRxTx)
-  {
-    description="stopRxTxEvent";
-  }
-};
-
-
-class prepareFixEvent: public baseEvent
-{
-public:
-  prepareFixEvent(QByteArray ba):baseEvent( (QEvent::Type)prepareFix),data(ba)
-  {
-    description="filterChangedEvent";
-  }
-  QByteArray &getData() {return data;}
-private:
-  QByteArray data;
-};
-
-
-/**
-  this event is send when the dspfunc thread stops running
-*/
-class displayTextEvent : public  baseEvent
-{
-public:
-  /** create event */
-  displayTextEvent(QString t):baseEvent( (QEvent::Type) displayText ), str(t)
-  {
-    description="displayTextEvent";
-  }
-  /** returns info string from the event */
-  QString getStr() const { return str; }
-private:
-  QString str;
-};
-
-class displayMBoxEvent : public  baseEvent
-{
-public:
-  /** create event */
-  displayMBoxEvent(QString title,QString text):baseEvent( (QEvent::Type) displayMBox ), str(text), title(title)
-  {
-    description="displayMBoxEvent";
-  }
-  /** returns info string from the event */
-  QString getStr() const { return str; }
-  QString getTitle() const { return title; }
-
-private:
-  QString str;
-  QString title;
-};
-
-
-class displayProgressFTPEvent : public  baseEvent
-{
-public:
-  /** create event */
-  displayProgressFTPEvent(quint64 byts,quint64 tot):baseEvent( (QEvent::Type) displayProgressFTP ),  bytes(byts),total(tot)
-  {
-    description="displayMBoxEvent";
-  }
-  /** returns info string from the event */
-  quint64 getTotal() const { return total; }
-  quint64 getBytes() const { return bytes; }
-
-private:
-  quint64 bytes;
-  quint64 total;
-
-};
-
-#endif
diff --git a/qsstv/documentation/manual/doxygen_sqlite3.db b/qsstv/documentation/manual/doxygen_sqlite3.db
new file mode 100644
index 0000000..7208c19
Binary files /dev/null and b/qsstv/documentation/manual/doxygen_sqlite3.db differ
diff --git a/qsstv/documentation/manual/images/Gallery_image_options.png b/qsstv/documentation/manual/images/Gallery_image_options.png
new file mode 100644
index 0000000..e46c156
Binary files /dev/null and b/qsstv/documentation/manual/images/Gallery_image_options.png differ
diff --git a/qsstv/documentation/manual/images/Gallery_rx.png b/qsstv/documentation/manual/images/Gallery_rx.png
new file mode 100644
index 0000000..c7ed4f1
Binary files /dev/null and b/qsstv/documentation/manual/images/Gallery_rx.png differ
diff --git a/qsstv/documentation/manual/images/Gallery_template.png b/qsstv/documentation/manual/images/Gallery_template.png
new file mode 100644
index 0000000..f7f8d8a
Binary files /dev/null and b/qsstv/documentation/manual/images/Gallery_template.png differ
diff --git a/qsstv/documentation/manual/images/Gallery_tx.png b/qsstv/documentation/manual/images/Gallery_tx.png
new file mode 100644
index 0000000..b776f9f
Binary files /dev/null and b/qsstv/documentation/manual/images/Gallery_tx.png differ
diff --git a/qsstv/documentation/manual/images/binary.png b/qsstv/documentation/manual/images/binary.png
new file mode 100644
index 0000000..eae4e50
Binary files /dev/null and b/qsstv/documentation/manual/images/binary.png differ
diff --git a/qsstv/documentation/manual/images/bsr_nfy.png b/qsstv/documentation/manual/images/bsr_nfy.png
new file mode 100644
index 0000000..62f029a
Binary files /dev/null and b/qsstv/documentation/manual/images/bsr_nfy.png differ
diff --git a/qsstv/documentation/manual/images/bsr_select.png b/qsstv/documentation/manual/images/bsr_select.png
new file mode 100644
index 0000000..fb4cecb
Binary files /dev/null and b/qsstv/documentation/manual/images/bsr_select.png differ
diff --git a/qsstv/documentation/manual/images/calibration.png b/qsstv/documentation/manual/images/calibration.png
new file mode 100644
index 0000000..4a3ca0e
Binary files /dev/null and b/qsstv/documentation/manual/images/calibration.png differ
diff --git a/qsstv/documentation/manual/images/config.png b/qsstv/documentation/manual/images/config.png
new file mode 100644
index 0000000..39bce23
Binary files /dev/null and b/qsstv/documentation/manual/images/config.png differ
diff --git a/qsstv/documentation/manual/images/config1.png b/qsstv/documentation/manual/images/config1.png
new file mode 100644
index 0000000..d49b745
Binary files /dev/null and b/qsstv/documentation/manual/images/config1.png differ
diff --git a/qsstv/documentation/manual/images/config10.png b/qsstv/documentation/manual/images/config10.png
new file mode 100644
index 0000000..148c32a
Binary files /dev/null and b/qsstv/documentation/manual/images/config10.png differ
diff --git a/qsstv/documentation/manual/images/config11.png b/qsstv/documentation/manual/images/config11.png
new file mode 100644
index 0000000..f66fc63
Binary files /dev/null and b/qsstv/documentation/manual/images/config11.png differ
diff --git a/qsstv/documentation/manual/images/config12.png b/qsstv/documentation/manual/images/config12.png
new file mode 100644
index 0000000..1aba6de
Binary files /dev/null and b/qsstv/documentation/manual/images/config12.png differ
diff --git a/qsstv/documentation/manual/images/config2.png b/qsstv/documentation/manual/images/config2.png
new file mode 100644
index 0000000..489b299
Binary files /dev/null and b/qsstv/documentation/manual/images/config2.png differ
diff --git a/qsstv/documentation/manual/images/config3.png b/qsstv/documentation/manual/images/config3.png
new file mode 100644
index 0000000..eaf589f
Binary files /dev/null and b/qsstv/documentation/manual/images/config3.png differ
diff --git a/qsstv/documentation/manual/images/config4.png b/qsstv/documentation/manual/images/config4.png
new file mode 100644
index 0000000..d93d128
Binary files /dev/null and b/qsstv/documentation/manual/images/config4.png differ
diff --git a/qsstv/documentation/manual/images/config5.png b/qsstv/documentation/manual/images/config5.png
new file mode 100644
index 0000000..383973e
Binary files /dev/null and b/qsstv/documentation/manual/images/config5.png differ
diff --git a/qsstv/documentation/manual/images/config6.png b/qsstv/documentation/manual/images/config6.png
new file mode 100644
index 0000000..7c84704
Binary files /dev/null and b/qsstv/documentation/manual/images/config6.png differ
diff --git a/qsstv/documentation/manual/images/config7.png b/qsstv/documentation/manual/images/config7.png
new file mode 100644
index 0000000..5c1acb6
Binary files /dev/null and b/qsstv/documentation/manual/images/config7.png differ
diff --git a/qsstv/documentation/manual/images/config8.png b/qsstv/documentation/manual/images/config8.png
new file mode 100644
index 0000000..44001f9
Binary files /dev/null and b/qsstv/documentation/manual/images/config8.png differ
diff --git a/qsstv/documentation/manual/images/config9.png b/qsstv/documentation/manual/images/config9.png
new file mode 100644
index 0000000..9192705
Binary files /dev/null and b/qsstv/documentation/manual/images/config9.png differ
diff --git a/qsstv/documentation/manual/images/cqrlog1.png b/qsstv/documentation/manual/images/cqrlog1.png
new file mode 100644
index 0000000..94c740a
Binary files /dev/null and b/qsstv/documentation/manual/images/cqrlog1.png differ
diff --git a/qsstv/documentation/manual/images/cqrlog2.png b/qsstv/documentation/manual/images/cqrlog2.png
new file mode 100644
index 0000000..a7ebcf9
Binary files /dev/null and b/qsstv/documentation/manual/images/cqrlog2.png differ
diff --git a/qsstv/documentation/manual/images/editor_1.png b/qsstv/documentation/manual/images/editor_1.png
new file mode 100644
index 0000000..5e4102e
Binary files /dev/null and b/qsstv/documentation/manual/images/editor_1.png differ
diff --git a/qsstv/documentation/manual/images/editor_2.png b/qsstv/documentation/manual/images/editor_2.png
new file mode 100644
index 0000000..ebb5617
Binary files /dev/null and b/qsstv/documentation/manual/images/editor_2.png differ
diff --git a/qsstv/documentation/manual/images/editor_3.png b/qsstv/documentation/manual/images/editor_3.png
new file mode 100644
index 0000000..babb764
Binary files /dev/null and b/qsstv/documentation/manual/images/editor_3.png differ
diff --git a/qsstv/documentation/manual/images/editor_image_size.png b/qsstv/documentation/manual/images/editor_image_size.png
new file mode 100644
index 0000000..35d5a97
Binary files /dev/null and b/qsstv/documentation/manual/images/editor_image_size.png differ
diff --git a/qsstv/documentation/manual/images/entertext.png b/qsstv/documentation/manual/images/entertext.png
new file mode 100644
index 0000000..83c76e6
Binary files /dev/null and b/qsstv/documentation/manual/images/entertext.png differ
diff --git a/qsstv/documentation/manual/images/eraser.png b/qsstv/documentation/manual/images/eraser.png
new file mode 100644
index 0000000..78632a5
Binary files /dev/null and b/qsstv/documentation/manual/images/eraser.png differ
diff --git a/qsstv/documentation/manual/images/fix.png b/qsstv/documentation/manual/images/fix.png
new file mode 100644
index 0000000..099c640
Binary files /dev/null and b/qsstv/documentation/manual/images/fix.png differ
diff --git a/qsstv/documentation/manual/images/flrig1.png b/qsstv/documentation/manual/images/flrig1.png
new file mode 100644
index 0000000..430c469
Binary files /dev/null and b/qsstv/documentation/manual/images/flrig1.png differ
diff --git a/qsstv/documentation/manual/images/hybrid_checkbox.png b/qsstv/documentation/manual/images/hybrid_checkbox.png
new file mode 100644
index 0000000..36bb44e
Binary files /dev/null and b/qsstv/documentation/manual/images/hybrid_checkbox.png differ
diff --git a/qsstv/documentation/manual/images/hybrid_dis_checkbox.png b/qsstv/documentation/manual/images/hybrid_dis_checkbox.png
new file mode 100644
index 0000000..ee13f95
Binary files /dev/null and b/qsstv/documentation/manual/images/hybrid_dis_checkbox.png differ
diff --git a/qsstv/documentation/manual/images/multiline.png b/qsstv/documentation/manual/images/multiline.png
new file mode 100644
index 0000000..f6f79ca
Binary files /dev/null and b/qsstv/documentation/manual/images/multiline.png differ
diff --git a/qsstv/documentation/manual/images/receivedrm.png b/qsstv/documentation/manual/images/receivedrm.png
new file mode 100644
index 0000000..7945ee2
Binary files /dev/null and b/qsstv/documentation/manual/images/receivedrm.png differ
diff --git a/qsstv/documentation/manual/images/refreshbutton.png b/qsstv/documentation/manual/images/refreshbutton.png
new file mode 100644
index 0000000..85c0db8
Binary files /dev/null and b/qsstv/documentation/manual/images/refreshbutton.png differ
diff --git a/qsstv/documentation/manual/images/rxdrm_constellation.png b/qsstv/documentation/manual/images/rxdrm_constellation.png
new file mode 100644
index 0000000..9041cb7
Binary files /dev/null and b/qsstv/documentation/manual/images/rxdrm_constellation.png differ
diff --git a/qsstv/documentation/manual/images/rxdrm_segments.png b/qsstv/documentation/manual/images/rxdrm_segments.png
new file mode 100644
index 0000000..8586a6b
Binary files /dev/null and b/qsstv/documentation/manual/images/rxdrm_segments.png differ
diff --git a/qsstv/documentation/manual/images/rxdrm_status.png b/qsstv/documentation/manual/images/rxdrm_status.png
new file mode 100644
index 0000000..fd337bf
Binary files /dev/null and b/qsstv/documentation/manual/images/rxdrm_status.png differ
diff --git a/qsstv/documentation/manual/images/rxwidget1.png b/qsstv/documentation/manual/images/rxwidget1.png
new file mode 100644
index 0000000..c276288
Binary files /dev/null and b/qsstv/documentation/manual/images/rxwidget1.png differ
diff --git a/qsstv/documentation/manual/images/sstvdrmselect.png b/qsstv/documentation/manual/images/sstvdrmselect.png
new file mode 100644
index 0000000..4fa00a5
Binary files /dev/null and b/qsstv/documentation/manual/images/sstvdrmselect.png differ
diff --git a/qsstv/documentation/manual/images/statusbar.png b/qsstv/documentation/manual/images/statusbar.png
new file mode 100644
index 0000000..3018aab
Binary files /dev/null and b/qsstv/documentation/manual/images/statusbar.png differ
diff --git a/qsstv/documentation/manual/images/statusleds.png b/qsstv/documentation/manual/images/statusleds.png
new file mode 100644
index 0000000..36f8769
Binary files /dev/null and b/qsstv/documentation/manual/images/statusleds.png differ
diff --git a/qsstv/documentation/manual/images/transmitdrm.png b/qsstv/documentation/manual/images/transmitdrm.png
new file mode 100644
index 0000000..e329d32
Binary files /dev/null and b/qsstv/documentation/manual/images/transmitdrm.png differ
diff --git a/qsstv/documentation/manual/images/tx-with-template.png b/qsstv/documentation/manual/images/tx-with-template.png
new file mode 100644
index 0000000..d8b1d26
Binary files /dev/null and b/qsstv/documentation/manual/images/tx-with-template.png differ
diff --git a/qsstv/documentation/manual/images/txdrm_compression.png b/qsstv/documentation/manual/images/txdrm_compression.png
new file mode 100644
index 0000000..55f1585
Binary files /dev/null and b/qsstv/documentation/manual/images/txdrm_compression.png differ
diff --git a/qsstv/documentation/manual/images/txdrm_options.png b/qsstv/documentation/manual/images/txdrm_options.png
new file mode 100644
index 0000000..0b12bf2
Binary files /dev/null and b/qsstv/documentation/manual/images/txdrm_options.png differ
diff --git a/qsstv/documentation/manual/images/txdrm_status.png b/qsstv/documentation/manual/images/txdrm_status.png
new file mode 100644
index 0000000..f9a69e8
Binary files /dev/null and b/qsstv/documentation/manual/images/txdrm_status.png differ
diff --git a/qsstv/documentation/manual/images/txwidget1.png b/qsstv/documentation/manual/images/txwidget1.png
new file mode 100644
index 0000000..460a2d5
Binary files /dev/null and b/qsstv/documentation/manual/images/txwidget1.png differ
diff --git a/qsstv/documentation/manual/images/vk4aes.jpg b/qsstv/documentation/manual/images/vk4aes.jpg
new file mode 100644
index 0000000..a18b81a
Binary files /dev/null and b/qsstv/documentation/manual/images/vk4aes.jpg differ
diff --git a/qsstv/documentation/manual/images/waterfall.png b/qsstv/documentation/manual/images/waterfall.png
new file mode 100644
index 0000000..7564382
Binary files /dev/null and b/qsstv/documentation/manual/images/waterfall.png differ
diff --git a/qsstv/documentation/manual/images/wf_bsr_id.png b/qsstv/documentation/manual/images/wf_bsr_id.png
new file mode 100644
index 0000000..799a83c
Binary files /dev/null and b/qsstv/documentation/manual/images/wf_bsr_id.png differ
diff --git a/qsstv/documentation/manual/images/wftextpopup.png b/qsstv/documentation/manual/images/wftextpopup.png
new file mode 100644
index 0000000..7fb9b93
Binary files /dev/null and b/qsstv/documentation/manual/images/wftextpopup.png differ
diff --git a/qsstv/Doxyfile b/qsstv/documentation/manual/manual.doxy
similarity index 76%
rename from qsstv/Doxyfile
rename to qsstv/documentation/manual/manual.doxy
index f6853d7..c5d3b5c 100644
--- a/qsstv/Doxyfile
+++ b/qsstv/documentation/manual/manual.doxy
@@ -1,103 +1,103 @@
-# Doxyfile 1.7.6.1
+# Doxyfile 1.8.1.2
 
 # This file describes the settings to be used by the documentation system
-# doxygen (www.doxygen.org) for a project
+# doxygen (www.doxygen.org) for a project.
 #
-# All text after a hash (#) is considered a comment and will be ignored
+# All text after a hash (#) is considered a comment and will be ignored.
 # The format is:
 #       TAG = value [value, ...]
 # For lists items can also be appended using:
 #       TAG += value [value, ...]
-# Values that contain spaces should be placed between quotes (" ")
+# Values that contain spaces should be placed between quotes (" ").
 
 #---------------------------------------------------------------------------
 # Project related configuration options
 #---------------------------------------------------------------------------
 
-# This tag specifies the encoding used for all characters in the config file 
-# that follow. The default is UTF-8 which is also the encoding used for all 
-# text before the first occurrence of this tag. Doxygen uses libiconv (or the 
-# iconv built into libc) for the transcoding. See 
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the
+# iconv built into libc) for the transcoding. See
 # http://www.gnu.org/software/libiconv for the list of possible encodings.
 
 DOXYFILE_ENCODING      = UTF-8
 
-# The PROJECT_NAME tag is a single word (or sequence of words) that should 
-# identify the project. Note that if you do not use Doxywizard you need 
+# The PROJECT_NAME tag is a single word (or sequence of words) that should
+# identify the project. Note that if you do not use Doxywizard you need
 # to put quotes around the project name if it contains spaces.
 
-PROJECT_NAME           = "QSSTV"
+PROJECT_NAME           = QSSTV
 
-# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
-# This could be handy for archiving the generated documentation or 
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
 # if some version control system is used.
 
-PROJECT_NUMBER         = 8.2.7
+PROJECT_NUMBER         = 9.1
 
-# Using the PROJECT_BRIEF tag one can provide an optional one line description 
-# for a project that appears at the top of each page and should give viewer 
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer
 # a quick idea about the purpose of the project. Keep the description short.
 
-PROJECT_BRIEF          = "SSTV and HAMDRM"
+PROJECT_BRIEF          =
 
-# With the PROJECT_LOGO tag one can specify an logo or icon that is 
-# included in the documentation. The maximum height of the logo should not 
-# exceed 55 pixels and the maximum width should not exceed 200 pixels. 
+# With the PROJECT_LOGO tag one can specify an logo or icon that is
+# included in the documentation. The maximum height of the logo should not
+# exceed 55 pixels and the maximum width should not exceed 200 pixels.
 # Doxygen will copy the logo to the output directory.
 
-PROJECT_LOGO           = 
+PROJECT_LOGO           =
 
-# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
-# base path where the generated documentation will be put. 
-# If a relative path is entered, it will be relative to the location 
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
 # where doxygen was started. If left blank the current directory will be used.
 
-OUTPUT_DIRECTORY       = Documentation
+OUTPUT_DIRECTORY       =
 
-# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
-# 4096 sub-directories (in 2 levels) under the output directory of each output 
-# format and will distribute the generated files over these directories. 
-# Enabling this option can be useful when feeding doxygen a huge amount of 
-# source files, where putting all generated files in the same directory would 
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
 # otherwise cause performance problems for the file system.
 
 CREATE_SUBDIRS         = NO
 
-# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
-# documentation generated by doxygen is written. Doxygen will use this 
-# information to generate all constant output in the proper language. 
-# The default language is English, other supported languages are: 
-# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, 
-# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, 
-# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English 
-# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, 
-# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, 
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
+# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
+# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
+# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,
+# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak,
 # Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
 
 OUTPUT_LANGUAGE        = English
 
-# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
-# include brief member descriptions after the members that are listed in 
-# the file and class documentation (similar to JavaDoc). 
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
 # Set to NO to disable this.
 
 BRIEF_MEMBER_DESC      = YES
 
-# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
-# the brief description of a member or function before the detailed description. 
-# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
 # brief descriptions will be completely suppressed.
 
 REPEAT_BRIEF           = YES
 
-# This tag implements a quasi-intelligent brief description abbreviator 
-# that is used to form the text in various listings. Each string 
-# in this list, if found as the leading text of the brief description, will be 
-# stripped from the text and the result after processing the whole list, is 
-# used as the annotated text. Otherwise, the brief description is used as-is. 
-# If left blank, the following values are used ("$name" is automatically 
-# replaced with the name of the entity): "The $name class" "The $name widget" 
-# "The $name file" "is" "provides" "specifies" "contains" 
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
 # "represents" "a" "an" "the"
 
 ABBREVIATE_BRIEF       = "The $name class" \
@@ -112,237 +112,230 @@ ABBREVIATE_BRIEF       = "The $name class" \
                          an \
                          the
 
-# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
-# Doxygen will generate a detailed section even if there is only a brief 
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
 # description.
 
 ALWAYS_DETAILED_SEC    = NO
 
-# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 
-# inherited members of a class in the documentation of that class as if those 
-# members were ordinary class members. Constructors, destructors and assignment 
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
 # operators of the base classes will not be shown.
 
 INLINE_INHERITED_MEMB  = NO
 
-# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
-# path before files name in the file list and in the header files. If set 
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
 # to NO the shortest path that makes the file name unique will be used.
 
 FULL_PATH_NAMES        = YES
 
-# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
-# can be used to strip a user-defined part of the path. Stripping is 
-# only done if one of the specified strings matches the left-hand part of 
-# the path. The tag can be used to show relative paths in the file list. 
-# If left blank the directory from which doxygen is run is used as the 
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
 # path to strip.
 
-STRIP_FROM_PATH        = 
+STRIP_FROM_PATH        =
 
-# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
-# the path mentioned in the documentation of a class, which tells 
-# the reader which header file to include in order to use a class. 
-# If left blank only the name of the header file containing the class 
-# definition is used. Otherwise one should specify the include paths that 
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
 # are normally passed to the compiler using the -I flag.
 
-STRIP_FROM_INC_PATH    = 
+STRIP_FROM_INC_PATH    =
 
-# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
-# (but less readable) file names. This can be useful if your file system 
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful if your file system
 # doesn't support long names like on DOS, Mac, or CD-ROM.
 
 SHORT_NAMES            = NO
 
-# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
-# will interpret the first line (until the first dot) of a JavaDoc-style 
-# comment as the brief description. If set to NO, the JavaDoc 
-# comments will behave just like regular Qt-style comments 
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like regular Qt-style comments
 # (thus requiring an explicit @brief command for a brief description.)
 
 JAVADOC_AUTOBRIEF      = NO
 
-# If the QT_AUTOBRIEF tag is set to YES then Doxygen will 
-# interpret the first line (until the first dot) of a Qt-style 
-# comment as the brief description. If set to NO, the comments 
-# will behave just like regular Qt-style comments (thus requiring 
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
+# interpret the first line (until the first dot) of a Qt-style
+# comment as the brief description. If set to NO, the comments
+# will behave just like regular Qt-style comments (thus requiring
 # an explicit \brief command for a brief description.)
 
 QT_AUTOBRIEF           = NO
 
-# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
-# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
-# comments) as a brief description. This used to be the default behaviour. 
-# The new default is to treat a multi-line C++ comment block as a detailed 
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
 # description. Set this tag to YES if you prefer the old behaviour instead.
 
 MULTILINE_CPP_IS_BRIEF = NO
 
-# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
-# member inherits the documentation from any documented member that it 
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
 # re-implements.
 
 INHERIT_DOCS           = YES
 
-# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 
-# a new page for each member. If set to NO, the documentation of a member will 
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
 # be part of the file/class/namespace that contains it.
 
 SEPARATE_MEMBER_PAGES  = NO
 
-# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
 # Doxygen uses this value to replace tabs by spaces in code fragments.
 
 TAB_SIZE               = 8
 
-# This tag can be used to specify a number of aliases that acts 
-# as commands in the documentation. An alias has the form "name=value". 
-# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
-# put the command \sideeffect (or @sideeffect) in the documentation, which 
-# will result in a user-defined paragraph with heading "Side Effects:". 
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
 # You can put \n's in the value part of an alias to insert newlines.
 
-ALIASES                = 
+ALIASES                =
 
-# This tag can be used to specify a number of word-keyword mappings (TCL only). 
-# A mapping has the form "name=value". For example adding 
-# "class=itcl::class" will allow you to use the command class in the 
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding
+# "class=itcl::class" will allow you to use the command class in the
 # itcl::class meaning.
 
-TCL_SUBST              = 
+TCL_SUBST              =
 
-# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 
-# sources only. Doxygen will then generate output that is more tailored for C. 
-# For instance, some of the names that are used will be different. The list 
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
 # of all members will be omitted, etc.
 
 OPTIMIZE_OUTPUT_FOR_C  = NO
 
-# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java 
-# sources only. Doxygen will then generate output that is more tailored for 
-# Java. For instance, namespaces will be presented as packages, qualified 
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
+# sources only. Doxygen will then generate output that is more tailored for
+# Java. For instance, namespaces will be presented as packages, qualified
 # scopes will look different, etc.
 
 OPTIMIZE_OUTPUT_JAVA   = NO
 
-# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran 
-# sources only. Doxygen will then generate output that is more tailored for 
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources only. Doxygen will then generate output that is more tailored for
 # Fortran.
 
 OPTIMIZE_FOR_FORTRAN   = NO
 
-# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL 
-# sources. Doxygen will then generate output that is tailored for 
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for
 # VHDL.
 
 OPTIMIZE_OUTPUT_VHDL   = NO
 
-# Doxygen selects the parser to use depending on the extension of the files it 
-# parses. With this tag you can assign which parser to use for a given extension. 
-# Doxygen has a built-in mapping, but you can override or extend it using this 
-# tag. The format is ext=language, where ext is a file extension, and language 
-# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, 
-# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make 
-# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C 
-# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions 
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given extension.
+# Doxygen has a built-in mapping, but you can override or extend it using this
+# tag. The format is ext=language, where ext is a file extension, and language
+# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C,
+# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make
+# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C
+# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions
 # you also need to set FILE_PATTERNS otherwise the files are not read by doxygen.
 
-EXTENSION_MAPPING      = 
+EXTENSION_MAPPING      =
 
-# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want 
-# to include (a tag file for) the STL sources as input, then you should 
-# set this tag to YES in order to let doxygen match functions declarations and 
-# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. 
-# func(std::string) {}). This also makes the inheritance and collaboration 
+# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all
+# comments according to the Markdown format, which allows for more readable
+# documentation. See http://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you
+# can mix doxygen, HTML, and XML commands with Markdown formatting.
+# Disable only in case of backward compatibilities issues.
+
+MARKDOWN_SUPPORT       = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should
+# set this tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
+# func(std::string) {}). This also makes the inheritance and collaboration
 # diagrams that involve STL classes more complete and accurate.
 
 BUILTIN_STL_SUPPORT    = NO
 
-# If you use Microsoft's C++/CLI language, you should set this option to YES to 
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
 # enable parsing support.
 
 CPP_CLI_SUPPORT        = NO
 
-# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. 
-# Doxygen will parse them like normal C++ but will assume all classes use public 
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
+# Doxygen will parse them like normal C++ but will assume all classes use public
 # instead of private inheritance when no explicit protection keyword is present.
 
 SIP_SUPPORT            = NO
 
-# For Microsoft's IDL there are propget and propput attributes to indicate getter 
-# and setter methods for a property. Setting this option to YES (the default) 
-# will make doxygen replace the get and set methods by a property in the 
-# documentation. This will only work if the methods are indeed getting or 
-# setting a simple type. If this is not the case, or you want to show the 
+# For Microsoft's IDL there are propget and propput attributes to indicate getter
+# and setter methods for a property. Setting this option to YES (the default)
+# will make doxygen replace the get and set methods by a property in the
+# documentation. This will only work if the methods are indeed getting or
+# setting a simple type. If this is not the case, or you want to show the
 # methods anyway, you should set this option to NO.
 
 IDL_PROPERTY_SUPPORT   = YES
 
-# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
-# tag is set to YES, then doxygen will reuse the documentation of the first 
-# member in the group (if any) for the other members of the group. By default 
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
 # all members of a group must be documented explicitly.
 
 DISTRIBUTE_GROUP_DOC   = NO
 
-# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
-# the same type (for instance a group of public functions) to be put as a 
-# subgroup of that type (e.g. under the Public Functions section). Set it to 
-# NO to prevent subgrouping. Alternatively, this can be done per class using 
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
 # the \nosubgrouping command.
 
 SUBGROUPING            = YES
 
-# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and 
-# unions are shown inside the group in which they are included (e.g. using 
-# @ingroup) instead of on a separate page (for HTML and Man pages) or 
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and
+# unions are shown inside the group in which they are included (e.g. using
+# @ingroup) instead of on a separate page (for HTML and Man pages) or
 # section (for LaTeX and RTF).
 
 INLINE_GROUPED_CLASSES = NO
 
-# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and 
-# unions with only public data fields will be shown inline in the documentation 
-# of the scope in which they are defined (i.e. file, namespace, or group 
-# documentation), provided this scope is documented. If set to NO (the default), 
-# structs, classes, and unions are shown on a separate page (for HTML and Man 
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and
+# unions with only public data fields will be shown inline in the documentation
+# of the scope in which they are defined (i.e. file, namespace, or group
+# documentation), provided this scope is documented. If set to NO (the default),
+# structs, classes, and unions are shown on a separate page (for HTML and Man
 # pages) or section (for LaTeX and RTF).
 
 INLINE_SIMPLE_STRUCTS  = NO
 
-# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum 
-# is documented as struct, union, or enum with the name of the typedef. So 
-# typedef struct TypeS {} TypeT, will appear in the documentation as a struct 
-# with name TypeT. When disabled the typedef will appear as a member of a file, 
-# namespace, or class. And the struct will be named TypeS. This can typically 
-# be useful for C code in case the coding convention dictates that all compound 
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
+# is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically
+# be useful for C code in case the coding convention dictates that all compound
 # types are typedef'ed and only the typedef is referenced, never the tag name.
 
 TYPEDEF_HIDES_STRUCT   = NO
 
-# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to 
-# determine which symbols to keep in memory and which to flush to disk. 
-# When the cache is full, less often used symbols will be written to disk. 
-# For small to medium size projects (<1000 input files) the default value is 
-# probably good enough. For larger projects a too small cache size can cause 
-# doxygen to be busy swapping symbols to and from disk most of the time 
-# causing a significant performance penalty. 
-# If the system has enough physical memory increasing the cache will improve the 
-# performance by keeping more symbols in memory. Note that the value works on 
-# a logarithmic scale so increasing the size by one will roughly double the 
-# memory usage. The cache size is given by this formula: 
-# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, 
-# corresponding to a cache size of 2^16 = 65536 symbols.
-
-SYMBOL_CACHE_SIZE      = 0
-
-# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be 
-# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given 
-# their name and scope. Since this can be an expensive process and often the 
-# same symbol appear multiple times in the code, doxygen keeps a cache of 
-# pre-resolved symbols. If the cache is too small doxygen will become slower. 
-# If the cache is too large, memory is wasted. The cache size is given by this 
-# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, 
+# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be
+# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given
+# their name and scope. Since this can be an expensive process and often the
+# same symbol appear multiple times in the code, doxygen keeps a cache of
+# pre-resolved symbols. If the cache is too small doxygen will become slower.
+# If the cache is too large, memory is wasted. The cache size is given by this
+# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0,
 # corresponding to a cache size of 2^16 = 65536 symbols.
 
 LOOKUP_CACHE_SIZE      = 0
@@ -351,509 +344,482 @@ LOOKUP_CACHE_SIZE      = 0
 # Build related configuration options
 #---------------------------------------------------------------------------
 
-# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
-# documentation are documented, even if no documentation was available. 
-# Private class members and static file members will be hidden unless 
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
 # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
 
 EXTRACT_ALL            = NO
 
-# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
 # will be included in the documentation.
 
 EXTRACT_PRIVATE        = NO
 
-# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal scope will be included in the documentation.
+
+EXTRACT_PACKAGE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
 # will be included in the documentation.
 
 EXTRACT_STATIC         = NO
 
-# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
-# defined locally in source files will be included in the documentation. 
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
 # If set to NO only classes defined in header files are included.
 
 EXTRACT_LOCAL_CLASSES  = YES
 
-# This flag is only useful for Objective-C code. When set to YES local 
-# methods, which are defined in the implementation section but not in 
-# the interface are included in the documentation. 
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
 # If set to NO (the default) only methods in the interface are included.
 
 EXTRACT_LOCAL_METHODS  = NO
 
-# If this flag is set to YES, the members of anonymous namespaces will be 
-# extracted and appear in the documentation as a namespace called 
-# 'anonymous_namespace{file}', where file will be replaced with the base 
-# name of the file that contains the anonymous namespace. By default 
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base
+# name of the file that contains the anonymous namespace. By default
 # anonymous namespaces are hidden.
 
 EXTRACT_ANON_NSPACES   = NO
 
-# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
-# undocumented members of documented classes, files or namespaces. 
-# If set to NO (the default) these members will be included in the 
-# various overviews, but no documentation section is generated. 
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
 # This option has no effect if EXTRACT_ALL is enabled.
 
 HIDE_UNDOC_MEMBERS     = NO
 
-# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
-# undocumented classes that are normally visible in the class hierarchy. 
-# If set to NO (the default) these classes will be included in the various 
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
 # overviews. This option has no effect if EXTRACT_ALL is enabled.
 
 HIDE_UNDOC_CLASSES     = NO
 
-# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
-# friend (class|struct|union) declarations. 
-# If set to NO (the default) these declarations will be included in the 
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
 # documentation.
 
 HIDE_FRIEND_COMPOUNDS  = NO
 
-# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
-# documentation blocks found inside the body of a function. 
-# If set to NO (the default) these blocks will be appended to the 
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
 # function's detailed documentation block.
 
 HIDE_IN_BODY_DOCS      = NO
 
-# The INTERNAL_DOCS tag determines if documentation 
-# that is typed after a \internal command is included. If the tag is set 
-# to NO (the default) then the documentation will be excluded. 
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
 # Set it to YES to include the internal documentation.
 
 INTERNAL_DOCS          = NO
 
-# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
-# file names in lower-case letters. If set to YES upper-case letters are also 
-# allowed. This is useful if you have classes or files whose names only differ 
-# in case and if your file system supports case sensitive file names. Windows 
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
 # and Mac users are advised to set this option to NO.
 
 CASE_SENSE_NAMES       = NO
 
-# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
-# will show members with their full class and namespace scopes in the 
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
 # documentation. If set to YES the scope will be hidden.
 
 HIDE_SCOPE_NAMES       = NO
 
-# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
-# will put a list of the files that are included by a file in the documentation 
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
 # of that file.
 
 SHOW_INCLUDE_FILES     = YES
 
-# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen 
-# will list include files with double quotes in the documentation 
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen
+# will list include files with double quotes in the documentation
 # rather than with sharp brackets.
 
 FORCE_LOCAL_INCLUDES   = NO
 
-# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
 # is inserted in the documentation for inline members.
 
 INLINE_INFO            = YES
 
-# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
-# will sort the (detailed) documentation of file and class members 
-# alphabetically by member name. If set to NO the members will appear in 
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
 # declaration order.
 
 SORT_MEMBER_DOCS       = YES
 
-# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
-# brief documentation of file, namespace and class members alphabetically 
-# by member name. If set to NO (the default) the members will appear in 
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
 # declaration order.
 
 SORT_BRIEF_DOCS        = NO
 
-# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen 
-# will sort the (brief and detailed) documentation of class members so that 
-# constructors and destructors are listed first. If set to NO (the default) 
-# the constructors will appear in the respective orders defined by 
-# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. 
-# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO 
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen
+# will sort the (brief and detailed) documentation of class members so that
+# constructors and destructors are listed first. If set to NO (the default)
+# the constructors will appear in the respective orders defined by
+# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS.
+# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO
 # and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
 
 SORT_MEMBERS_CTORS_1ST = NO
 
-# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the 
-# hierarchy of group names into alphabetical order. If set to NO (the default) 
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
+# hierarchy of group names into alphabetical order. If set to NO (the default)
 # the group names will appear in their defined order.
 
 SORT_GROUP_NAMES       = NO
 
-# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
-# sorted by fully-qualified names, including namespaces. If set to 
-# NO (the default), the class list will be sorted only by class name, 
-# not including the namespace part. 
-# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. 
-# Note: This option applies only to the class list, not to the 
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
 # alphabetical list.
 
 SORT_BY_SCOPE_NAME     = NO
 
-# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to 
-# do proper type resolution of all parameters of a function it will reject a 
-# match between the prototype and the implementation of a member function even 
-# if there is only one candidate or it is obvious which candidate to choose 
-# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen 
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to
+# do proper type resolution of all parameters of a function it will reject a
+# match between the prototype and the implementation of a member function even
+# if there is only one candidate or it is obvious which candidate to choose
+# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen
 # will still accept a match between prototype and implementation in such cases.
 
 STRICT_PROTO_MATCHING  = NO
 
-# The GENERATE_TODOLIST tag can be used to enable (YES) or 
-# disable (NO) the todo list. This list is created by putting \todo 
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
 # commands in the documentation.
 
 GENERATE_TODOLIST      = YES
 
-# The GENERATE_TESTLIST tag can be used to enable (YES) or 
-# disable (NO) the test list. This list is created by putting \test 
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
 # commands in the documentation.
 
 GENERATE_TESTLIST      = YES
 
-# The GENERATE_BUGLIST tag can be used to enable (YES) or 
-# disable (NO) the bug list. This list is created by putting \bug 
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
 # commands in the documentation.
 
 GENERATE_BUGLIST       = YES
 
-# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
-# disable (NO) the deprecated list. This list is created by putting 
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
 # \deprecated commands in the documentation.
 
 GENERATE_DEPRECATEDLIST= YES
 
-# The ENABLED_SECTIONS tag can be used to enable conditional 
+# The ENABLED_SECTIONS tag can be used to enable conditional
 # documentation sections, marked by \if sectionname ... \endif.
 
-ENABLED_SECTIONS       = 
+ENABLED_SECTIONS       =
 
-# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
-# the initial value of a variable or macro consists of for it to appear in 
-# the documentation. If the initializer consists of more lines than specified 
-# here it will be hidden. Use a value of 0 to hide initializers completely. 
-# The appearance of the initializer of individual variables and macros in the 
-# documentation can be controlled using \showinitializer or \hideinitializer 
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or macro consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and macros in the
+# documentation can be controlled using \showinitializer or \hideinitializer
 # command in the documentation regardless of this setting.
 
 MAX_INITIALIZER_LINES  = 30
 
-# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
-# at the bottom of the documentation of classes and structs. If set to YES the 
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
 # list will mention the files that were used to generate the documentation.
 
 SHOW_USED_FILES        = YES
 
-# If the sources in your project are distributed over multiple directories 
-# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 
-# in the documentation. The default is NO.
-
-SHOW_DIRECTORIES       = NO
-
-# Set the SHOW_FILES tag to NO to disable the generation of the Files page. 
-# This will remove the Files entry from the Quick Index and from the 
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
+# This will remove the Files entry from the Quick Index and from the
 # Folder Tree View (if specified). The default is YES.
 
 SHOW_FILES             = YES
 
-# Set the SHOW_NAMESPACES tag to NO to disable the generation of the 
-# Namespaces page.  This will remove the Namespaces entry from the Quick Index 
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
+# Namespaces page.
+# This will remove the Namespaces entry from the Quick Index
 # and from the Folder Tree View (if specified). The default is YES.
 
 SHOW_NAMESPACES        = YES
 
-# The FILE_VERSION_FILTER tag can be used to specify a program or script that 
-# doxygen should invoke to get the current version for each file (typically from 
-# the version control system). Doxygen will invoke the program by executing (via 
-# popen()) the command <command> <input-file>, where <command> is the value of 
-# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file 
-# provided by doxygen. Whatever the program writes to standard output 
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
+# provided by doxygen. Whatever the program writes to standard output
 # is used as the file version. See the manual for examples.
 
-FILE_VERSION_FILTER    = 
+FILE_VERSION_FILTER    =
 
-# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed 
-# by doxygen. The layout file controls the global structure of the generated 
-# output files in an output format independent way. The create the layout file 
-# that represents doxygen's defaults, run doxygen with the -l option. 
-# You can optionally specify a file name after the option, if omitted 
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option.
+# You can optionally specify a file name after the option, if omitted
 # DoxygenLayout.xml will be used as the name of the layout file.
 
-LAYOUT_FILE            = 
+LAYOUT_FILE            =
 
-# The CITE_BIB_FILES tag can be used to specify one or more bib files 
-# containing the references data. This must be a list of .bib files. The 
-# .bib extension is automatically appended if omitted. Using this command 
-# requires the bibtex tool to be installed. See also 
-# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style 
-# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this 
+# The CITE_BIB_FILES tag can be used to specify one or more bib files
+# containing the references data. This must be a list of .bib files. The
+# .bib extension is automatically appended if omitted. Using this command
+# requires the bibtex tool to be installed. See also
+# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style
+# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this
 # feature you need bibtex and perl available in the search path.
 
-CITE_BIB_FILES         = 
+CITE_BIB_FILES         =
 
 #---------------------------------------------------------------------------
 # configuration options related to warning and progress messages
 #---------------------------------------------------------------------------
 
-# The QUIET tag can be used to turn on/off the messages that are generated 
+# The QUIET tag can be used to turn on/off the messages that are generated
 # by doxygen. Possible values are YES and NO. If left blank NO is used.
 
 QUIET                  = NO
 
-# The WARNINGS tag can be used to turn on/off the warning messages that are 
-# generated by doxygen. Possible values are YES and NO. If left blank 
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
 # NO is used.
 
 WARNINGS               = YES
 
-# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
-# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
 # automatically be disabled.
 
 WARN_IF_UNDOCUMENTED   = YES
 
-# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
-# potential errors in the documentation, such as not documenting some 
-# parameters in a documented function, or documenting parameters that 
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
 # don't exist or using markup commands wrongly.
 
 WARN_IF_DOC_ERROR      = YES
 
-# The WARN_NO_PARAMDOC option can be enabled to get warnings for 
-# functions that are documented, but have no documentation for their parameters 
-# or return value. If set to NO (the default) doxygen will only warn about 
-# wrong or incomplete parameter documentation, but not about the absence of 
+# The WARN_NO_PARAMDOC option can be enabled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
 # documentation.
 
 WARN_NO_PARAMDOC       = NO
 
-# The WARN_FORMAT tag determines the format of the warning messages that 
-# doxygen can produce. The string should contain the $file, $line, and $text 
-# tags, which will be replaced by the file and line number from which the 
-# warning originated and the warning text. Optionally the format may contain 
-# $version, which will be replaced by the version of the file (if it could 
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
 # be obtained via FILE_VERSION_FILTER)
 
 WARN_FORMAT            = "$file:$line: $text"
 
-# The WARN_LOGFILE tag can be used to specify a file to which warning 
-# and error messages should be written. If left blank the output is written 
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
 # to stderr.
 
-WARN_LOGFILE           = 
+WARN_LOGFILE           =
 
 #---------------------------------------------------------------------------
 # configuration options related to the input files
 #---------------------------------------------------------------------------
 
-# The INPUT tag can be used to specify the files and/or directories that contain 
-# documented source files. You may enter file names like "myfile.cpp" or 
-# directories like "/usr/src/myproject". Separate the files or directories 
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
 # with spaces.
 
-INPUT                  = ./.
+INPUT                  = manual.txt
 
-# This tag can be used to specify the character encoding of the source files 
-# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is 
-# also the default input encoding. Doxygen uses libiconv (or the iconv built 
-# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for 
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
+# also the default input encoding. Doxygen uses libiconv (or the iconv built
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
 # the list of possible encodings.
 
 INPUT_ENCODING         = UTF-8
 
-# If the value of the INPUT tag contains directories, you can use the 
-# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
-# and *.h) to filter out the source-files in the directories. If left 
-# blank the following patterns are tested: 
-# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh 
-# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py 
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh
+# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py
 # *.f90 *.f *.for *.vhd *.vhdl
 
-FILE_PATTERNS          = *.c \
-                         *.cc \
-                         *.cxx \
-                         *.cpp \
-                         *.c++ \
-                         *.d \
-                         *.java \
-                         *.ii \
-                         *.ixx \
-                         *.ipp \
-                         *.i++ \
-                         *.inl \
-                         *.h \
-                         *.hh \
-                         *.hxx \
-                         *.hpp \
-                         *.h++ \
-                         *.idl \
-                         *.odl \
-                         *.cs \
-                         *.php \
-                         *.php3 \
-                         *.inc \
-                         *.m \
-                         *.mm \
-                         *.dox \
-                         *.py \
-                         *.f90 \
-                         *.f \
-                         *.for \
-                         *.vhd \
-                         *.vhdl
-
-# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
-# should be searched for input files as well. Possible values are YES and NO. 
+FILE_PATTERNS          = *.txt
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
 # If left blank NO is used.
 
-RECURSIVE              = YES
+RECURSIVE              = NO
 
-# The EXCLUDE tag can be used to specify files and/or directories that should be 
-# excluded from the INPUT source files. This way you can easily exclude a 
-# subdirectory from a directory tree whose root is specified with the INPUT tag. 
-# Note that relative paths are relative to the directory from which doxygen is 
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+# Note that relative paths are relative to the directory from which doxygen is
 # run.
 
-EXCLUDE                = 
+EXCLUDE                =
 
-# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or 
-# directories that are symbolic links (a Unix file system feature) are excluded 
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
 # from the input.
 
 EXCLUDE_SYMLINKS       = NO
 
-# If the value of the INPUT tag contains directories, you can use the 
-# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
-# certain files from those directories. Note that the wildcards are matched 
-# against the file with absolute path, so to exclude all test directories 
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
 # for example use the pattern */test/*
 
-EXCLUDE_PATTERNS       = 
+EXCLUDE_PATTERNS       =
 
-# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names 
-# (namespaces, classes, functions, etc.) that should be excluded from the 
-# output. The symbol name can be a fully qualified name, a word, or if the 
-# wildcard * is used, a substring. Examples: ANamespace, AClass, 
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
 # AClass::ANamespace, ANamespace::*Test
 
-EXCLUDE_SYMBOLS        = 
+EXCLUDE_SYMBOLS        =
 
-# The EXAMPLE_PATH tag can be used to specify one or more files or 
-# directories that contain example code fragments that are included (see 
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
 # the \include command).
 
-EXAMPLE_PATH           = 
+EXAMPLE_PATH           =
 
-# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
-# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
-# and *.h) to filter out the source-files in the directories. If left 
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
 # blank all files are included.
 
 EXAMPLE_PATTERNS       = *
 
-# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
-# searched for input files to be used with the \include or \dontinclude 
-# commands irrespective of the value of the RECURSIVE tag. 
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
 # Possible values are YES and NO. If left blank NO is used.
 
 EXAMPLE_RECURSIVE      = NO
 
-# The IMAGE_PATH tag can be used to specify one or more files or 
-# directories that contain image that are included in the documentation (see 
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
 # the \image command).
 
-IMAGE_PATH             = 
+IMAGE_PATH             = images \
+                       ../../icons
 
-# The INPUT_FILTER tag can be used to specify a program that doxygen should 
-# invoke to filter for each input file. Doxygen will invoke the filter program 
-# by executing (via popen()) the command <filter> <input-file>, where <filter> 
-# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
-# input file. Doxygen will then use the output that the filter program writes 
-# to standard output.  If FILTER_PATTERNS is specified, this tag will be 
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output.
+# If FILTER_PATTERNS is specified, this tag will be
 # ignored.
 
-INPUT_FILTER           = 
+INPUT_FILTER           =
 
-# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
-# basis.  Doxygen will compare the file name with each pattern and apply the 
-# filter if there is a match.  The filters are a list of the form: 
-# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
-# info on how filters are used. If FILTER_PATTERNS is empty or if 
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis.
+# Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match.
+# The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty or if
 # non of the patterns match the file name, INPUT_FILTER is applied.
 
-FILTER_PATTERNS        = 
+FILTER_PATTERNS        =
 
-# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
-# INPUT_FILTER) will be used to filter the input files when producing source 
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
 # files to browse (i.e. when SOURCE_BROWSER is set to YES).
 
 FILTER_SOURCE_FILES    = NO
 
-# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file 
-# pattern. A pattern will override the setting for FILTER_PATTERN (if any) 
-# and it is also possible to disable source filtering for a specific pattern 
-# using *.ext= (so without naming a filter). This option only has effect when 
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any)
+# and it is also possible to disable source filtering for a specific pattern
+# using *.ext= (so without naming a filter). This option only has effect when
 # FILTER_SOURCE_FILES is enabled.
 
-FILTER_SOURCE_PATTERNS = 
+FILTER_SOURCE_PATTERNS =
 
 #---------------------------------------------------------------------------
 # configuration options related to source browsing
 #---------------------------------------------------------------------------
 
-# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
-# be generated. Documented entities will be cross-referenced with these sources. 
-# Note: To get rid of all source code in the generated output, make sure also 
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
 # VERBATIM_HEADERS is set to NO.
 
 SOURCE_BROWSER         = NO
 
-# Setting the INLINE_SOURCES tag to YES will include the body 
+# Setting the INLINE_SOURCES tag to YES will include the body
 # of functions and classes directly in the documentation.
 
 INLINE_SOURCES         = NO
 
-# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
-# doxygen to hide any special comment blocks from generated source code 
-# fragments. Normal C and C++ comments will always remain visible.
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C, C++ and Fortran comments will always remain visible.
 
 STRIP_CODE_COMMENTS    = YES
 
-# If the REFERENCED_BY_RELATION tag is set to YES 
-# then for each documented function all documented 
+# If the REFERENCED_BY_RELATION tag is set to YES
+# then for each documented function all documented
 # functions referencing it will be listed.
 
 REFERENCED_BY_RELATION = NO
 
-# If the REFERENCES_RELATION tag is set to YES 
-# then for each documented function all documented entities 
+# If the REFERENCES_RELATION tag is set to YES
+# then for each documented function all documented entities
 # called/used by that function will be listed.
 
 REFERENCES_RELATION    = NO
 
-# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) 
-# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from 
-# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will 
-# link to the source code.  Otherwise they will link to the documentation.
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code.
+# Otherwise they will link to the documentation.
 
-REFERENCES_LINK_SOURCE = YES
+REFERENCES_LINK_SOURCE = NO
 
-# If the USE_HTAGS tag is set to YES then the references to source code 
-# will point to the HTML generated by the htags(1) tool instead of doxygen 
-# built-in source browser. The htags tool is part of GNU's global source 
-# tagging system (see http://www.gnu.org/software/global/global.html). You 
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
 # will need version 4.8.6 or higher.
 
 USE_HTAGS              = NO
 
-# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
-# will generate a verbatim copy of the header file for each class for 
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
 # which an include is specified. Set to NO to disable this.
 
 VERBATIM_HEADERS       = YES
@@ -862,157 +828,160 @@ VERBATIM_HEADERS       = YES
 # configuration options related to the alphabetical class index
 #---------------------------------------------------------------------------
 
-# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
-# of all compounds will be generated. Enable this if the project 
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
 # contains a lot of classes, structs, unions or interfaces.
 
 ALPHABETICAL_INDEX     = YES
 
-# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
-# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
 # in which this list will be split (can be a number in the range [1..20])
 
 COLS_IN_ALPHA_INDEX    = 5
 
-# In case all classes in a project start with a common prefix, all 
-# classes will be put under the same header in the alphabetical index. 
-# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
 # should be ignored while generating the index headers.
 
-IGNORE_PREFIX          = 
+IGNORE_PREFIX          =
 
 #---------------------------------------------------------------------------
 # configuration options related to the HTML output
 #---------------------------------------------------------------------------
 
-# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
 # generate HTML output.
 
 GENERATE_HTML          = YES
 
-# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
 # put in front of it. If left blank `html' will be used as the default path.
 
-HTML_OUTPUT            = html
+HTML_OUTPUT            = manual
 
-# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
-# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
 # doxygen will generate files with .html extension.
 
 HTML_FILE_EXTENSION    = .html
 
-# The HTML_HEADER tag can be used to specify a personal HTML header for 
-# each generated HTML page. If it is left blank doxygen will generate a 
-# standard header. Note that when using a custom header you are responsible  
-# for the proper inclusion of any scripts and style sheets that doxygen 
-# needs, which is dependent on the configuration options used. 
-# It is advised to generate a default header using "doxygen -w html 
-# header.html footer.html stylesheet.css YourConfigFile" and then modify 
-# that header. Note that the header is subject to change so you typically 
-# have to redo this when upgrading to a newer version of doxygen or when 
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header. Note that when using a custom header you are responsible
+#  for the proper inclusion of any scripts and style sheets that doxygen
+# needs, which is dependent on the configuration options used.
+# It is advised to generate a default header using "doxygen -w html
+# header.html footer.html stylesheet.css YourConfigFile" and then modify
+# that header. Note that the header is subject to change so you typically
+# have to redo this when upgrading to a newer version of doxygen or when
 # changing the value of configuration settings such as GENERATE_TREEVIEW!
 
-HTML_HEADER            = 
+HTML_HEADER            =
 
-# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
-# each generated HTML page. If it is left blank doxygen will generate a 
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
 # standard footer.
 
-HTML_FOOTER            = 
+HTML_FOOTER            =
 
-# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
-# style sheet that is used by each HTML page. It can be used to 
-# fine-tune the look of the HTML output. If the tag is left blank doxygen 
-# will generate a default style sheet. Note that doxygen will try to copy 
-# the style sheet file to the HTML output directory, so don't put your own 
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet. Note that doxygen will try to copy
+# the style sheet file to the HTML output directory, so don't put your own
 # style sheet in the HTML output directory as well, or it will be erased!
 
-HTML_STYLESHEET        = 
+HTML_STYLESHEET        = qsstv.css
 
-# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or 
-# other source files which should be copied to the HTML output directory. Note 
-# that these files will be copied to the base HTML output directory. Use the 
-# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these 
-# files. In the HTML_STYLESHEET file, use the file name only. Also note that 
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that
 # the files will be copied as-is; there are no commands or markers available.
 
-HTML_EXTRA_FILES       = 
+HTML_EXTRA_FILES       =
 
-# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. 
-# Doxygen will adjust the colors in the style sheet and background images 
-# according to this color. Hue is specified as an angle on a colorwheel, 
-# see http://en.wikipedia.org/wiki/Hue for more information. 
-# For instance the value 0 represents red, 60 is yellow, 120 is green, 
-# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. 
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output.
+# Doxygen will adjust the colors in the style sheet and background images
+# according to this color. Hue is specified as an angle on a colorwheel,
+# see http://en.wikipedia.org/wiki/Hue for more information.
+# For instance the value 0 represents red, 60 is yellow, 120 is green,
+# 180 is cyan, 240 is blue, 300 purple, and 360 is red again.
 # The allowed range is 0 to 359.
 
 HTML_COLORSTYLE_HUE    = 220
 
-# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of 
-# the colors in the HTML output. For a value of 0 the output will use 
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of
+# the colors in the HTML output. For a value of 0 the output will use
 # grayscales only. A value of 255 will produce the most vivid colors.
 
 HTML_COLORSTYLE_SAT    = 100
 
-# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to 
-# the luminance component of the colors in the HTML output. Values below 
-# 100 gradually make the output lighter, whereas values above 100 make 
-# the output darker. The value divided by 100 is the actual gamma applied, 
-# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, 
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to
+# the luminance component of the colors in the HTML output. Values below
+# 100 gradually make the output lighter, whereas values above 100 make
+# the output darker. The value divided by 100 is the actual gamma applied,
+# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2,
 # and 100 does not change the gamma.
 
 HTML_COLORSTYLE_GAMMA  = 80
 
-# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML 
-# page will contain the date and time when the page was generated. Setting 
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting
 # this to NO can help when comparing the output of multiple runs.
 
 HTML_TIMESTAMP         = YES
 
-# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
-# files or namespaces will be aligned in HTML using tables. If set to 
-# NO a bullet list will be used.
-
-HTML_ALIGN_MEMBERS     = YES
-
-# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML 
-# documentation will contain sections that can be hidden and shown after the 
-# page has loaded. For this to work a browser that supports 
-# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox 
-# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded.
 
 HTML_DYNAMIC_SECTIONS  = NO
 
-# If the GENERATE_DOCSET tag is set to YES, additional index files 
-# will be generated that can be used as input for Apple's Xcode 3 
-# integrated development environment, introduced with OSX 10.5 (Leopard). 
-# To create a documentation set, doxygen will generate a Makefile in the 
-# HTML output directory. Running make will produce the docset in that 
-# directory and running "make install" will install the docset in 
-# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find 
-# it at startup. 
-# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html 
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of
+# entries shown in the various tree structured indices initially; the user
+# can expand and collapse entries dynamically later on. Doxygen will expand
+# the tree to such a level that at most the specified number of entries are
+# visible (unless a fully collapsed tree already exceeds this amount).
+# So setting the number of entries 1 will produce a full collapsed tree by
+# default. 0 is a special value representing an infinite number of entries
+# and will result in a full expanded tree by default.
+
+HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files
+# will be generated that can be used as input for Apple's Xcode 3
+# integrated development environment, introduced with OSX 10.5 (Leopard).
+# To create a documentation set, doxygen will generate a Makefile in the
+# HTML output directory. Running make will produce the docset in that
+# directory and running "make install" will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
+# it at startup.
+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
 # for more information.
 
 GENERATE_DOCSET        = NO
 
-# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the 
-# feed. A documentation feed provides an umbrella under which multiple 
-# documentation sets from a single provider (such as a company or product suite) 
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
+# feed. A documentation feed provides an umbrella under which multiple
+# documentation sets from a single provider (such as a company or product suite)
 # can be grouped.
 
 DOCSET_FEEDNAME        = "Doxygen generated docs"
 
-# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that 
-# should uniquely identify the documentation set bundle. This should be a 
-# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen 
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
+# should uniquely identify the documentation set bundle. This should be a
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
 # will append .docset to the name.
 
 DOCSET_BUNDLE_ID       = org.doxygen.Project
 
-# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify 
-# the documentation publisher. This should be a reverse domain-name style 
+# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify
+# the documentation publisher. This should be a reverse domain-name style
 # string, e.g. com.mycompany.MyDocSet.documentation.
 
 DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
@@ -1021,220 +990,216 @@ DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
 
 DOCSET_PUBLISHER_NAME  = Publisher
 
-# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
-# will be generated that can be used as input for tools like the 
-# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) 
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
 # of the generated HTML documentation.
 
 GENERATE_HTMLHELP      = NO
 
-# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
-# be used to specify the file name of the resulting .chm file. You 
-# can add a path in front of the file if the result should not be 
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
 # written to the html output directory.
 
-CHM_FILE               = 
+CHM_FILE               =
 
-# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
-# be used to specify the location (absolute path including file name) of 
-# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
 # the HTML help compiler on the generated index.hhp.
 
-HHC_LOCATION           = 
+HHC_LOCATION           =
 
-# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
-# controls if a separate .chi index file is generated (YES) or that 
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
 # it should be included in the master .chm file (NO).
 
 GENERATE_CHI           = NO
 
-# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING 
-# is used to encode HtmlHelp index (hhk), content (hhc) and project file 
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file
 # content.
 
-CHM_INDEX_ENCODING     = 
+CHM_INDEX_ENCODING     =
 
-# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
-# controls whether a binary table of contents is generated (YES) or a 
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
 # normal table of contents (NO) in the .chm file.
 
 BINARY_TOC             = NO
 
-# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
 # to the contents of the HTML help documentation and to the tree view.
 
 TOC_EXPAND             = NO
 
-# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and 
-# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated 
-# that can be used as input for Qt's qhelpgenerator to generate a 
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated
+# that can be used as input for Qt's qhelpgenerator to generate a
 # Qt Compressed Help (.qch) of the generated HTML documentation.
 
 GENERATE_QHP           = NO
 
-# If the QHG_LOCATION tag is specified, the QCH_FILE tag can 
-# be used to specify the file name of the resulting .qch file. 
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can
+# be used to specify the file name of the resulting .qch file.
 # The path specified is relative to the HTML output folder.
 
-QCH_FILE               = 
+QCH_FILE               =
 
-# The QHP_NAMESPACE tag specifies the namespace to use when generating 
-# Qt Help Project output. For more information please see 
+# The QHP_NAMESPACE tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
 # http://doc.trolltech.com/qthelpproject.html#namespace
 
 QHP_NAMESPACE          = org.doxygen.Project
 
-# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating 
-# Qt Help Project output. For more information please see 
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
 # http://doc.trolltech.com/qthelpproject.html#virtual-folders
 
 QHP_VIRTUAL_FOLDER     = doc
 
-# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to 
-# add. For more information please see 
+# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to
+# add. For more information please see
 # http://doc.trolltech.com/qthelpproject.html#custom-filters
 
-QHP_CUST_FILTER_NAME   = 
+QHP_CUST_FILTER_NAME   =
 
-# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the 
-# custom filter to add. For more information please see 
-# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters"> 
+# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">
 # Qt Help Project / Custom Filters</a>.
 
-QHP_CUST_FILTER_ATTRS  = 
+QHP_CUST_FILTER_ATTRS  =
 
-# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this 
-# project's 
-# filter section matches. 
-# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes"> 
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's
+# filter section matches.
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">
 # Qt Help Project / Filter Attributes</a>.
 
-QHP_SECT_FILTER_ATTRS  = 
+QHP_SECT_FILTER_ATTRS  =
 
-# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can 
-# be used to specify the location of Qt's qhelpgenerator. 
-# If non-empty doxygen will try to run qhelpgenerator on the generated 
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can
+# be used to specify the location of Qt's qhelpgenerator.
+# If non-empty doxygen will try to run qhelpgenerator on the generated
 # .qhp file.
 
-QHG_LOCATION           = 
+QHG_LOCATION           =
 
-# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files  
-# will be generated, which together with the HTML files, form an Eclipse help 
-# plugin. To install this plugin and make it available under the help contents 
-# menu in Eclipse, the contents of the directory containing the HTML and XML 
-# files needs to be copied into the plugins directory of eclipse. The name of 
-# the directory within the plugins directory should be the same as 
-# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before 
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files
+#  will be generated, which together with the HTML files, form an Eclipse help
+# plugin. To install this plugin and make it available under the help contents
+# menu in Eclipse, the contents of the directory containing the HTML and XML
+# files needs to be copied into the plugins directory of eclipse. The name of
+# the directory within the plugins directory should be the same as
+# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before
 # the help appears.
 
 GENERATE_ECLIPSEHELP   = NO
 
-# A unique identifier for the eclipse help plugin. When installing the plugin 
-# the directory name containing the HTML and XML files should also have 
+# A unique identifier for the eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have
 # this name.
 
 ECLIPSE_DOC_ID         = org.doxygen.Project
 
-# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) 
-# at top of each HTML page. The value NO (the default) enables the index and 
-# the value YES disables it. Since the tabs have the same information as the 
-# navigation tree you can set this option to NO if you already set 
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs)
+# at top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it. Since the tabs have the same information as the
+# navigation tree you can set this option to NO if you already set
 # GENERATE_TREEVIEW to YES.
 
 DISABLE_INDEX          = NO
 
-# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index 
-# structure should be generated to display hierarchical information. 
-# If the tag value is set to YES, a side panel will be generated 
-# containing a tree-like index structure (just like the one that 
-# is generated for HTML Help). For this to work a browser that supports 
-# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). 
-# Windows users are probably better off using the HTML help feature. 
-# Since the tree basically has the same information as the tab index you 
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information.
+# If the tag value is set to YES, a side panel will be generated
+# containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).
+# Windows users are probably better off using the HTML help feature.
+# Since the tree basically has the same information as the tab index you
 # could consider to set DISABLE_INDEX to NO when enabling this option.
 
-GENERATE_TREEVIEW      = NO
+GENERATE_TREEVIEW      = YES
 
-# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values 
-# (range [0,1..20]) that doxygen will group on one line in the generated HTML 
-# documentation. Note that a value of 0 will completely suppress the enum 
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values
+# (range [0,1..20]) that doxygen will group on one line in the generated HTML
+# documentation. Note that a value of 0 will completely suppress the enum
 # values from appearing in the overview section.
 
 ENUM_VALUES_PER_LINE   = 4
 
-# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, 
-# and Class Hierarchy pages using a tree view instead of an ordered list.
-
-USE_INLINE_TREES       = NO
-
-# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
-# used to set the initial width (in pixels) of the frame in which the tree 
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
 # is shown.
 
 TREEVIEW_WIDTH         = 250
 
-# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open 
+# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open
 # links to external symbols imported via tag files in a separate window.
 
 EXT_LINKS_IN_WINDOW    = NO
 
-# Use this tag to change the font size of Latex formulas included 
-# as images in the HTML documentation. The default is 10. Note that 
-# when you change the font size after a successful doxygen run you need 
-# to manually remove any form_*.png images from the HTML output directory 
+# Use this tag to change the font size of Latex formulas included
+# as images in the HTML documentation. The default is 10. Note that
+# when you change the font size after a successful doxygen run you need
+# to manually remove any form_*.png images from the HTML output directory
 # to force them to be regenerated.
 
 FORMULA_FONTSIZE       = 10
 
-# Use the FORMULA_TRANPARENT tag to determine whether or not the images 
-# generated for formulas are transparent PNGs. Transparent PNGs are 
-# not supported properly for IE 6.0, but are supported on all modern browsers. 
-# Note that when changing this option you need to delete any form_*.png files 
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are
+# not supported properly for IE 6.0, but are supported on all modern browsers.
+# Note that when changing this option you need to delete any form_*.png files
 # in the HTML output before the changes have effect.
 
 FORMULA_TRANSPARENT    = YES
 
-# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax 
-# (see http://www.mathjax.org) which uses client side Javascript for the 
-# rendering instead of using prerendered bitmaps. Use this if you do not 
-# have LaTeX installed or if you want to formulas look prettier in the HTML 
-# output. When enabled you also need to install MathJax separately and 
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax
+# (see http://www.mathjax.org) which uses client side Javascript for the
+# rendering instead of using prerendered bitmaps. Use this if you do not
+# have LaTeX installed or if you want to formulas look prettier in the HTML
+# output. When enabled you may also need to install MathJax separately and
 # configure the path to it using the MATHJAX_RELPATH option.
 
 USE_MATHJAX            = NO
 
-# When MathJax is enabled you need to specify the location relative to the 
-# HTML output directory using the MATHJAX_RELPATH option. The destination 
-# directory should contain the MathJax.js script. For instance, if the mathjax 
-# directory is located at the same level as the HTML output directory, then 
-# MATHJAX_RELPATH should be ../mathjax. The default value points to the 
-# mathjax.org site, so you can quickly see the result without installing 
-# MathJax, but it is strongly recommended to install a local copy of MathJax 
-# before deployment.
+# When MathJax is enabled you need to specify the location relative to the
+# HTML output directory using the MATHJAX_RELPATH option. The destination
+# directory should contain the MathJax.js script. For instance, if the mathjax
+# directory is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to
+# the MathJax Content Delivery Network so you can quickly see the result without
+# installing MathJax.
+# However, it is strongly recommended to install a local
+# copy of MathJax from http://www.mathjax.org before deployment.
 
-MATHJAX_RELPATH        = http://www.mathjax.org/mathjax
+MATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest
 
-# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension 
+# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension
 # names that should be enabled during MathJax rendering.
 
-MATHJAX_EXTENSIONS     = 
+MATHJAX_EXTENSIONS     =
 
-# When the SEARCHENGINE tag is enabled doxygen will generate a search box 
-# for the HTML output. The underlying search engine uses javascript 
-# and DHTML and should work on any modern browser. Note that when using 
-# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets 
-# (GENERATE_DOCSET) there is already a search function so this one should 
-# typically be disabled. For large projects the javascript based search engine 
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box
+# for the HTML output. The underlying search engine uses javascript
+# and DHTML and should work on any modern browser. Note that when using
+# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets
+# (GENERATE_DOCSET) there is already a search function so this one should
+# typically be disabled. For large projects the javascript based search engine
 # can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
 
-SEARCHENGINE           = YES
+SEARCHENGINE           = NO
 
-# When the SERVER_BASED_SEARCH tag is enabled the search engine will be 
-# implemented using a PHP enabled web server instead of at the web client 
-# using Javascript. Doxygen will generate the search PHP script and index 
-# file to put on the web server. The advantage of the server 
-# based approach is that it scales better to large projects and allows 
-# full text search. The disadvantages are that it is more difficult to setup 
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a PHP enabled web server instead of at the web client
+# using Javascript. Doxygen will generate the search PHP script and index
+# file to put on the web server. The advantage of the server
+# based approach is that it scales better to large projects and allows
+# full text search. The disadvantages are that it is more difficult to setup
 # and does not have live searching capabilities.
 
 SERVER_BASED_SEARCH    = NO
@@ -1243,97 +1208,97 @@ SERVER_BASED_SEARCH    = NO
 # configuration options related to the LaTeX output
 #---------------------------------------------------------------------------
 
-# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
 # generate Latex output.
 
 GENERATE_LATEX         = NO
 
-# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
 # put in front of it. If left blank `latex' will be used as the default path.
 
 LATEX_OUTPUT           = latex
 
-# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
-# invoked. If left blank `latex' will be used as the default command name. 
-# Note that when enabling USE_PDFLATEX this option is only used for 
-# generating bitmaps for formulas in the HTML output, but not in the 
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+# Note that when enabling USE_PDFLATEX this option is only used for
+# generating bitmaps for formulas in the HTML output, but not in the
 # Makefile that is written to the output directory.
 
 LATEX_CMD_NAME         = latex
 
-# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
-# generate index for LaTeX. If left blank `makeindex' will be used as the 
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
 # default command name.
 
 MAKEINDEX_CMD_NAME     = makeindex
 
-# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
-# LaTeX documents. This may be useful for small projects and may help to 
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
 # save some trees in general.
 
 COMPACT_LATEX          = NO
 
-# The PAPER_TYPE tag can be used to set the paper type that is used 
-# by the printer. Possible values are: a4, letter, legal and 
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, letter, legal and
 # executive. If left blank a4wide will be used.
 
-PAPER_TYPE             = a4
+PAPER_TYPE             = a4wide
 
-# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
 # packages that should be included in the LaTeX output.
 
-EXTRA_PACKAGES         = 
+EXTRA_PACKAGES         =
 
-# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
-# the generated latex document. The header should contain everything until 
-# the first chapter. If it is left blank doxygen will generate a 
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
 # standard header. Notice: only use this tag if you know what you are doing!
 
-LATEX_HEADER           = 
+LATEX_HEADER           =
 
-# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for 
-# the generated latex document. The footer should contain everything after 
-# the last chapter. If it is left blank doxygen will generate a 
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for
+# the generated latex document. The footer should contain everything after
+# the last chapter. If it is left blank doxygen will generate a
 # standard footer. Notice: only use this tag if you know what you are doing!
 
-LATEX_FOOTER           = 
+LATEX_FOOTER           =
 
-# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
-# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
-# contain links (just like the HTML output) instead of page references 
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
 # This makes the output suitable for online browsing using a pdf viewer.
 
 PDF_HYPERLINKS         = YES
 
-# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
-# plain latex in the generated Makefile. Set this option to YES to get a 
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
 # higher quality PDF documentation.
 
 USE_PDFLATEX           = YES
 
-# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
-# command to the generated LaTeX files. This will instruct LaTeX to keep 
-# running if errors occur, instead of asking the user for help. 
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
 # This option is also used when generating formulas in HTML.
 
 LATEX_BATCHMODE        = NO
 
-# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
-# include the index chapters (such as File Index, Compound Index, etc.) 
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
 # in the output.
 
 LATEX_HIDE_INDICES     = NO
 
-# If LATEX_SOURCE_CODE is set to YES then doxygen will include 
-# source code with syntax highlighting in the LaTeX output. 
-# Note that which sources are shown also depends on other settings 
+# If LATEX_SOURCE_CODE is set to YES then doxygen will include
+# source code with syntax highlighting in the LaTeX output.
+# Note that which sources are shown also depends on other settings
 # such as SOURCE_BROWSER.
 
 LATEX_SOURCE_CODE      = NO
 
-# The LATEX_BIB_STYLE tag can be used to specify the style to use for the 
-# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See 
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See
 # http://en.wikipedia.org/wiki/BibTeX for more info.
 
 LATEX_BIB_STYLE        = plain
@@ -1342,68 +1307,68 @@ LATEX_BIB_STYLE        = plain
 # configuration options related to the RTF output
 #---------------------------------------------------------------------------
 
-# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
-# The RTF output is optimized for Word 97 and may not look very pretty with 
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
 # other RTF readers or editors.
 
 GENERATE_RTF           = NO
 
-# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
 # put in front of it. If left blank `rtf' will be used as the default path.
 
 RTF_OUTPUT             = rtf
 
-# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
-# RTF documents. This may be useful for small projects and may help to 
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
 # save some trees in general.
 
 COMPACT_RTF            = NO
 
-# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
-# will contain hyperlink fields. The RTF file will 
-# contain links (just like the HTML output) instead of page references. 
-# This makes the output suitable for online browsing using WORD or other 
-# programs which support those fields. 
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
 # Note: wordpad (write) and others do not support links.
 
 RTF_HYPERLINKS         = NO
 
-# Load style sheet definitions from file. Syntax is similar to doxygen's 
-# config file, i.e. a series of assignments. You only have to provide 
+# Load style sheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
 # replacements, missing definitions are set to their default value.
 
-RTF_STYLESHEET_FILE    = 
+RTF_STYLESHEET_FILE    =
 
-# Set optional variables used in the generation of an rtf document. 
+# Set optional variables used in the generation of an rtf document.
 # Syntax is similar to doxygen's config file.
 
-RTF_EXTENSIONS_FILE    = 
+RTF_EXTENSIONS_FILE    =
 
 #---------------------------------------------------------------------------
 # configuration options related to the man page output
 #---------------------------------------------------------------------------
 
-# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
 # generate man pages
 
 GENERATE_MAN           = NO
 
-# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
 # put in front of it. If left blank `man' will be used as the default path.
 
 MAN_OUTPUT             = man
 
-# The MAN_EXTENSION tag determines the extension that is added to 
+# The MAN_EXTENSION tag determines the extension that is added to
 # the generated man pages (default is the subroutine's section .3)
 
 MAN_EXTENSION          = .3
 
-# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
-# then it will generate one additional man file for each entity 
-# documented in the real man page(s). These additional files 
-# only source the real man page, but without them the man command 
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
 # would be unable to find the correct page. The default is NO.
 
 MAN_LINKS              = NO
@@ -1412,33 +1377,22 @@ MAN_LINKS              = NO
 # configuration options related to the XML output
 #---------------------------------------------------------------------------
 
-# If the GENERATE_XML tag is set to YES Doxygen will 
-# generate an XML file that captures the structure of 
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
 # the code including all documentation.
 
 GENERATE_XML           = NO
 
-# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
 # put in front of it. If left blank `xml' will be used as the default path.
 
 XML_OUTPUT             = xml
 
-# The XML_SCHEMA tag can be used to specify an XML schema, 
-# which can be used by a validating XML parser to check the 
-# syntax of the XML files.
-
-XML_SCHEMA             = 
 
-# The XML_DTD tag can be used to specify an XML DTD, 
-# which can be used by a validating XML parser to check the 
-# syntax of the XML files.
-
-XML_DTD                = 
-
-# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
-# dump the program listings (including syntax highlighting 
-# and cross-referencing information) to the XML output. Note that 
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
 # enabling this will significantly increase the size of the XML output.
 
 XML_PROGRAMLISTING     = YES
@@ -1447,10 +1401,10 @@ XML_PROGRAMLISTING     = YES
 # configuration options for the AutoGen Definitions output
 #---------------------------------------------------------------------------
 
-# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
-# generate an AutoGen Definitions (see autogen.sf.net) file 
-# that captures the structure of the code including all 
-# documentation. Note that this feature is still experimental 
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
 # and incomplete at the moment.
 
 GENERATE_AUTOGEN_DEF   = NO
@@ -1459,97 +1413,99 @@ GENERATE_AUTOGEN_DEF   = NO
 # configuration options related to the Perl module output
 #---------------------------------------------------------------------------
 
-# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
-# generate a Perl module file that captures the structure of 
-# the code including all documentation. Note that this 
-# feature is still experimental and incomplete at the 
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
 # moment.
 
 GENERATE_PERLMOD       = NO
 
-# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
-# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
 # to generate PDF and DVI output from the Perl module output.
 
 PERLMOD_LATEX          = NO
 
-# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
-# nicely formatted so it can be parsed by a human reader.  This is useful 
-# if you want to understand what is going on.  On the other hand, if this 
-# tag is set to NO the size of the Perl module output will be much smaller 
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader.
+# This is useful
+# if you want to understand what is going on.
+# On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
 # and Perl will parse it just the same.
 
 PERLMOD_PRETTY         = YES
 
-# The names of the make variables in the generated doxyrules.make file 
-# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
-# This is useful so different doxyrules.make files included by the same 
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
 # Makefile don't overwrite each other's variables.
 
-PERLMOD_MAKEVAR_PREFIX = 
+PERLMOD_MAKEVAR_PREFIX =
 
 #---------------------------------------------------------------------------
 # Configuration options related to the preprocessor
 #---------------------------------------------------------------------------
 
-# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
-# evaluate all C-preprocessor directives found in the sources and include 
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
 # files.
 
 ENABLE_PREPROCESSING   = YES
 
-# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
-# names in the source code. If set to NO (the default) only conditional 
-# compilation will be performed. Macro expansion can be done in a controlled 
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
 # way by setting EXPAND_ONLY_PREDEF to YES.
 
 MACRO_EXPANSION        = NO
 
-# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
-# then the macro expansion is limited to the macros specified with the 
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
 # PREDEFINED and EXPAND_AS_DEFINED tags.
 
 EXPAND_ONLY_PREDEF     = NO
 
-# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
 # pointed to by INCLUDE_PATH will be searched when a #include is found.
 
 SEARCH_INCLUDES        = YES
 
-# The INCLUDE_PATH tag can be used to specify one or more directories that 
-# contain include files that are not input files but should be processed by 
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
 # the preprocessor.
 
-INCLUDE_PATH           = 
+INCLUDE_PATH           =
 
-# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
-# patterns (like *.h and *.hpp) to filter out the header-files in the 
-# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
 # be used.
 
-INCLUDE_FILE_PATTERNS  = 
+INCLUDE_FILE_PATTERNS  =
 
-# The PREDEFINED tag can be used to specify one or more macro names that 
-# are defined before the preprocessor is started (similar to the -D option of 
-# gcc). The argument of the tag is a list of macros of the form: name 
-# or name=definition (no spaces). If the definition and the = are 
-# omitted =1 is assumed. To prevent a macro definition from being 
-# undefined via #undef or recursively expanded use the := operator 
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
 # instead of the = operator.
 
-PREDEFINED             = 
+PREDEFINED             =
 
-# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
-# this tag can be used to specify a list of macro names that should be expanded. 
-# The macro definition that is found in the sources will be used. 
-# Use the PREDEFINED tag if you want to use a different macro definition that 
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition that
 # overrules the definition found in the source code.
 
-EXPAND_AS_DEFINED      = 
+EXPAND_AS_DEFINED      =
 
-# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
-# doxygen's preprocessor will remove all references to function-like macros 
-# that are alone on a line, have an all uppercase name, and do not end with a 
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all references to function-like macros
+# that are alone on a line, have an all uppercase name, and do not end with a
 # semicolon, because these will confuse the parser if not removed.
 
 SKIP_FUNCTION_MACROS   = YES
@@ -1558,41 +1514,39 @@ SKIP_FUNCTION_MACROS   = YES
 # Configuration::additions related to external references
 #---------------------------------------------------------------------------
 
-# The TAGFILES option can be used to specify one or more tagfiles. 
-# Optionally an initial location of the external documentation 
-# can be added for each tagfile. The format of a tag file without 
-# this location is as follows: 
-#   TAGFILES = file1 file2 ... 
-# Adding location for the tag files is done as follows: 
-#   TAGFILES = file1=loc1 "file2 = loc2" ... 
-# where "loc1" and "loc2" can be relative or absolute paths or 
-# URLs. If a location is present for each tag, the installdox tool 
-# does not have to be run to correct the links. 
-# Note that each tag file must have a unique name 
-# (where the name does NOT include the path) 
-# If a tag file is not located in the directory in which doxygen 
-# is run, you must also specify the path to the tagfile here.
-
-TAGFILES               = 
-
-# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# The TAGFILES option can be used to specify one or more tagfiles. For each
+# tag file the location of the external documentation should be added. The
+# format of a tag file without this location is as follows:
+#
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+#
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths
+# or URLs. Note that each tag file must have a unique name (where the name does
+# NOT include the path). If a tag file is not located in the directory in which
+# doxygen is run, you must also specify the path to the tagfile here.
+
+TAGFILES               =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
 # a tag file that is based on the input files it reads.
 
-GENERATE_TAGFILE       = 
+GENERATE_TAGFILE       =
 
-# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
-# in the class index. If set to NO only the inherited external classes 
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
 # will be listed.
 
 ALLEXTERNALS           = NO
 
-# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
-# in the modules index. If set to NO, only the current project's groups will 
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
 # be listed.
 
 EXTERNAL_GROUPS        = YES
 
-# The PERL_PATH should be the absolute path and name of the perl script 
+# The PERL_PATH should be the absolute path and name of the perl script
 # interpreter (i.e. the result of `which perl').
 
 PERL_PATH              = /usr/bin/perl
@@ -1601,213 +1555,222 @@ PERL_PATH              = /usr/bin/perl
 # Configuration options related to the dot tool
 #---------------------------------------------------------------------------
 
-# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
-# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 
-# or super classes. Setting the tag to NO turns the diagrams off. Note that 
-# this option also works with HAVE_DOT disabled, but it is recommended to 
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option also works with HAVE_DOT disabled, but it is recommended to
 # install and use dot, since it yields more powerful graphs.
 
-CLASS_DIAGRAMS         = YES
+CLASS_DIAGRAMS         = NO
 
-# You can define message sequence charts within doxygen comments using the \msc 
-# command. Doxygen will then run the mscgen tool (see 
-# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the 
-# documentation. The MSCGEN_PATH tag allows you to specify the directory where 
-# the mscgen tool resides. If left empty the tool is assumed to be found in the 
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
 # default search path.
 
-MSCGEN_PATH            = 
+MSCGEN_PATH            =
 
-# If set to YES, the inheritance and collaboration graphs will hide 
-# inheritance and usage relations if the target is undocumented 
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
 # or is not a class.
 
 HIDE_UNDOC_RELATIONS   = YES
 
-# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
-# available from the path. This tool is part of Graphviz, a graph visualization 
-# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
 # have no effect if this option is set to NO (the default)
 
 HAVE_DOT               = NO
 
-# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is 
-# allowed to run in parallel. When set to 0 (the default) doxygen will 
-# base this on the number of processors available in the system. You can set it 
-# explicitly to a value larger than 0 to get control over the balance 
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is
+# allowed to run in parallel. When set to 0 (the default) doxygen will
+# base this on the number of processors available in the system. You can set it
+# explicitly to a value larger than 0 to get control over the balance
 # between CPU load and processing speed.
 
 DOT_NUM_THREADS        = 0
 
-# By default doxygen will use the Helvetica font for all dot files that 
-# doxygen generates. When you want a differently looking font you can specify 
-# the font name using DOT_FONTNAME. You need to make sure dot is able to find 
-# the font, which can be done by putting it in a standard location or by setting 
-# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the 
+# By default doxygen will use the Helvetica font for all dot files that
+# doxygen generates. When you want a differently looking font you can specify
+# the font name using DOT_FONTNAME. You need to make sure dot is able to find
+# the font, which can be done by putting it in a standard location or by setting
+# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the
 # directory containing the font.
 
-DOT_FONTNAME           = Helvetica
+#DOT_FONTNAME           = FreeSans.ttf
 
-# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. 
+# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
 # The default size is 10pt.
 
 DOT_FONTSIZE           = 10
 
-# By default doxygen will tell dot to use the Helvetica font. 
-# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to 
+# By default doxygen will tell dot to use the Helvetica font.
+# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to
 # set the path where dot can find it.
 
-DOT_FONTPATH           = 
+DOT_FONTPATH           =
 
-# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
-# will generate a graph for each documented class showing the direct and 
-# indirect inheritance relations. Setting this tag to YES will force the 
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
 # CLASS_DIAGRAMS tag to NO.
 
 CLASS_GRAPH            = YES
 
-# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
-# will generate a graph for each documented class showing the direct and 
-# indirect implementation dependencies (inheritance, containment, and 
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
 # class references variables) of the class with other documented classes.
 
 COLLABORATION_GRAPH    = YES
 
-# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
 # will generate a graph for groups, showing the direct groups dependencies
 
 GROUP_GRAPHS           = YES
 
-# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
-# collaboration diagrams in a style similar to the OMG's Unified Modeling 
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
 # Language.
 
 UML_LOOK               = NO
 
-# If set to YES, the inheritance and collaboration graphs will show the 
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside
+# the class node. If there are many fields or methods and many nodes the
+# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS
+# threshold limits the number of items for each type to make the size more
+# managable. Set this to 0 for no limit. Note that the threshold may be
+# exceeded by 50% before the limit is enforced.
+
+UML_LIMIT_NUM_FIELDS   = 10
+
+# If set to YES, the inheritance and collaboration graphs will show the
 # relations between templates and their instances.
 
 TEMPLATE_RELATIONS     = NO
 
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
-# tags are set to YES then doxygen will generate a graph for each documented 
-# file showing the direct and indirect include dependencies of the file with 
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
 # other documented files.
 
 INCLUDE_GRAPH          = YES
 
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
-# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
-# documented header file showing the documented files that directly or 
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
 # indirectly include this file.
 
 INCLUDED_BY_GRAPH      = YES
 
-# If the CALL_GRAPH and HAVE_DOT options are set to YES then 
-# doxygen will generate a call dependency graph for every global function 
-# or class method. Note that enabling this option will significantly increase 
-# the time of a run. So in most cases it will be better to enable call graphs 
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then
+# doxygen will generate a call dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable call graphs
 # for selected functions only using the \callgraph command.
 
 CALL_GRAPH             = NO
 
-# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then 
-# doxygen will generate a caller dependency graph for every global function 
-# or class method. Note that enabling this option will significantly increase 
-# the time of a run. So in most cases it will be better to enable caller 
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
+# doxygen will generate a caller dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable caller
 # graphs for selected functions only using the \callergraph command.
 
 CALLER_GRAPH           = NO
 
-# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
 # will generate a graphical hierarchy of all classes instead of a textual one.
 
 GRAPHICAL_HIERARCHY    = YES
 
-# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 
-# then doxygen will show the dependencies a directory has on other directories 
-# in a graphical way. The dependency relations are determined by the #include 
+# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
 # relations between the files in the directories.
 
 DIRECTORY_GRAPH        = YES
 
-# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
-# generated by dot. Possible values are svg, png, jpg, or gif. 
-# If left blank png will be used. If you choose svg you need to set 
-# HTML_FILE_EXTENSION to xhtml in order to make the SVG files 
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are svg, png, jpg, or gif.
+# If left blank png will be used. If you choose svg you need to set
+# HTML_FILE_EXTENSION to xhtml in order to make the SVG files
 # visible in IE 9+ (other browsers do not have this requirement).
 
 DOT_IMAGE_FORMAT       = png
 
-# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to 
-# enable generation of interactive SVG images that allow zooming and panning. 
-# Note that this requires a modern browser other than Internet Explorer. 
-# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you 
-# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files 
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+# Note that this requires a modern browser other than Internet Explorer.
+# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you
+# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files
 # visible. Older versions of IE do not have SVG support.
 
 INTERACTIVE_SVG        = NO
 
-# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
 # found. If left blank, it is assumed the dot tool can be found in the path.
 
-DOT_PATH               = 
+DOT_PATH               =
 
-# The DOTFILE_DIRS tag can be used to specify one or more directories that 
-# contain dot files that are included in the documentation (see the 
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
 # \dotfile command).
 
-DOTFILE_DIRS           = 
+DOTFILE_DIRS           =
 
-# The MSCFILE_DIRS tag can be used to specify one or more directories that 
-# contain msc files that are included in the documentation (see the 
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the
 # \mscfile command).
 
-MSCFILE_DIRS           = 
+MSCFILE_DIRS           =
 
-# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of 
-# nodes that will be shown in the graph. If the number of nodes in a graph 
-# becomes larger than this value, doxygen will truncate the graph, which is 
-# visualized by representing a node as a red box. Note that doxygen if the 
-# number of direct children of the root node in a graph is already larger than 
-# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note 
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
+# nodes that will be shown in the graph. If the number of nodes in a graph
+# becomes larger than this value, doxygen will truncate the graph, which is
+# visualized by representing a node as a red box. Note that doxygen if the
+# number of direct children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
 # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
 
 DOT_GRAPH_MAX_NODES    = 50
 
-# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
-# graphs generated by dot. A depth value of 3 means that only nodes reachable 
-# from the root by following a path via at most 3 edges will be shown. Nodes 
-# that lay further from the root node will be omitted. Note that setting this 
-# option to 1 or 2 may greatly reduce the computation time needed for large 
-# code bases. Also note that the size of a graph can be further restricted by 
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that the size of a graph can be further restricted by
 # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
 
 MAX_DOT_GRAPH_DEPTH    = 0
 
-# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
-# background. This is disabled by default, because dot on Windows does not 
-# seem to support this out of the box. Warning: Depending on the platform used, 
-# enabling this option may lead to badly anti-aliased labels on the edges of 
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not
+# seem to support this out of the box. Warning: Depending on the platform used,
+# enabling this option may lead to badly anti-aliased labels on the edges of
 # a graph (i.e. they become hard to read).
 
 DOT_TRANSPARENT        = NO
 
-# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 
-# files in one run (i.e. multiple -o and -T options on the command line). This 
-# makes dot run faster, but since only newer versions of dot (>1.8.10) 
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
 # support this, this feature is disabled by default.
 
 DOT_MULTI_TARGETS      = NO
 
-# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
-# generate a legend page explaining the meaning of the various boxes and 
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
 # arrows in the dot generated graphs.
 
 GENERATE_LEGEND        = YES
 
-# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
-# remove the intermediate dot files that are used to generate 
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
 # the various graphs.
 
 DOT_CLEANUP            = YES
diff --git a/qsstv/documentation/manual/manual.txt b/qsstv/documentation/manual/manual.txt
new file mode 100644
index 0000000..c858b2f
--- /dev/null
+++ b/qsstv/documentation/manual/manual.txt
@@ -0,0 +1,891 @@
+n/***************************************************************************
+ *   Copyright (C) 2000-2011 by Johan Maes                                 *
+ *   on4qz at telenet.be                                                      *
+ *   http://users.telenet.be/on4qz                                         *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   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.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+/** \file */
+
+// Documentation
+/*! \mainpage QSSTV 9.1
+\author Johan Maes ON4QZ
+
+\section intro_sec Introduction
+
+QSSTV 9 is a program for receiving and transmitting SSTV and HAMDRM (sometimes called DSSTV). It is compatible with most of MMSSTV and EasyPal<br>
+
+
+!!!  ALSO READ THE FAQ AT http://users.telenet.be/on4qz/qsstv_9/faq.html !!!
+
+This manual is divided in the following sections:
+- \subpage whatsnew
+- \subpage changelog
+- \subpage installation
+- \subpage gettingstarted
+- \subpage statusbar
+- \subpage imagepopup
+- \subpage RXSSTV
+- \subpage TXSSTV
+- \subpage RXDRM
+- \subpage TXDRM
+- \subpage fixdrm
+- \subpage gallery
+- \subpage editor
+- \subpage externalprog
+- \subpage todo1
+- \subpage credits
+- \subpage Copying
+
+73's
+Johan ON4QZ 
+
+
+\page whatsnew What's New
+QSSTV 9.1.x has the following new features compared to QSSTV 8.2.x
+
+- Build on top QT 5.x ( and also compatible with Qt 4.8)
+- Better synchronization in SSTV mode
+- New SSTV narrow band modes (MP73-N,MP110-N,MP140-N,MC110-N,MC140-N,MC180-N)
+- Changed GUI layout
+- Gallery window now shows all the rx/tx images.
+- RX and TX images for SSTV and DRM now in separate gallery tab.
+- TX Stock Images for fast selecting preferred TX Images.
+- SSTV Images only saved after a configurable percentage completed
+- Setting and reading frequency via CAT interface
+- Preferred fast frequency selection for SSTV and DRM
+- Editor/templates:  multi-line inputs for x,y and z
+- Pulse audio direct interface
+
+
+
+
+\page changelog Change log
+
+\li 20160416 QSSTV 9.1.5
+ - upload received images to ftp server (sstv and drm) gave file error -> solved
+
+\li 20160415 QSSTV 9.1.4
+ - rx image save button was not working -> fixed
+
+\li 20160410 QSSTV 9.1.3
+ - fixing compiler error: missing function cleanupcache in release mode
+
+\li 20160409 QSSTV 9.1.2
+ - implementation of image cache for faster image display in the gallery
+ - bug fix ,race condition for RxNotification
+
+\li 20160408 QSSTV 9.1.1
+ - replaced jpeg2000 library Jasper with openjpeg because some distros won't support Jasper anymore. Jasper has not been maintained for more than 10 years.
+
+\li 20151130 QSSTV 9.0.9
+- directories are auto-created if they don't exist
+- additional CAT command now also works with rigctld
+
+
+\li 20150930 QSSTV 9.0.8
+- fix DRM status update
+
+\li 20150929 QSSTV 9.0.7
+- fixed hang on exit
+
+\li 20150928 QSSTV 9.0.6
+- performace optimization (especially for Raspberry Pi 2)
+
+\li 20150926 QSSTV 9.0.4
+- added option for slow cpu (see Options ->GUI) This makes it possible to run QSSTV running on a Raspberry Pi 2.
+- minor change to ALSA sound interface.
+- some more bug fixing
+
+\li 20150910 QSSTV 9.0.3
+- xmlrpc bug fix (persistent connections)
+- manual (a lot of) spelling corrections
+- compatibility with Qt 4.8
+
+\li 20150907 QSSTV 9.0.2
+- changed configuration frequencies to allow for data modes on Icom
+- changed Editor, you may need to check/re-edit your template files (text offsets may have changed)
+
+\li 20150831 QSSTV 9.0.1
+- first release
+
+
+
+\page installation Installation
+
+Warning: from version 9.1.1 and higher,  Jasper library is dropped and openjpeg is used
+We need openjpeg2 (e.g. libopenjpeg2.1 or higher) and not libopenjpeg 1.5
+
+\section step1 Step 1: Prerequisites
+Before you can compile QSSTV make sure that you have installed the following software
+- g++
+- libfftw3-dev
+- qt5-default (qt4-default)
+- hamlib-dev
+- libasound2-dev
+- libpulse-dev
+- libopenjp2-7
+- libopenjp2-7-dev
+- libv4l-dev
+
+
+QSSTV is compatible with Qt 4.8.6 but mostly tested on Qt 5.4.x or higher
+
+<p>On Ubuntu, Debian or Mint you can type:
+
+<pre>sudo apt-get install g++ libfftw3-dev qt5-default libpulse-dev</pre>
+<pre>sudo apt-get install hamlib-dev libasound-dev  libv4l-dev</pre>
+<pre>sudo apt-get install libopenjp2-7 libopenjp2-7-dev</pre>
+
+If you don't find libopenjp2-7 you can download it with the follwing commands if you're running a Debian derived distribution:
+
+<pre>wget http://ftp.de.debian.org/debian/pool/main/o/openjpeg2/libopenjp2-7_2.1.0-2_i386.deb</pre>
+<pre>wget http://ftp.de.debian.org/debian/pool/main/o/openjpeg2/libopenjp2-7-dev_2.1.0-2_i386.deb</pre>
+or
+<pre>wget http://ftp.de.debian.org/debian/pool/main/o/openjpeg2/libopenjp2-7_2.1.0-2_amd64.deb</pre>
+<pre>wget http://ftp.de.debian.org/debian/pool/main/o/openjpeg2/libopenjp2-7-dev_2.1.0-2_amd64.deb</pre>
+
+and install the packages with the package manager or simply by double clicking on them.
+First install the library and then the development package. This is the case for example for Linux Mint 17.3.
+
+
+For specific instructions on installation on different distributions: have a look at the FAQ
+html http://users.telenet.be/on4qz/qsstv_9/faq.html
+
+\section step2 Step 2: Getting the software
+
+The latest versions of QSSTV is always available at http://users.telenet.be/on4qz
+Download the latest tar file to a local directory (e.g. ~/Downloads)
+
+\section step3 Step 3: Compile and Install the software
+Go to the directory you have chosen and extract the tar file.
+Note: replace the 9.1.1 with the appropriate version you have downloaded
+<pre>
+>cd ~/Downloads
+>tar -xvzf qsstv_9.1.1.tar.gz
+>cd qsstv_9.1.1
+>qmake
+>make
+>sudo make install
+</pre>
+\section step4 Step 4: Run QSSTV
+You can now run the program by typing qsstv at the prompt of a terminal session, or make a short cut on your desktop.
+<pre>>qsstv</pre>
+If you have problems compiling the software, please give as much information as possible but at least:
+- Linux Distribution (e.g. Ubuntu 12.10)
+- QT Version (e.g Qt 5.4.1)
+- Dump of the compile process showing the error
+
+\page gettingstarted Getting Started
+
+The program is build around 3 windows
+- Receive window:  Receive functions and configuration
+- Transmit window: Transmit functions and camera control
+- Gallery window:  History of received images, transmit images and templates
+The program will remember the last position and the size of each window on restart.
+
+\section config Configuration
+
+Before we can use QSSTV you need to do some configuration.
+\image html config.png
+The configuration tool is accessed through the "Options" menu in the receive window.
+The following tabs are available
+<br><br>
+\li Personal Settings
+<br><br>
+\image html config1.png
+<br><br>
+- Call sign
+- First Name
+- Last Name
+- QTH
+- Locator (Grid Square)
+<br>This information can also be used in templates (see also \ref editor)
+<br><br>
+
+\li Directories
+<br><br>
+\image html config2.png
+<br><br>
+- RX SSTV Images: directory for saving the SSTV received images
+- RX DRM Images: directory for saving the DRM received images
+- TX Images: directory for images to transmit
+- Templates: directory where the template files are stored
+- Audio Records: directory for audio files (where you save/read recorded audio files)
+- Documentation: URL of the user manual (if you copied the manual locally then you can point to it with e.g. file:///usr/share/doc/qsstv/manual
+<br><br>
+
+\li Gui
+<br><br>
+\image html config3.png
+<br><br>
+- Stretch: if checked, the image will fill the receive window (keeping the aspect ratio)  else it will be displayed as is.
+- Background Colour: colour used for image borders and background in the gallery
+- Image Background Colour: Default image background
+Push the push button to select the colour selector.
+- Gallery: Rows and columns: set-up the number of rows and columns to be used in the Gallery tab. If you're running on a slow CPU (like on a Raspberry Pi) select row=1 and columns=1.
+- Slow CPU: Select this option if you're running on a slow CPU (e.g. Rapsberry Pi)
+
+<br><br>
+
+\li Audio
+<br><br>
+\image html config4.png
+<br><br>
+- ALSA Input Audio Device : depending on your hardware (e.g. default,hw:0,0)
+- ALSA Output Audio Device : depending on your hardware (e.g. default,hw:0,0)
+- PulseAudio: native pulse audio interface
+Note: <b> Most distributions use Pulse Audio interface.. You can select the audio card settings through the audio applet by right clicking on the Speaker icon and selecting the Sound Preferences</b>
+- RX Clock frequency : clock used while receiving SSTV images,(see also \ref calib)
+- TX Clock frequency : clock used while transmitting SSTV images,(see also \ref calib)
+- Sound Input routing
+   - From sound card: default mode
+   - From file: decode a previously recorded file
+   - From sound card and record: decode and record to a file (wav type, stereo 48000)
+   - Maximum recording size: limits the size of the recorded file
+- Sound Output routing
+   - To sound card: default
+   - Playback: playback a wav-file (use 48000 samples per second recording in mono or stereo)
+   - Playback and record: playback the sound and record at the same time.
+<br>
+Note: To playback an audio file, be sure the format is of type wav and has a samplerate of 48000 samples/second. You can always open the file with audacity and export the file to adapt the type and/or
+ samplerate<br>
+
+
+\li CAT
+<br><br>
+\image html config5.png
+<br><br>
+
+- Special Serial Port: If you have a separate serial interface to control the PTT you can enable Special Serial Port to control it.
+You can select RTS and or DTR in inverted or non-inverted mode (i.e. +RTS will assert RTS at +12V when the PTT is active
+and -RTS will assert RTS at -12V). +RTS and/or +DTR is used most of the time.
+The same goes for DTR.
+<br>
+You cannot select both +RTS and -RTS or +DTR and -DTR at the same time.
+- Enable Hamlib Cat Interface
+ - Radio Model: drop down list from the radio models
+ - CIV Address: only used for ICOM, if left empty, the default address of the radio will be used
+ - Serial Port/host: either the serial port (e.g. /dev/ttyUSB0) or the host address (e.g. localhost:4532)
+ - Handshake, Parity, Data bits, Stop bits, Baud rate: serial port settings
+ - PTT Serial Port: serial port (e.g. /dev/ttyS0) only used if  "Enable PTT serial Interface" is selected
+ - PTT Control via: If the radio uses a CAT command to activate Transmission then select "CAT". If you have a radio that does not support such a CAT command, you can
+let Hamlib use the RTS or DTR on the serial port specified by "PTT Serial Port".
+Example: IC-706MKIIG via a cat interface such as interfaceOne.
+\anchor flrigconfig
+- Enable XMLRPC
+ This allows you to connect to the Flrig program using the XMLRPC protocol. Flrig will handle all the communication with the transceiver (including PTT).
+- TX Delay: The program will wait for the selected delay before transmitting any audio.
+
+
+Note: The option Enable XMLRPC excludes the use of hamlib.
+
+A sample set-up of Flrig is shown below.
+<br><br>
+\image html flrig1.png
+<br><br>
+
+
+
+
+\li CW
+<br><br>
+\image html config6.png
+<br><br>
+- Tone: frequency of the CW tone
+- Words per Minute: CW transmission speed
+- Text To Send: this text will be send at the end of an image transmission if the option is enabled.
+
+
+
+
+\li Repeater
+<br><br>
+\image html config7.png
+<br><br>
+- Enable repeater: enable repeater operation
+- Image Interval (min): interval time before sending one of the Idle Images
+- Repeater TX mode: the mode the repeater will use to send the images
+- Idle Image[1-4]: images send by the repeater if there is no activity for more than the interval time
+- Idle Template:template that will be super-imposed on the idle images
+- Repeater Template: template that will be super-imposed on the repeated(received) images
+
+\li FTP
+<br><br>
+\image html config8.png
+<br><br>
+This is used to save the received images to an FTP server. The images will also still be saved in the local rx folder.
+- Enable FTP: enable ftp operation
+- FTP Port: default 21
+- Default Image Format: select the image format from the drop down bow (used only in SSTV)
+- Remote Hostname: hostname of the ftp server (e.g. myftp.home.net or 192.168.0.1)
+- Remote directory:the ftp server directory where you'll store the images
+- FTP Login name: your login name on the server (can be anonymous)
+- FTP Password: if you need one, otherwise leave blank
+- Image store:
+  - Image1 - image30: The files will be saved under the generic name imageXX, where xx ranges from 1 to 30. When a new image arrives, the old images are shifted down
+  (i.e. image29 becomes image30, image28 becomes image 29 etc ..) and the new one is stored as image1.
+  -file name: the image (or other type of file) is stored with a file name derived from the mode (SSTV) or from the file name transmitted in DRM.
+
+Note: This FTP server is unrelated to the FTP server for Hybrid Mode.
+
+You can test the connection by clicking the Test connection button. It will set-up a connection to the server and send a test file to check if all parameters are correct.
+You will either see a pop-up with "Connection OK" or an error message showing the reason of the fail.
+
+
+
+
+\li Waterfall
+<br><br>
+\image html config9.png
+<br><br>
+- Start Pic: Waterfall text to send at the beginning of a DRM transmission
+- End Pic: Waterfall text to send at the end of a DRM transmission
+- FIX: Waterfall text to send at the beginning of a DRM retransmission
+- BSR: Waterfall text to send at the beginning of a DRM request for retransmission
+<br> Note: you can also use %%m. This will be replaced by your call sign
+
+
+\li Hybrid
+<br><br>
+\image html config10.png
+<br><br>
+- Enable Reception in Hybrid Mode: allows reception of hamDRM in hybrid mode. If this is not enabled, hybrid mode files will not be shown or stored.
+- Enable Special server: Activate only if you want to use a different server than the preprogrammed default one of VK4AES
+- FTP Port: default 21
+- Remote Hostname: hostname of your ftp server
+- Remote directory:the ftp server directory where the stored images are
+- FTP Login name: the login name on the server
+- FTP Password: will be encrypted
+
+Login name, password,hostname and directories will be encrypted before being sent on the air.
+
+If you want to use the special server, the directories to store images is relative to the directory HybridFiles1. So first create a top level directory HybridFiles1.
+If you leave the Remote Directory empty, then the files will be placed in the directory HybridFiles1.
+If you put for example "testdir" in the Remote Directory (as shown in the above screen shot), then you need to create testdir under HybridFiles (HybridFiles1/testdir).
+
+QSSTV will not create those directories for you.
+
+EasyPal also use two other directories on the same level as HybridFiles1
+- OnlineCallsigns1
+- RxOkNotifications1
+
+You can create them on your server but they are not used by QSSTV at this moment.
+
+You can test the connection by clicking the Test connection button. It will setup a connection to the server and send a test file to check if all parameters are correct.
+You will either see a pop-up with "Connection OK" or an error message showing the reason of the fail.
+
+\li DRM Profiles
+<br><br>
+\image html config11.png
+<br><br>
+Used for quick selection of the most common settings you use in DRM.
+Choose a short name for the profile and make a selection for all the parameters.
+The name will appear in the Profiles drop-down box in the Transmit window for DRM.
+
+\li Frequencies
+\anchor configFreq
+<br><br>
+\image html config12.png
+<br><br>
+- List of selectable frequencies. Click Add to add a new combo frequency/mode/modulation. Enter the frequency and select the mode and modulation type.<br>
+To move a frequency/mode/modulation  up or down the list, click first on the entry in the table and then click on one of the arrow buttons.
+
+- Hamlib Data Command: (only used with Hamlib) As far a I know Hamlib does not support switching the Icomxxx to data mode.
+As a result, if you for example selected USB-D1 on a Icom 7600,changing the frequency will switch the rig back to the regular USB (data mode off).<br>
+Hamlib Data Command allows you to send a "raw command" that will be executed when you change frequencies.
+
+- Example: FEFE7AE01A060101FD and Hex button checked: will put the Icom in data mode D1 (LSB, USB or FM) and the Filter 1.
+
+- Hex: if checked the text is interpreted as hex values else it will be interpreted as a regular ASCII string.
+
+- Note 1: you can put any valid raw command here, it will be send on every frequency change
+
+- Note 2: Flrig does not support FM data modes.
+
+
+
+\section calib Calibration
+Note: Calibration is only needed for SSTV mode
+All SSTV applications need an accurate and stable clock. The accuracy of a PC clock is not always correct.
+Therefore it's necessary to execute some sort of calibration.
+You need to synchronize your PC with an network time server via the ntp protocol.
+Every Linux distribution has some configuration tool that allows you to install the ntp client. Be sure it's active.
+You can check it with:
+<pre>
+>ntpdc -p
+</pre>
+
+The selected ntp server should have an asterisk in the first column.
+<pre>
+remote           local      st poll reach  delay   offset    disp
+=======================================================================
+*stratum1dc1.bc  10.119.37.19     2   64  377 0.00386  0.036853 0.06850
+</pre>
+
+You can now launch the Calibration.<br><br>
+<b>It will take several minutes to complete. Be sure to wait long enough, the progress is extremely slow</b>
+<br><br>
+\image html calibration.png
+When RX and TX calibration is finished, press the OK button to accept the new values.
+
+\li Note: You can always enter the clock values manually.
+
+
+\page statusbar Statusbar
+\image html statusbar.png
+- Radio Frequency: the current frequency of the radio (only if CAT interface is enabled)
+- Drop down menu to set the radio on the selected frequency (only if CAT interface is enabled) (see also \ref configFreq Config freq)
+- WF Text: gives you a selection of user defined text you can send to appear as waterfall text.
+<br><br>
+\image html wftextpopup.png
+<br>
+Send the text by clicking the tx button next to it<br>
+The %%m will be substituted by your callsign and the %%s by the average SNR of the last received DRM stream.
+<br><br>
+
+- BSR: When a file is not completely received, you can ask for a retransmission.
+ \image html bsr_select.png
+ By default the latest received file is selected (you can select another one through the drop-down box).
+<br>There are two modes: EasyPal and Compatible. EasyPal mode is more advanced and is normally used as EasyPal is the de facto standard on Windows and QSSTV also uses this mode in BSR reception.
+<br>Note: BSR is greyed out in SSTV.
+<br><br>
+-  ID: send callsign in waterfall - this is a short-cut to send your own callsign in the waterfall
+<br><br>
+- PTT indicator: turns red while the PTT is activated.
+
+\page imagepopup Image Viewer
+All the images displayed in QSSTV have pop-up actions. This is an example for the Gallery.
+
+<br>
+\image html Gallery_image_options.png
+<br><br>
+By right clicking on the images, a pop-up window appears that can have one or more of the following actions:
+- New: open the editor to create a new image.
+- Load: load new file into window
+- To TX: send image to TX window
+- Edit: edit the selected image
+- Print: print the selected image
+- Delete: delete the selected image, a pop-up will ask if you want to delete the file also from disk., if so the file will be moved to the trash folder.
+- View: Display the image in a new window actual size (the window is resizeable).
+- Properties: displays the image and file properties if available
+
+
+
+
+\page RXSSTV Receive SSTV Window
+\image html rxwidget1.png
+Menu toolbar:
+\li \image html start.png
+start receiving images
+\li \image html stop.png
+stop receiving images
+\li \image html replay.png
+force a restart (e.g. when you see a wrong synchronization then click the restart button).
+\li \image html filesave.png
+save the image at any time using the save button. You will probably want to use this if the Auto-save is not selected. Note only active in SSTV mode.
+\li \image html eraser.png
+erase the screen
+
+
+
+Sync Indicator (vu-meter S):
+- sync quality ranging from 0-10
+
+Volume (vu-meter V):
+- adjust your recording level to half scale.
+
+SSTV tab:
+- Use VIS Code: the reception will only start if a correct VIS code is received. If left unchecked, QSSTV will auto-detect the modes (this is the most used method).
+- Auto-slant: A lot of times the receive clock of the local station is not equal to the transmit clock of the sending station. The result is a slanted image.
+If The auto-slant is activated, the program will automatically try to compensate for those clock differences.
+You may notice a momentary freeze of the image build-up while the program is recalculating the image.
+- Auto-save: When the program detect the end of the image, the image will be saved to disk.
+- Save if Complete %: Auto-save if the image is at least completed for the indicated percentage.
+- Mode: you can either select AUTO or one of the supported SSTV modes.
+When AUTO is selected, the program will try to determine the mode of the image it is receiving.
+If a specific mode is selected the program will reject all images except if they are transmitted in the selected mode.
+- Signals: Normal and DX.
+When the Sensitivity is set to DX the signal will run until the end of the image before resynchronization.
+
+
+Spectrum and Waterfall:<br>
+There are three markers for SSTV (red lines):
+- 1200: Sync frequency
+- 1500: Lower video frequency
+- 2300: Upper video frequency
+In DRM, the markers indicate the 3 unmodulated carrier frequencies
+
+
+\page TXSSTV Transmit SSTV Window
+\image html txwidget1.png
+
+
+The TX progress-bar indicates the progress of the transmission. <br><br>
+\anchor sstvMenu
+Menu toolbar:
+\li \image html start.png
+start transmitting images
+\li \image html stop.png
+stop transmitting  images
+\li \image html tone.png
+sends a repeater tone of 1750 Hz
+\li \image html fileopen.png
+loads a file in the transmit window
+\li \image html edit.png
+opens the image editor
+\li \image html camera.png
+takes a snapshot if there is a camera installed that is supported by v4l2
+\li \image html binary.png
+only used in DRM mode
+\li \image html doubletone.png
+let you select frequency and duration of a tone to send
+\li \image html sweep.png
+let you select the sweep frequencies and duration to send
+\li \image html hybrid_dis_checkbox.png
+This check-box is disabled in SSTV mode
+\li \image html refreshbutton.png
+You can refresh the content of the replay image by clicking the Refresh button (e.g. when you have loaded a new image in the preview image window).
+
+
+<p>
+- Select the transmission mode (Martin 1, Scottie etc.).</p>
+
+\anchor Control
+- Select CW if you want to append a morse message after the image (the message is set in Options->Configuration->CW) .
+- If the VOX check-box is set a tone will be sent before the actual image is sent so that you can use the VOX
+on your transceiver (if you do not have PTT control).
+- Select the template (or none) you want as an overlay (see \ref gallery). Only the templates
+that are in the Gallery will be available.
+
+The text inputs correspond to the following macros:
+
+\li TO: %%c - call of the contacted station
+\li RSV %%r - RSV (radio-strength-video best is 595)
+\li Op: %%o - name of the operator of the contacted station
+\li x %%x - comment1
+\li y %%y - comment2
+\li z %%z - comment3
+\n see also \ref editor
+
+- The last received image is displayed at the bottom right. It will be updated automatically as
+new images are received. They can be inserted if you use a template containing an "image replay object" see also \ref editor
+<br>
+Right clicking on this image also allows you to load other images for insertion. Use the refresh button to update the main window if necessary.
+
+
+\page RXDRM Receive DRM Window
+\image html receivedrm.png
+
+SNR (vu-meter S):
+- SNR in dB
+
+Volume (vu-meter V):
+- adjust your recording level to half scale (better too low than too high).
+
+Received segments:
+\image html rxdrm_segments.png
+- green: correctly received segments
+- red: missing segments
+
+Constellation:
+\image html rxdrm_constellation.png
+
+- FAC constellation (always QAM 4)
+- MSC constellation.
+
+
+Receive status
+\image html rxdrm_status.png
+- Mode (A,B or E)
+- Bandwidth (2.3 KHz or 2.5 KHz)
+- Interleave (Short or Long)
+- Protection (Normal or High)
+- QAM (4,16 or 64)
+- SNR (should be above 6 dBm)
+- Offset (0 Hz if no frequency offset)
+- Total Segm.: total number of segments in the file
+- RX Sgmnts.: number of correctly received segment
+- Cur. Sgmnt.: segment currently transmitted
+- Transp. ID; unique identifier for the current stream.
+- Callsign from the transmitting station
+
+
+\image html statusleds.png
+- TIME: green if time sync else red
+- FRAME: green if frame sync else red
+- FAC: green if FAC correctly received else red
+- MSC:
+	- red: incorrectly received
+	- green: correctly received
+	- yellow: already received
+
+When an data stream is received , the program will try to decode it and save it in the receive image directory.
+If the data stream is a text file it will be displayed in a separate window. Just click OK to close it.
+
+\image html waterfall.png
+Spectrum:<br>
+You can select the spectrum or the waterfall by clicking in this window. In DRM the waterfall gives you better view.
+The three markers above the waterfall indicate  the position of the pilot frequencies. This helps tuning the radio to the correct frequency.
+<br><br>
+(8) see \ref RXSSTV
+
+
+\page TXDRM Transmit DRM Window
+\image html transmitdrm.png
+
+
+
+see  also \ref sstvMenu under SSTV TX
+
+- \image html binary.png
+Click here to send a binary file (basically any file will do)
+
+- \image html hybrid_checkbox.png
+When this check-box is checked, the image is transmitted in hybrid mode.
+
+For the other icons and actions see also \ref TXSSTV
+<br>
+<br>
+Mode Selection
+\image html txdrm_options.png
+<br>
+- Mode (A,B or E)
+- Bandwidth (2.3 KHz or 2.5 KHz)
+- Interleave (Short or Long)
+- Protection (Normal or High)
+- QAM (4,16 or 64)
+- Reed Solomon: (rs1, rs2, rs3 or rs4).File encoder for forward error correction. On HF it is recommended to always use Reed Solomon. The most often used is rs2.
+The higher the number, the more protection but also the more overhead.
+- Profile: quick selection of a profile (i.e. settings of mode,QAM ...) as defined in the Options->Configuration->DRM Profiles)
+<br>
+
+\image html txdrm_status.png
+
+The TX progress-bar indicates the progress of the transmission.
+
+see also  \ref Control under SSTV TX
+- Last received image will be updated automatically as
+new images are received. They can be inserted if you use a template containing an "image replay object" see also \ref editor
+<br>
+- Compression
+<br><br>
+
+\image html txdrm_compression.png
+<br>Avoid to send huge images (especially if you're not in hybrid mode).<br>
+You can drag the slider to compress the image before it is sent (the original image is not modified). The file size is shown on the right. You can see the result in the image frame when you release the handle.
+<br>
+Note: This does not include the overhead of the RS-encoding.
+
+
+\page fixdrm Sending FIX in DRM
+\image html fix.png
+
+When the image you transmitted is not correctly received, the other station can send a BSR. When you receive a BSR and it is destined for you, then the above popup will show.
+You can either send the fix or cancel.<br>
+If the BSR is not for you then the following window will pop-up for a few seconds.
+\image html bsr_nfy.png
+
+
+
+\page gallery Gallery
+The Gallery contains six tabs. The directories where the different images are stored are configured in the Directories tab of the Configuration.
+<br>
+\image html Gallery_rx.png
+<br>
+-RX SSTV: SSTV images are stored on disk and shown here if the Auto-save is enabled in the receive window and the minimum percentage is reached
+-RX DRM:  All images received in DRM mode are stored on disk and shown here.
+-TX SSTV: When sending an image in SSTV mode then the resulting images is stored on disk and shown here (this includes the template overlay).
+-TX DRM:  When sending an image in SSTV mode then the resulting images is stored on disk and shown here (this includes the template overlay).
+-TX Stock: Contains your selection of "Stock" images you want to use for transmission.
+-Templates <br> <br>
+\image html Gallery_tx.png
+-Templates: template images to be used as overlay on tx images
+\image html Gallery_template.png
+
+
+
+
+\page editor Editor
+The editor can be used for regular image editing and for the creation and editing of template images.
+Template images are used as overlays. They will be dynamically adapted when you select the template in the TX-window.
+While in edit mode, you can change all the attributes (such as size, position, colours etc ...). If you save the canvas as an
+image, the scene will be rendered (i.e. flattened) and become a single image object. If you save the canvas as a template, all objects
+will be accessible again when loaded.
+
+<br>
+To create an object, click on the left menu to select the type of object (e.g circle) and then click on the canvas where you want the object positioned.
+Just click on an item to select it. A outline of the item will be shown by a dashed line.
+If you hoover over the object you will see the cursor change to a hand-icon (in the middle of the object) to move it, or to a resize-icon if you are on a border.
+
+The attributes (line colour, fill colour, gradients etc ..) that are active in the top menu will be used to create the item.
+Object have also a z-component, i.e they can be in front our behind another object. This can be changed by right clicking on the item and use the Arrange selection.
+
+
+\image html editor_1.png
+\li Top menu 1
+- Image Size: Select the size of the image: the outline of the image will be shown on the canvas.
+\image html editor_image_size.png
+- Font: drop down box where you can select the text font
+- Font size: text size
+- Bold : bold text
+- Italic: italic text
+- Underline: underlined text
+- Pen width: width of lines in number of pixels
+\li Top menu 2
+- Fill: Fill colour drop down menu
+- Line: Line colour drop down menu
+- Gradient: Gradient selection menu
+
+\li  Left menu
+- \image html arrow.png
+select/deselect objects
+- \image html fcircle.png
+ create filled circle/ellipse
+- \image html frect.png
+ create filled rectangle
+-\image html line.png
+ create line
+-\image html camera.png
+insert image
+-\image html replay.png
+ insert replay image place-holder. When the template will be loaded in the TX-window, this place-holder will replaced by the last received image
+-\image html text.png
+create text. When you select this option a window will pop-up to enter text.
+<br>
+-\image html entertext.png
+<br>You can enter multiple lines of text. Click OK, the window will be hidden and you can click on the canvas to position the text.
+The text will appear on the canvas.
+-\image html multiline.png
+<br>
+
+\li Bottom menu
+- Horizontal Shear: shear selected object horizontally
+- Rotate: rotate selected object
+\li Right menu
+- Vertical Shear: shear selected object vertically
+<p>
+If you right click on an object then the following pop-up menu will be shown:</p>
+\li Arrange
+- Forward - one level forward
+- Backward - one level backward
+- Bring to Front - all the way to the front
+- Sent to Back - all the way to the back
+\li Change text - change the text of a text object
+\li Expand - object will expand horizontally and vertically to fill the complete canvas
+\li Delete - remove selected object from the canvas
+\li Lock - lock items so that they can not be moved or resized
+\li Unlock - unlock selected items
+
+<p> We need some sort of macro's to enable variable text when transmitting images. The editor uses predefined strings that will be replaced by
+the "actual content" when the template is processed just before transmission.<br>
+
+Here's an example of the editor using macros and the result in the transmitter.</p>
+<br>
+\image html editor_2.png
+<br><br>
+\image html transmitdrm.png
+
+
+Following macro's are supported:<br>
+Macro's where the value is defined in the configuration
+\li %%m - my callsign
+\li %%q - my QTH
+\li %%l - my locator
+\li %%n - my last name
+\li %%f - my first name
+
+Macro's where the value is entered in the TX-window prior to transmission
+\li %%c - call of the contacted station
+\li %%r - RSV (radio-strength-video best is 595) You can also input free text as is sometimes required for contest (e.g. 595#007 or Good Copy)
+\li %%o - name of the operator of the contacted station
+\li %%x - comment1
+\li %%y - comment2
+\li %%z - comment3
+
+Note: comment 1,2 and 3 can be multi-line.
+
+Macro's where the value is defined by the system
+\li %%t - time in hours:minutes format
+\li %%d - date in year/month/day format
+\li %%v - qsstv_version
+\li %%s - SNR - only to be used for DRM in the WF Text see also \ref statusbar
+
+
+
+\page credits Credits
+- SSTV:<br>
+Many thanks to all testers and users of QSSTV - too many to name them all.
+<br><br>
+- DRM:<br>
+I started developing the DRM functionality in QSSTV after studying the excellent work Ties Bos (PA0MBO) did on txrxamadrm.<br>
+see: http://www.pa0mbo.nl/ties/public_html/hamradio/txamadrm/index.html<br>
+The software is NOT based on the hamdrm.dll but on DIORAMA (http://nt.eit.uni-kl.de/static/diorama/index.html)<br>and adapted by PA0MBO. For more information , see the manual of txrxamadrm.
+
+This document contains references to Easypal (by VK4AES). Erik Sundstrup was kind enough to give me permission to use the extended BSR functionality and the DRM Hybrid mode.
+Easypal was used extensively to test my program. <br>
+<br>
+\image html vk4aes.jpg
+<br><br>
+
+Erik is now silent key as of 14th march 2015.     We will miss him.
+<br>
+I hope there will be other OM's that take up the maintenance,enhancements  and development of EasyPal so that people running Windows will continue to enjoy his software.
+<br>reference: http://vk4aes.com/
+
+\page externalprog External Programs
+
+QSSTV can interface with other programs.
+<br><br> Flrig see \ref flrigconfig
+
+<br><br>
+Cqrlog: QSSTV (when in DRM mode) sends the following information to Cqrlog:
+- program: identifies QSSTV
+- version: protocol version
+- date: based on UTC
+- time: based on UTC (time when the images is correctly received)
+- endtime: based on UTC (always = time)
+- call: call sign of the received station
+- mhz: frequency in MHz
+- mode: SSTV (ADIF restriction: there is no DSSTV nor DRM specified in ADIF, SSTV is the closest match)
+- notes: contains file name, DRM mode information (i.e mode, QAM, protection.. hybrid)
+
+<br><br>
+- Setup: <br><br>\image html cqrlog1.png <br>
+<br><br>
+- Do not enable Run Fldigi ...
+- Start Cqrlog and select Remote mode for Fldigi
+- If you want to see the QSO's: Select "Show QSO list" from the file menu.<br><br>
+\image html cqrlog2.png
+<br>
+Note: Unless you configured the Automatic refresh, you will only see the QSO's if you hit the Refresh button.
+
+
+\page todo1 To Do
+\li fax implementation and testing
+\li expand function in editor
+\li improve documentation
+
+
+\page Copying Copying
+
+This software uses Qt for Linux: see http://qt.digia.com/
+The application is released under GPLv3
+
+*/
+
+
diff --git a/qsstv/documentation/manual/manual/Gallery_image_options.png b/qsstv/documentation/manual/manual/Gallery_image_options.png
new file mode 100644
index 0000000..e46c156
Binary files /dev/null and b/qsstv/documentation/manual/manual/Gallery_image_options.png differ
diff --git a/qsstv/documentation/manual/manual/Gallery_rx.png b/qsstv/documentation/manual/manual/Gallery_rx.png
new file mode 100644
index 0000000..c7ed4f1
Binary files /dev/null and b/qsstv/documentation/manual/manual/Gallery_rx.png differ
diff --git a/qsstv/documentation/manual/manual/Gallery_template.png b/qsstv/documentation/manual/manual/Gallery_template.png
new file mode 100644
index 0000000..f7f8d8a
Binary files /dev/null and b/qsstv/documentation/manual/manual/Gallery_template.png differ
diff --git a/qsstv/documentation/manual/manual/Gallery_tx.png b/qsstv/documentation/manual/manual/Gallery_tx.png
new file mode 100644
index 0000000..b776f9f
Binary files /dev/null and b/qsstv/documentation/manual/manual/Gallery_tx.png differ
diff --git a/qsstv/documentation/manual/manual/_copying.html b/qsstv/documentation/manual/manual/_copying.html
new file mode 100644
index 0000000..3d4d0c3
--- /dev/null
+++ b/qsstv/documentation/manual/manual/_copying.html
@@ -0,0 +1,77 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.9.1"/>
+<title>QSSTV: Copying</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<script type="text/javascript">
+  $(document).ready(initResizable);
+  $(window).load(resizeHeight);
+</script>
+<link href="qsstv.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+  <td style="padding-left: 0.5em;">
+   <div id="projectname">QSSTV
+    <span id="projectnumber">9.1</span>
+   </div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.9.1 -->
+  <div id="navrow1" class="tabs">
+    <ul class="tablist">
+      <li><a href="index.html"><span>Main Page</span></a></li>
+      <li class="current"><a href="pages.html"><span>Related Pages</span></a></li>
+    </ul>
+  </div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+$(document).ready(function(){initNavTree('_copying.html','');});
+</script>
+<div id="doc-content">
+<div class="header">
+  <div class="headertitle">
+<div class="title">Copying </div>  </div>
+</div><!--header-->
+<div class="contents">
+<div class="textblock"><p>This software uses Qt for Linux: see <a href="http://qt.digia.com/">http://qt.digia.com/</a> The application is released under GPLv3 </p>
+</div></div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="index.html">QSSTV 9.1</a></li>
+    <li class="footer">Generated on Sat Apr 16 2016 17:32:52 for QSSTV by
+    <a href="http://www.doxygen.org/index.html">
+    <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.9.1 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/qsstv/documentation/manual/manual/_r_x_d_r_m.html b/qsstv/documentation/manual/manual/_r_x_d_r_m.html
new file mode 100644
index 0000000..7914ab9
--- /dev/null
+++ b/qsstv/documentation/manual/manual/_r_x_d_r_m.html
@@ -0,0 +1,138 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.9.1"/>
+<title>QSSTV: Receive DRM Window</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<script type="text/javascript">
+  $(document).ready(initResizable);
+  $(window).load(resizeHeight);
+</script>
+<link href="qsstv.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+  <td style="padding-left: 0.5em;">
+   <div id="projectname">QSSTV
+    <span id="projectnumber">9.1</span>
+   </div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.9.1 -->
+  <div id="navrow1" class="tabs">
+    <ul class="tablist">
+      <li><a href="index.html"><span>Main Page</span></a></li>
+      <li class="current"><a href="pages.html"><span>Related Pages</span></a></li>
+    </ul>
+  </div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+$(document).ready(function(){initNavTree('_r_x_d_r_m.html','');});
+</script>
+<div id="doc-content">
+<div class="header">
+  <div class="headertitle">
+<div class="title">Receive DRM Window </div>  </div>
+</div><!--header-->
+<div class="contents">
+<div class="textblock"><div class="image">
+<img src="receivedrm.png" alt="receivedrm.png"/>
+</div>
+<p>SNR (vu-meter S):</p><ul>
+<li>SNR in dB</li>
+</ul>
+<p>Volume (vu-meter V):</p><ul>
+<li>adjust your recording level to half scale (better too low than too high).</li>
+</ul>
+<p>Received segments: </p><div class="image">
+<img src="rxdrm_segments.png" alt="rxdrm_segments.png"/>
+</div>
+<ul>
+<li>green: correctly received segments</li>
+<li>red: missing segments</li>
+</ul>
+<p>Constellation: </p><div class="image">
+<img src="rxdrm_constellation.png" alt="rxdrm_constellation.png"/>
+</div>
+<ul>
+<li>FAC constellation (always QAM 4)</li>
+<li>MSC constellation.</li>
+</ul>
+<p>Receive status </p><div class="image">
+<img src="rxdrm_status.png" alt="rxdrm_status.png"/>
+</div>
+<ul>
+<li>Mode (A,B or E)</li>
+<li>Bandwidth (2.3 KHz or 2.5 KHz)</li>
+<li>Interleave (Short or Long)</li>
+<li>Protection (Normal or High)</li>
+<li>QAM (4,16 or 64)</li>
+<li>SNR (should be above 6 dBm)</li>
+<li>Offset (0 Hz if no frequency offset)</li>
+<li>Total Segm.: total number of segments in the file</li>
+<li>RX Sgmnts.: number of correctly received segment</li>
+<li>Cur. Sgmnt.: segment currently transmitted</li>
+<li>Transp. ID; unique identifier for the current stream.</li>
+<li>Callsign from the transmitting station</li>
+</ul>
+<div class="image">
+<img src="statusleds.png" alt="statusleds.png"/>
+</div>
+<ul>
+<li>TIME: green if time sync else red</li>
+<li>FRAME: green if frame sync else red</li>
+<li>FAC: green if FAC correctly received else red</li>
+<li>MSC:<ul>
+<li>red: incorrectly received</li>
+<li>green: correctly received</li>
+<li>yellow: already received</li>
+</ul>
+</li>
+</ul>
+<p>When an data stream is received , the program will try to decode it and save it in the receive image directory. If the data stream is a text file it will be displayed in a separate window. Just click OK to close it.</p>
+<div class="image">
+<img src="waterfall.png" alt="waterfall.png"/>
+</div>
+<p> Spectrum:<br />
+ You can select the spectrum or the waterfall by clicking in this window. In DRM the waterfall gives you better view. The three markers above the waterfall indicate the position of the pilot frequencies. This helps tuning the radio to the correct frequency. <br />
+<br />
+ (8) see <a class="el" href="_r_x_s_s_t_v.html">Receive SSTV Window</a> </p>
+</div></div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="index.html">QSSTV 9.1</a></li>
+    <li class="footer">Generated on Sat Apr 16 2016 17:32:52 for QSSTV by
+    <a href="http://www.doxygen.org/index.html">
+    <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.9.1 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/qsstv/documentation/manual/manual/_r_x_s_s_t_v.html b/qsstv/documentation/manual/manual/_r_x_s_s_t_v.html
new file mode 100644
index 0000000..fdc0730
--- /dev/null
+++ b/qsstv/documentation/manual/manual/_r_x_s_s_t_v.html
@@ -0,0 +1,121 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.9.1"/>
+<title>QSSTV: Receive SSTV Window</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<script type="text/javascript">
+  $(document).ready(initResizable);
+  $(window).load(resizeHeight);
+</script>
+<link href="qsstv.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+  <td style="padding-left: 0.5em;">
+   <div id="projectname">QSSTV
+    <span id="projectnumber">9.1</span>
+   </div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.9.1 -->
+  <div id="navrow1" class="tabs">
+    <ul class="tablist">
+      <li><a href="index.html"><span>Main Page</span></a></li>
+      <li class="current"><a href="pages.html"><span>Related Pages</span></a></li>
+    </ul>
+  </div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+$(document).ready(function(){initNavTree('_r_x_s_s_t_v.html','');});
+</script>
+<div id="doc-content">
+<div class="header">
+  <div class="headertitle">
+<div class="title">Receive SSTV Window </div>  </div>
+</div><!--header-->
+<div class="contents">
+<div class="textblock"><div class="image">
+<img src="rxwidget1.png" alt="rxwidget1.png"/>
+</div>
+<p> Menu toolbar: </p><ul>
+<li><div class="image">
+<img src="start.png" alt="start.png"/>
+</div>
+ start receiving images </li>
+<li><div class="image">
+<img src="stop.png" alt="stop.png"/>
+</div>
+ stop receiving images </li>
+<li><div class="image">
+<img src="replay.png" alt="replay.png"/>
+</div>
+ force a restart (e.g. when you see a wrong synchronization then click the restart button). </li>
+<li><div class="image">
+<img src="filesave.png" alt="filesave.png"/>
+</div>
+ save the image at any time using the save button. You will probably want to use this if the Auto-save is not selected. Note only active in SSTV mode. </li>
+<li><div class="image">
+<img src="eraser.png" alt="eraser.png"/>
+</div>
+ erase the screen</li>
+</ul>
+<p>Sync Indicator (vu-meter S):</p><ul>
+<li>sync quality ranging from 0-10</li>
+</ul>
+<p>Volume (vu-meter V):</p><ul>
+<li>adjust your recording level to half scale.</li>
+</ul>
+<p>SSTV tab:</p><ul>
+<li>Use VIS Code: the reception will only start if a correct VIS code is received. If left unchecked, QSSTV will auto-detect the modes (this is the most used method).</li>
+<li>Auto-slant: A lot of times the receive clock of the local station is not equal to the transmit clock of the sending station. The result is a slanted image. If The auto-slant is activated, the program will automatically try to compensate for those clock differences. You may notice a momentary freeze of the image build-up while the program is recalculating the image.</li>
+<li>Auto-save: When the program detect the end of the image, the image will be saved to disk.</li>
+<li>Save if Complete %: Auto-save if the image is at least completed for the indicated percentage.</li>
+<li>Mode: you can either select AUTO or one of the supported SSTV modes. When AUTO is selected, the program will try to determine the mode of the image it is receiving. If a specific mode is selected the program will reject all images except if they are transmitted in the selected mode.</li>
+<li>Signals: Normal and DX. When the Sensitivity is set to DX the signal will run until the end of the image before resynchronization.</li>
+</ul>
+<p>Spectrum and Waterfall:<br />
+ There are three markers for SSTV (red lines):</p><ul>
+<li>1200: Sync frequency</li>
+<li>1500: Lower video frequency</li>
+<li>2300: Upper video frequency In DRM, the markers indicate the 3 unmodulated carrier frequencies </li>
+</ul>
+</div></div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="index.html">QSSTV 9.1</a></li>
+    <li class="footer">Generated on Sat Apr 16 2016 17:32:52 for QSSTV by
+    <a href="http://www.doxygen.org/index.html">
+    <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.9.1 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/qsstv/documentation/manual/manual/_t_x_d_r_m.html b/qsstv/documentation/manual/manual/_t_x_d_r_m.html
new file mode 100644
index 0000000..18897eb
--- /dev/null
+++ b/qsstv/documentation/manual/manual/_t_x_d_r_m.html
@@ -0,0 +1,124 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.9.1"/>
+<title>QSSTV: Transmit DRM Window</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<script type="text/javascript">
+  $(document).ready(initResizable);
+  $(window).load(resizeHeight);
+</script>
+<link href="qsstv.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+  <td style="padding-left: 0.5em;">
+   <div id="projectname">QSSTV
+    <span id="projectnumber">9.1</span>
+   </div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.9.1 -->
+  <div id="navrow1" class="tabs">
+    <ul class="tablist">
+      <li><a href="index.html"><span>Main Page</span></a></li>
+      <li class="current"><a href="pages.html"><span>Related Pages</span></a></li>
+    </ul>
+  </div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+$(document).ready(function(){initNavTree('_t_x_d_r_m.html','');});
+</script>
+<div id="doc-content">
+<div class="header">
+  <div class="headertitle">
+<div class="title">Transmit DRM Window </div>  </div>
+</div><!--header-->
+<div class="contents">
+<div class="textblock"><div class="image">
+<img src="transmitdrm.png" alt="transmitdrm.png"/>
+</div>
+<p>see also <a class="el" href="_t_x_s_s_t_v.html#sstvMenu">sstvMenu</a> under SSTV TX</p>
+<ul>
+<li><div class="image">
+<img src="binary.png" alt="binary.png"/>
+</div>
+ Click here to send a binary file (basically any file will do)</li>
+<li><div class="image">
+<img src="hybrid_checkbox.png" alt="hybrid_checkbox.png"/>
+</div>
+ When this check-box is checked, the image is transmitted in hybrid mode.</li>
+</ul>
+<p>For the other icons and actions see also <a class="el" href="_t_x_s_s_t_v.html">Transmit SSTV Window</a> <br />
+ <br />
+ Mode Selection </p><div class="image">
+<img src="txdrm_options.png" alt="txdrm_options.png"/>
+</div>
+<p> <br />
+</p><ul>
+<li>Mode (A,B or E)</li>
+<li>Bandwidth (2.3 KHz or 2.5 KHz)</li>
+<li>Interleave (Short or Long)</li>
+<li>Protection (Normal or High)</li>
+<li>QAM (4,16 or 64)</li>
+<li>Reed Solomon: (rs1, rs2, rs3 or rs4).File encoder for forward error correction. On HF it is recommended to always use Reed Solomon. The most often used is rs2. The higher the number, the more protection but also the more overhead.</li>
+<li>Profile: quick selection of a profile (i.e. settings of mode,QAM ...) as defined in the Options->Configuration->DRM Profiles) <br />
+</li>
+</ul>
+<div class="image">
+<img src="txdrm_status.png" alt="txdrm_status.png"/>
+</div>
+<p>The TX progress-bar indicates the progress of the transmission.</p>
+<p>see also <a class="el" href="_t_x_s_s_t_v.html#Control">Control</a> under SSTV TX</p><ul>
+<li>Last received image will be updated automatically as new images are received. They can be inserted if you use a template containing an "image replay object" see also <a class="el" href="editor.html">Editor</a> <br />
+</li>
+<li>Compression <br />
+<br />
+</li>
+</ul>
+<div class="image">
+<img src="txdrm_compression.png" alt="txdrm_compression.png"/>
+</div>
+<p> <br />
+Avoid to send huge images (especially if you're not in hybrid mode).<br />
+ You can drag the slider to compress the image before it is sent (the original image is not modified). The file size is shown on the right. You can see the result in the image frame when you release the handle. <br />
+ Note: This does not include the overhead of the RS-encoding. </p>
+</div></div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="index.html">QSSTV 9.1</a></li>
+    <li class="footer">Generated on Sat Apr 16 2016 17:32:52 for QSSTV by
+    <a href="http://www.doxygen.org/index.html">
+    <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.9.1 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/qsstv/documentation/manual/manual/_t_x_s_s_t_v.html b/qsstv/documentation/manual/manual/_t_x_s_s_t_v.html
new file mode 100644
index 0000000..f75fcc7
--- /dev/null
+++ b/qsstv/documentation/manual/manual/_t_x_s_s_t_v.html
@@ -0,0 +1,149 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.9.1"/>
+<title>QSSTV: Transmit SSTV Window</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<script type="text/javascript">
+  $(document).ready(initResizable);
+  $(window).load(resizeHeight);
+</script>
+<link href="qsstv.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+  <td style="padding-left: 0.5em;">
+   <div id="projectname">QSSTV
+    <span id="projectnumber">9.1</span>
+   </div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.9.1 -->
+  <div id="navrow1" class="tabs">
+    <ul class="tablist">
+      <li><a href="index.html"><span>Main Page</span></a></li>
+      <li class="current"><a href="pages.html"><span>Related Pages</span></a></li>
+    </ul>
+  </div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+$(document).ready(function(){initNavTree('_t_x_s_s_t_v.html','');});
+</script>
+<div id="doc-content">
+<div class="header">
+  <div class="headertitle">
+<div class="title">Transmit SSTV Window </div>  </div>
+</div><!--header-->
+<div class="contents">
+<div class="textblock"><div class="image">
+<img src="txwidget1.png" alt="txwidget1.png"/>
+</div>
+<p>The TX progress-bar indicates the progress of the transmission. <br />
+<br />
+ <a class="anchor" id="sstvMenu"></a>Menu toolbar: </p><ul>
+<li><div class="image">
+<img src="start.png" alt="start.png"/>
+</div>
+ start transmitting images </li>
+<li><div class="image">
+<img src="stop.png" alt="stop.png"/>
+</div>
+ stop transmitting images </li>
+<li><div class="image">
+<img src="tone.png" alt="tone.png"/>
+</div>
+ sends a repeater tone of 1750 Hz </li>
+<li><div class="image">
+<img src="fileopen.png" alt="fileopen.png"/>
+</div>
+ loads a file in the transmit window </li>
+<li><div class="image">
+<img src="edit.png" alt="edit.png"/>
+</div>
+ opens the image editor </li>
+<li><div class="image">
+<img src="camera.png" alt="camera.png"/>
+</div>
+ takes a snapshot if there is a camera installed that is supported by v4l2 </li>
+<li><div class="image">
+<img src="binary.png" alt="binary.png"/>
+</div>
+ only used in DRM mode </li>
+<li><div class="image">
+<img src="doubletone.png" alt="doubletone.png"/>
+</div>
+ let you select frequency and duration of a tone to send </li>
+<li><div class="image">
+<img src="sweep.png" alt="sweep.png"/>
+</div>
+ let you select the sweep frequencies and duration to send </li>
+<li><div class="image">
+<img src="hybrid_dis_checkbox.png" alt="hybrid_dis_checkbox.png"/>
+</div>
+ This check-box is disabled in SSTV mode </li>
+<li><div class="image">
+<img src="refreshbutton.png" alt="refreshbutton.png"/>
+</div>
+ You can refresh the content of the replay image by clicking the Refresh button (e.g. when you have loaded a new image in the preview image window).</li>
+</ul>
+<ul>
+<li>Select the transmission mode (Martin 1, Scottie etc.).</li>
+</ul>
+<p><a class="anchor" id="Control"></a></p><ul>
+<li>Select CW if you want to append a morse message after the image (the message is set in Options->Configuration->CW) .</li>
+<li>If the VOX check-box is set a tone will be sent before the actual image is sent so that you can use the VOX on your transceiver (if you do not have PTT control).</li>
+<li>Select the template (or none) you want as an overlay (see <a class="el" href="gallery.html">Gallery</a>). Only the templates that are in the Gallery will be available.</li>
+</ul>
+<p>The text inputs correspond to the following macros:</p>
+<ul>
+<li>TO: %c - call of the contacted station </li>
+<li>RSV %r - RSV (radio-strength-video best is 595) </li>
+<li>Op: %o - name of the operator of the contacted station </li>
+<li>x %x - comment1 </li>
+<li>y %y - comment2 </li>
+<li>z %z - comment3 <br />
+ see also <a class="el" href="editor.html">Editor</a></li>
+</ul>
+<ul>
+<li>The last received image is displayed at the bottom right. It will be updated automatically as new images are received. They can be inserted if you use a template containing an "image replay object" see also <a class="el" href="editor.html">Editor</a> <br />
+ Right clicking on this image also allows you to load other images for insertion. Use the refresh button to update the main window if necessary. </li>
+</ul>
+</div></div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="index.html">QSSTV 9.1</a></li>
+    <li class="footer">Generated on Sat Apr 16 2016 17:32:52 for QSSTV by
+    <a href="http://www.doxygen.org/index.html">
+    <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.9.1 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/qsstv/documentation/manual/manual/arrow.png b/qsstv/documentation/manual/manual/arrow.png
new file mode 100644
index 0000000..62229be
Binary files /dev/null and b/qsstv/documentation/manual/manual/arrow.png differ
diff --git a/qsstv/documentation/manual/manual/arrowdown.png b/qsstv/documentation/manual/manual/arrowdown.png
new file mode 100644
index 0000000..0b63f6d
Binary files /dev/null and b/qsstv/documentation/manual/manual/arrowdown.png differ
diff --git a/qsstv/documentation/manual/manual/arrowright.png b/qsstv/documentation/manual/manual/arrowright.png
new file mode 100644
index 0000000..c6ee22f
Binary files /dev/null and b/qsstv/documentation/manual/manual/arrowright.png differ
diff --git a/qsstv/documentation/manual/manual/bc_s.png b/qsstv/documentation/manual/manual/bc_s.png
new file mode 100644
index 0000000..224b29a
Binary files /dev/null and b/qsstv/documentation/manual/manual/bc_s.png differ
diff --git a/qsstv/documentation/manual/manual/bdwn.png b/qsstv/documentation/manual/manual/bdwn.png
new file mode 100644
index 0000000..940a0b9
Binary files /dev/null and b/qsstv/documentation/manual/manual/bdwn.png differ
diff --git a/qsstv/documentation/manual/manual/binary.png b/qsstv/documentation/manual/manual/binary.png
new file mode 100644
index 0000000..eae4e50
Binary files /dev/null and b/qsstv/documentation/manual/manual/binary.png differ
diff --git a/qsstv/documentation/manual/manual/bsr_nfy.png b/qsstv/documentation/manual/manual/bsr_nfy.png
new file mode 100644
index 0000000..62f029a
Binary files /dev/null and b/qsstv/documentation/manual/manual/bsr_nfy.png differ
diff --git a/qsstv/documentation/manual/manual/bsr_select.png b/qsstv/documentation/manual/manual/bsr_select.png
new file mode 100644
index 0000000..fb4cecb
Binary files /dev/null and b/qsstv/documentation/manual/manual/bsr_select.png differ
diff --git a/qsstv/documentation/manual/manual/calibration.png b/qsstv/documentation/manual/manual/calibration.png
new file mode 100644
index 0000000..4a3ca0e
Binary files /dev/null and b/qsstv/documentation/manual/manual/calibration.png differ
diff --git a/qsstv/documentation/manual/manual/camera.png b/qsstv/documentation/manual/manual/camera.png
new file mode 100644
index 0000000..6876fa9
Binary files /dev/null and b/qsstv/documentation/manual/manual/camera.png differ
diff --git a/qsstv/documentation/manual/manual/changelog.html b/qsstv/documentation/manual/manual/changelog.html
new file mode 100644
index 0000000..e129eb6
--- /dev/null
+++ b/qsstv/documentation/manual/manual/changelog.html
@@ -0,0 +1,161 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.9.1"/>
+<title>QSSTV: Change log</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<script type="text/javascript">
+  $(document).ready(initResizable);
+  $(window).load(resizeHeight);
+</script>
+<link href="qsstv.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+  <td style="padding-left: 0.5em;">
+   <div id="projectname">QSSTV
+    <span id="projectnumber">9.1</span>
+   </div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.9.1 -->
+  <div id="navrow1" class="tabs">
+    <ul class="tablist">
+      <li><a href="index.html"><span>Main Page</span></a></li>
+      <li class="current"><a href="pages.html"><span>Related Pages</span></a></li>
+    </ul>
+  </div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+$(document).ready(function(){initNavTree('changelog.html','');});
+</script>
+<div id="doc-content">
+<div class="header">
+  <div class="headertitle">
+<div class="title">Change log </div>  </div>
+</div><!--header-->
+<div class="contents">
+<div class="textblock"><ul>
+<li>20160416 QSSTV 9.1.5<ul>
+<li>upload received images to ftp server (sstv and drm) gave file error -> solved</li>
+</ul>
+</li>
+</ul>
+<ul>
+<li>20160415 QSSTV 9.1.4<ul>
+<li>rx image save button was not working -> fixed</li>
+</ul>
+</li>
+</ul>
+<ul>
+<li>20160410 QSSTV 9.1.3<ul>
+<li>fixing compiler error: missing function cleanupcache in release mode</li>
+</ul>
+</li>
+</ul>
+<ul>
+<li>20160409 QSSTV 9.1.2<ul>
+<li>implementation of image cache for faster image display in the gallery</li>
+<li>bug fix ,race condition for RxNotification</li>
+</ul>
+</li>
+</ul>
+<ul>
+<li>20160408 QSSTV 9.1.1<ul>
+<li>replaced jpeg2000 library Jasper with openjpeg because some distros won't support Jasper anymore. Jasper has not been maintained for more than 10 years.</li>
+</ul>
+</li>
+</ul>
+<ul>
+<li>20151130 QSSTV 9.0.9<ul>
+<li>directories are auto-created if they don't exist</li>
+<li>additional CAT command now also works with rigctld</li>
+</ul>
+</li>
+</ul>
+<ul>
+<li>20150930 QSSTV 9.0.8<ul>
+<li>fix DRM status update</li>
+</ul>
+</li>
+</ul>
+<ul>
+<li>20150929 QSSTV 9.0.7<ul>
+<li>fixed hang on exit</li>
+</ul>
+</li>
+</ul>
+<ul>
+<li>20150928 QSSTV 9.0.6<ul>
+<li>performace optimization (especially for Raspberry Pi 2)</li>
+</ul>
+</li>
+</ul>
+<ul>
+<li>20150926 QSSTV 9.0.4<ul>
+<li>added option for slow cpu (see Options ->GUI) This makes it possible to run QSSTV running on a Raspberry Pi 2.</li>
+<li>minor change to ALSA sound interface.</li>
+<li>some more bug fixing</li>
+</ul>
+</li>
+</ul>
+<ul>
+<li>20150910 QSSTV 9.0.3<ul>
+<li>xmlrpc bug fix (persistent connections)</li>
+<li>manual (a lot of) spelling corrections</li>
+<li>compatibility with Qt 4.8</li>
+</ul>
+</li>
+</ul>
+<ul>
+<li>20150907 QSSTV 9.0.2<ul>
+<li>changed configuration frequencies to allow for data modes on Icom</li>
+<li>changed Editor, you may need to check/re-edit your template files (text offsets may have changed)</li>
+</ul>
+</li>
+</ul>
+<ul>
+<li>20150831 QSSTV 9.0.1<ul>
+<li>first release </li>
+</ul>
+</li>
+</ul>
+</div></div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="index.html">QSSTV 9.1</a></li>
+    <li class="footer">Generated on Sat Apr 16 2016 17:32:52 for QSSTV by
+    <a href="http://www.doxygen.org/index.html">
+    <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.9.1 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/qsstv/documentation/manual/manual/closed.png b/qsstv/documentation/manual/manual/closed.png
new file mode 100644
index 0000000..98cc2c9
Binary files /dev/null and b/qsstv/documentation/manual/manual/closed.png differ
diff --git a/qsstv/documentation/manual/manual/config.png b/qsstv/documentation/manual/manual/config.png
new file mode 100644
index 0000000..39bce23
Binary files /dev/null and b/qsstv/documentation/manual/manual/config.png differ
diff --git a/qsstv/documentation/manual/manual/config1.png b/qsstv/documentation/manual/manual/config1.png
new file mode 100644
index 0000000..d49b745
Binary files /dev/null and b/qsstv/documentation/manual/manual/config1.png differ
diff --git a/qsstv/documentation/manual/manual/config10.png b/qsstv/documentation/manual/manual/config10.png
new file mode 100644
index 0000000..148c32a
Binary files /dev/null and b/qsstv/documentation/manual/manual/config10.png differ
diff --git a/qsstv/documentation/manual/manual/config11.png b/qsstv/documentation/manual/manual/config11.png
new file mode 100644
index 0000000..f66fc63
Binary files /dev/null and b/qsstv/documentation/manual/manual/config11.png differ
diff --git a/qsstv/documentation/manual/manual/config12.png b/qsstv/documentation/manual/manual/config12.png
new file mode 100644
index 0000000..1aba6de
Binary files /dev/null and b/qsstv/documentation/manual/manual/config12.png differ
diff --git a/qsstv/documentation/manual/manual/config2.png b/qsstv/documentation/manual/manual/config2.png
new file mode 100644
index 0000000..489b299
Binary files /dev/null and b/qsstv/documentation/manual/manual/config2.png differ
diff --git a/qsstv/documentation/manual/manual/config3.png b/qsstv/documentation/manual/manual/config3.png
new file mode 100644
index 0000000..eaf589f
Binary files /dev/null and b/qsstv/documentation/manual/manual/config3.png differ
diff --git a/qsstv/documentation/manual/manual/config4.png b/qsstv/documentation/manual/manual/config4.png
new file mode 100644
index 0000000..d93d128
Binary files /dev/null and b/qsstv/documentation/manual/manual/config4.png differ
diff --git a/qsstv/documentation/manual/manual/config5.png b/qsstv/documentation/manual/manual/config5.png
new file mode 100644
index 0000000..383973e
Binary files /dev/null and b/qsstv/documentation/manual/manual/config5.png differ
diff --git a/qsstv/documentation/manual/manual/config6.png b/qsstv/documentation/manual/manual/config6.png
new file mode 100644
index 0000000..7c84704
Binary files /dev/null and b/qsstv/documentation/manual/manual/config6.png differ
diff --git a/qsstv/documentation/manual/manual/config7.png b/qsstv/documentation/manual/manual/config7.png
new file mode 100644
index 0000000..5c1acb6
Binary files /dev/null and b/qsstv/documentation/manual/manual/config7.png differ
diff --git a/qsstv/documentation/manual/manual/config8.png b/qsstv/documentation/manual/manual/config8.png
new file mode 100644
index 0000000..44001f9
Binary files /dev/null and b/qsstv/documentation/manual/manual/config8.png differ
diff --git a/qsstv/documentation/manual/manual/config9.png b/qsstv/documentation/manual/manual/config9.png
new file mode 100644
index 0000000..9192705
Binary files /dev/null and b/qsstv/documentation/manual/manual/config9.png differ
diff --git a/qsstv/documentation/manual/manual/cqrlog1.png b/qsstv/documentation/manual/manual/cqrlog1.png
new file mode 100644
index 0000000..94c740a
Binary files /dev/null and b/qsstv/documentation/manual/manual/cqrlog1.png differ
diff --git a/qsstv/documentation/manual/manual/cqrlog2.png b/qsstv/documentation/manual/manual/cqrlog2.png
new file mode 100644
index 0000000..a7ebcf9
Binary files /dev/null and b/qsstv/documentation/manual/manual/cqrlog2.png differ
diff --git a/qsstv/documentation/manual/manual/credits.html b/qsstv/documentation/manual/manual/credits.html
new file mode 100644
index 0000000..b9c1238
--- /dev/null
+++ b/qsstv/documentation/manual/manual/credits.html
@@ -0,0 +1,98 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.9.1"/>
+<title>QSSTV: Credits</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<script type="text/javascript">
+  $(document).ready(initResizable);
+  $(window).load(resizeHeight);
+</script>
+<link href="qsstv.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+  <td style="padding-left: 0.5em;">
+   <div id="projectname">QSSTV
+    <span id="projectnumber">9.1</span>
+   </div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.9.1 -->
+  <div id="navrow1" class="tabs">
+    <ul class="tablist">
+      <li><a href="index.html"><span>Main Page</span></a></li>
+      <li class="current"><a href="pages.html"><span>Related Pages</span></a></li>
+    </ul>
+  </div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+$(document).ready(function(){initNavTree('credits.html','');});
+</script>
+<div id="doc-content">
+<div class="header">
+  <div class="headertitle">
+<div class="title">Credits </div>  </div>
+</div><!--header-->
+<div class="contents">
+<div class="textblock"><ul>
+<li>SSTV:<br />
+ Many thanks to all testers and users of QSSTV - too many to name them all. <br />
+<br />
+</li>
+<li>DRM:<br />
+ I started developing the DRM functionality in QSSTV after studying the excellent work Ties Bos (PA0MBO) did on txrxamadrm.<br />
+ see: <a href="http://www.pa0mbo.nl/ties/public_html/hamradio/txamadrm/index.html">http://www.pa0mbo.nl/ties/public_html/hamradio/txamadrm/index.html</a><br />
+ The software is NOT based on the hamdrm.dll but on DIORAMA (<a href="http://nt.eit.uni-kl.de/static/diorama/index.html">http://nt.eit.uni-kl.de/static/diorama/index.html</a>)<br />
+and adapted by PA0MBO. For more information , see the manual of txrxamadrm.</li>
+</ul>
+<p>This document contains references to Easypal (by VK4AES). Erik Sundstrup was kind enough to give me permission to use the extended BSR functionality and the DRM Hybrid mode. Easypal was used extensively to test my program. <br />
+ <br />
+ </p><div class="image">
+<img src="vk4aes.jpg" alt="vk4aes.jpg"/>
+</div>
+<p> <br />
+<br />
+</p>
+<p>Erik is now silent key as of 14th march 2015. We will miss him. <br />
+ I hope there will be other OM's that take up the maintenance,enhancements and development of EasyPal so that people running Windows will continue to enjoy his software. <br />
+reference: <a href="http://vk4aes.com/">http://vk4aes.com/</a> </p>
+</div></div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="index.html">QSSTV 9.1</a></li>
+    <li class="footer">Generated on Sat Apr 16 2016 17:32:52 for QSSTV by
+    <a href="http://www.doxygen.org/index.html">
+    <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.9.1 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/qsstv/documentation/manual/manual/doc.png b/qsstv/documentation/manual/manual/doc.png
new file mode 100644
index 0000000..17edabf
Binary files /dev/null and b/qsstv/documentation/manual/manual/doc.png differ
diff --git a/qsstv/documentation/manual/manual/doubletone.png b/qsstv/documentation/manual/manual/doubletone.png
new file mode 100644
index 0000000..c60ca1f
Binary files /dev/null and b/qsstv/documentation/manual/manual/doubletone.png differ
diff --git a/qsstv/documentation/manual/manual/doxygen.png b/qsstv/documentation/manual/manual/doxygen.png
new file mode 100644
index 0000000..3ff17d8
Binary files /dev/null and b/qsstv/documentation/manual/manual/doxygen.png differ
diff --git a/qsstv/documentation/manual/manual/dynsections.js b/qsstv/documentation/manual/manual/dynsections.js
new file mode 100644
index 0000000..85e1836
--- /dev/null
+++ b/qsstv/documentation/manual/manual/dynsections.js
@@ -0,0 +1,97 @@
+function toggleVisibility(linkObj)
+{
+ var base = $(linkObj).attr('id');
+ var summary = $('#'+base+'-summary');
+ var content = $('#'+base+'-content');
+ var trigger = $('#'+base+'-trigger');
+ var src=$(trigger).attr('src');
+ if (content.is(':visible')===true) {
+   content.hide();
+   summary.show();
+   $(linkObj).addClass('closed').removeClass('opened');
+   $(trigger).attr('src',src.substring(0,src.length-8)+'closed.png');
+ } else {
+   content.show();
+   summary.hide();
+   $(linkObj).removeClass('closed').addClass('opened');
+   $(trigger).attr('src',src.substring(0,src.length-10)+'open.png');
+ } 
+ return false;
+}
+
+function updateStripes()
+{
+  $('table.directory tr').
+       removeClass('even').filter(':visible:even').addClass('even');
+}
+
+function toggleLevel(level)
+{
+  $('table.directory tr').each(function() {
+    var l = this.id.split('_').length-1;
+    var i = $('#img'+this.id.substring(3));
+    var a = $('#arr'+this.id.substring(3));
+    if (l<level+1) {
+      i.removeClass('iconfopen iconfclosed').addClass('iconfopen');
+      a.html('▼');
+      $(this).show();
+    } else if (l==level+1) {
+      i.removeClass('iconfclosed iconfopen').addClass('iconfclosed');
+      a.html('►');
+      $(this).show();
+    } else {
+      $(this).hide();
+    }
+  });
+  updateStripes();
+}
+
+function toggleFolder(id)
+{
+  // the clicked row
+  var currentRow = $('#row_'+id);
+
+  // all rows after the clicked row
+  var rows = currentRow.nextAll("tr");
+
+  var re = new RegExp('^row_'+id+'\\d+_$', "i"); //only one sub
+
+  // only match elements AFTER this one (can't hide elements before)
+  var childRows = rows.filter(function() { return this.id.match(re); });
+
+  // first row is visible we are HIDING
+  if (childRows.filter(':first').is(':visible')===true) {
+    // replace down arrow by right arrow for current row
+    var currentRowSpans = currentRow.find("span");
+    currentRowSpans.filter(".iconfopen").removeClass("iconfopen").addClass("iconfclosed");
+    currentRowSpans.filter(".arrow").html('►');
+    rows.filter("[id^=row_"+id+"]").hide(); // hide all children
+  } else { // we are SHOWING
+    // replace right arrow by down arrow for current row
+    var currentRowSpans = currentRow.find("span");
+    currentRowSpans.filter(".iconfclosed").removeClass("iconfclosed").addClass("iconfopen");
+    currentRowSpans.filter(".arrow").html('▼');
+    // replace down arrows by right arrows for child rows
+    var childRowsSpans = childRows.find("span");
+    childRowsSpans.filter(".iconfopen").removeClass("iconfopen").addClass("iconfclosed");
+    childRowsSpans.filter(".arrow").html('►');
+    childRows.show(); //show all children
+  }
+  updateStripes();
+}
+
+
+function toggleInherit(id)
+{
+  var rows = $('tr.inherit.'+id);
+  var img = $('tr.inherit_header.'+id+' img');
+  var src = $(img).attr('src');
+  if (rows.filter(':first').is(':visible')===true) {
+    rows.css('display','none');
+    $(img).attr('src',src.substring(0,src.length-8)+'closed.png');
+  } else {
+    rows.css('display','table-row'); // using show() causes jump in firefox
+    $(img).attr('src',src.substring(0,src.length-10)+'open.png');
+  }
+}
+
diff --git a/qsstv/documentation/manual/manual/edit.png b/qsstv/documentation/manual/manual/edit.png
new file mode 100644
index 0000000..526ca69
Binary files /dev/null and b/qsstv/documentation/manual/manual/edit.png differ
diff --git a/qsstv/documentation/manual/manual/editor.html b/qsstv/documentation/manual/manual/editor.html
new file mode 100644
index 0000000..d650561
--- /dev/null
+++ b/qsstv/documentation/manual/manual/editor.html
@@ -0,0 +1,203 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.9.1"/>
+<title>QSSTV: Editor</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<script type="text/javascript">
+  $(document).ready(initResizable);
+  $(window).load(resizeHeight);
+</script>
+<link href="qsstv.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+  <td style="padding-left: 0.5em;">
+   <div id="projectname">QSSTV
+    <span id="projectnumber">9.1</span>
+   </div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.9.1 -->
+  <div id="navrow1" class="tabs">
+    <ul class="tablist">
+      <li><a href="index.html"><span>Main Page</span></a></li>
+      <li class="current"><a href="pages.html"><span>Related Pages</span></a></li>
+    </ul>
+  </div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+$(document).ready(function(){initNavTree('editor.html','');});
+</script>
+<div id="doc-content">
+<div class="header">
+  <div class="headertitle">
+<div class="title">Editor </div>  </div>
+</div><!--header-->
+<div class="contents">
+<div class="textblock"><p>The editor can be used for regular image editing and for the creation and editing of template images. Template images are used as overlays. They will be dynamically adapted when you select the template in the TX-window. While in edit mode, you can change all the attributes (such as size, position, colours etc ...). If you save the canvas as an image, the scene will be rendered (i.e. flattened) and become a single image object. If you save the canvas as a templat [...]
+<p><br />
+ To create an object, click on the left menu to select the type of object (e.g circle) and then click on the canvas where you want the object positioned. Just click on an item to select it. A outline of the item will be shown by a dashed line. If you hoover over the object you will see the cursor change to a hand-icon (in the middle of the object) to move it, or to a resize-icon if you are on a border.</p>
+<p>The attributes (line colour, fill colour, gradients etc ..) that are active in the top menu will be used to create the item. Object have also a z-component, i.e they can be in front our behind another object. This can be changed by right clicking on the item and use the Arrange selection.</p>
+<div class="image">
+<img src="editor_1.png" alt="editor_1.png"/>
+</div>
+ <ul>
+<li>Top menu 1<ul>
+<li>Image Size: Select the size of the image: the outline of the image will be shown on the canvas. <div class="image">
+<img src="editor_image_size.png" alt="editor_image_size.png"/>
+</div>
+</li>
+<li>Font: drop down box where you can select the text font</li>
+<li>Font size: text size</li>
+<li>Bold : bold text</li>
+<li>Italic: italic text</li>
+<li>Underline: underlined text</li>
+<li>Pen width: width of lines in number of pixels </li>
+</ul>
+</li>
+<li>Top menu 2<ul>
+<li>Fill: Fill colour drop down menu</li>
+<li>Line: Line colour drop down menu</li>
+<li>Gradient: Gradient selection menu</li>
+</ul>
+</li>
+</ul>
+<ul>
+<li>Left menu<ul>
+<li><div class="image">
+<img src="arrow.png" alt="arrow.png"/>
+</div>
+ select/deselect objects</li>
+<li><div class="image">
+<img src="fcircle.png" alt="fcircle.png"/>
+</div>
+ create filled circle/ellipse</li>
+<li><div class="image">
+<img src="frect.png" alt="frect.png"/>
+</div>
+ create filled rectangle -<div class="image">
+<img src="line.png" alt="line.png"/>
+</div>
+ create line -<div class="image">
+<img src="camera.png" alt="camera.png"/>
+</div>
+ insert image -<div class="image">
+<img src="replay.png" alt="replay.png"/>
+</div>
+ insert replay image place-holder. When the template will be loaded in the TX-window, this place-holder will replaced by the last received image -<div class="image">
+<img src="text.png" alt="text.png"/>
+</div>
+ create text. When you select this option a window will pop-up to enter text. <br />
+ -<div class="image">
+<img src="entertext.png" alt="entertext.png"/>
+</div>
+ <br />
+You can enter multiple lines of text. Click OK, the window will be hidden and you can click on the canvas to position the text. The text will appear on the canvas. -<div class="image">
+<img src="multiline.png" alt="multiline.png"/>
+</div>
+ <br />
+</li>
+</ul>
+</li>
+</ul>
+<ul>
+<li>Bottom menu<ul>
+<li>Horizontal Shear: shear selected object horizontally</li>
+<li>Rotate: rotate selected object </li>
+</ul>
+</li>
+<li>Right menu<ul>
+<li>Vertical Shear: shear selected object vertically </li>
+</ul>
+</li>
+</ul>
+<p>If you right click on an object then the following pop-up menu will be shown:</p>
+<ul>
+<li>Arrange<ul>
+<li>Forward - one level forward</li>
+<li>Backward - one level backward</li>
+<li>Bring to Front - all the way to the front</li>
+<li>Sent to Back - all the way to the back </li>
+</ul>
+</li>
+<li>Change text - change the text of a text object </li>
+<li>Expand - object will expand horizontally and vertically to fill the complete canvas </li>
+<li>Delete - remove selected object from the canvas </li>
+<li>Lock - lock items so that they can not be moved or resized </li>
+<li>Unlock - unlock selected items</li>
+</ul>
+<p>We need some sort of macro's to enable variable text when transmitting images. The editor uses predefined strings that will be replaced by the "actual content" when the template is processed just before transmission.<br />
+</p>
+<p>Here's an example of the editor using macros and the result in the transmitter.</p>
+<p><br />
+ </p><div class="image">
+<img src="editor_2.png" alt="editor_2.png"/>
+</div>
+<p> <br />
+<br />
+ </p><div class="image">
+<img src="transmitdrm.png" alt="transmitdrm.png"/>
+</div>
+<p>Following macro's are supported:<br />
+ Macro's where the value is defined in the configuration </p><ul>
+<li>%m - my callsign </li>
+<li>%q - my QTH </li>
+<li>%l - my locator </li>
+<li>%n - my last name </li>
+<li>%f - my first name</li>
+</ul>
+<p>Macro's where the value is entered in the TX-window prior to transmission </p><ul>
+<li>%c - call of the contacted station </li>
+<li>%r - RSV (radio-strength-video best is 595) You can also input free text as is sometimes required for contest (e.g. 595#007 or Good Copy) </li>
+<li>%o - name of the operator of the contacted station </li>
+<li>%x - comment1 </li>
+<li>%y - comment2 </li>
+<li>%z - comment3</li>
+</ul>
+<p>Note: comment 1,2 and 3 can be multi-line.</p>
+<p>Macro's where the value is defined by the system </p><ul>
+<li>%t - time in hours:minutes format </li>
+<li>%d - date in year/month/day format </li>
+<li>%v - qsstv_version </li>
+<li>%s - SNR - only to be used for DRM in the WF Text see also <a class="el" href="statusbar.html">Statusbar</a> </li>
+</ul>
+</div></div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="index.html">QSSTV 9.1</a></li>
+    <li class="footer">Generated on Sat Apr 16 2016 17:32:52 for QSSTV by
+    <a href="http://www.doxygen.org/index.html">
+    <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.9.1 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/qsstv/documentation/manual/manual/editor_1.png b/qsstv/documentation/manual/manual/editor_1.png
new file mode 100644
index 0000000..5e4102e
Binary files /dev/null and b/qsstv/documentation/manual/manual/editor_1.png differ
diff --git a/qsstv/documentation/manual/manual/editor_2.png b/qsstv/documentation/manual/manual/editor_2.png
new file mode 100644
index 0000000..ebb5617
Binary files /dev/null and b/qsstv/documentation/manual/manual/editor_2.png differ
diff --git a/qsstv/documentation/manual/manual/editor_image_size.png b/qsstv/documentation/manual/manual/editor_image_size.png
new file mode 100644
index 0000000..35d5a97
Binary files /dev/null and b/qsstv/documentation/manual/manual/editor_image_size.png differ
diff --git a/qsstv/documentation/manual/manual/entertext.png b/qsstv/documentation/manual/manual/entertext.png
new file mode 100644
index 0000000..83c76e6
Binary files /dev/null and b/qsstv/documentation/manual/manual/entertext.png differ
diff --git a/qsstv/documentation/manual/manual/eraser.png b/qsstv/documentation/manual/manual/eraser.png
new file mode 100644
index 0000000..78632a5
Binary files /dev/null and b/qsstv/documentation/manual/manual/eraser.png differ
diff --git a/qsstv/documentation/manual/manual/externalprog.html b/qsstv/documentation/manual/manual/externalprog.html
new file mode 100644
index 0000000..24b6862
--- /dev/null
+++ b/qsstv/documentation/manual/manual/externalprog.html
@@ -0,0 +1,113 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.9.1"/>
+<title>QSSTV: External Programs</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<script type="text/javascript">
+  $(document).ready(initResizable);
+  $(window).load(resizeHeight);
+</script>
+<link href="qsstv.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+  <td style="padding-left: 0.5em;">
+   <div id="projectname">QSSTV
+    <span id="projectnumber">9.1</span>
+   </div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.9.1 -->
+  <div id="navrow1" class="tabs">
+    <ul class="tablist">
+      <li><a href="index.html"><span>Main Page</span></a></li>
+      <li class="current"><a href="pages.html"><span>Related Pages</span></a></li>
+    </ul>
+  </div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+$(document).ready(function(){initNavTree('externalprog.html','');});
+</script>
+<div id="doc-content">
+<div class="header">
+  <div class="headertitle">
+<div class="title">External Programs </div>  </div>
+</div><!--header-->
+<div class="contents">
+<div class="textblock"><p>QSSTV can interface with other programs. <br />
+<br />
+ Flrig see <a class="el" href="gettingstarted.html#flrigconfig">flrigconfig</a></p>
+<p><br />
+<br />
+ Cqrlog: QSSTV (when in DRM mode) sends the following information to Cqrlog:</p><ul>
+<li>program: identifies QSSTV</li>
+<li>version: protocol version</li>
+<li>date: based on UTC</li>
+<li>time: based on UTC (time when the images is correctly received)</li>
+<li>endtime: based on UTC (always = time)</li>
+<li>call: call sign of the received station</li>
+<li>mhz: frequency in MHz</li>
+<li>mode: SSTV (ADIF restriction: there is no DSSTV nor DRM specified in ADIF, SSTV is the closest match)</li>
+<li>notes: contains file name, DRM mode information (i.e mode, QAM, protection.. hybrid)</li>
+</ul>
+<p><br />
+<br />
+</p><ul>
+<li>Setup: <br />
+<br />
+<div class="image">
+<img src="cqrlog1.png" alt="cqrlog1.png"/>
+</div>
+ <br />
+<br />
+</li>
+<li>Do not enable Run Fldigi ...</li>
+<li>Start Cqrlog and select Remote mode for Fldigi</li>
+<li>If you want to see the QSO's: Select "Show QSO list" from the file menu.<br />
+<br />
+ <div class="image">
+<img src="cqrlog2.png" alt="cqrlog2.png"/>
+</div>
+ <br />
+ Note: Unless you configured the Automatic refresh, you will only see the QSO's if you hit the Refresh button. </li>
+</ul>
+</div></div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="index.html">QSSTV 9.1</a></li>
+    <li class="footer">Generated on Sat Apr 16 2016 17:32:52 for QSSTV by
+    <a href="http://www.doxygen.org/index.html">
+    <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.9.1 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/qsstv/documentation/manual/manual/fcircle.png b/qsstv/documentation/manual/manual/fcircle.png
new file mode 100644
index 0000000..4f5fcc7
Binary files /dev/null and b/qsstv/documentation/manual/manual/fcircle.png differ
diff --git a/qsstv/documentation/manual/manual/fileopen.png b/qsstv/documentation/manual/manual/fileopen.png
new file mode 100644
index 0000000..a79982e
Binary files /dev/null and b/qsstv/documentation/manual/manual/fileopen.png differ
diff --git a/qsstv/documentation/manual/manual/filesave.png b/qsstv/documentation/manual/manual/filesave.png
new file mode 100644
index 0000000..3bc2a37
Binary files /dev/null and b/qsstv/documentation/manual/manual/filesave.png differ
diff --git a/qsstv/documentation/manual/manual/fix.png b/qsstv/documentation/manual/manual/fix.png
new file mode 100644
index 0000000..099c640
Binary files /dev/null and b/qsstv/documentation/manual/manual/fix.png differ
diff --git a/qsstv/documentation/manual/manual/fixdrm.html b/qsstv/documentation/manual/manual/fixdrm.html
new file mode 100644
index 0000000..a37d398
--- /dev/null
+++ b/qsstv/documentation/manual/manual/fixdrm.html
@@ -0,0 +1,83 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.9.1"/>
+<title>QSSTV: Sending FIX in DRM</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<script type="text/javascript">
+  $(document).ready(initResizable);
+  $(window).load(resizeHeight);
+</script>
+<link href="qsstv.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+  <td style="padding-left: 0.5em;">
+   <div id="projectname">QSSTV
+    <span id="projectnumber">9.1</span>
+   </div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.9.1 -->
+  <div id="navrow1" class="tabs">
+    <ul class="tablist">
+      <li><a href="index.html"><span>Main Page</span></a></li>
+      <li class="current"><a href="pages.html"><span>Related Pages</span></a></li>
+    </ul>
+  </div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+$(document).ready(function(){initNavTree('fixdrm.html','');});
+</script>
+<div id="doc-content">
+<div class="header">
+  <div class="headertitle">
+<div class="title">Sending FIX in DRM </div>  </div>
+</div><!--header-->
+<div class="contents">
+<div class="textblock"><div class="image">
+<img src="fix.png" alt="fix.png"/>
+</div>
+<p>When the image you transmitted is not correctly received, the other station can send a BSR. When you receive a BSR and it is destined for you, then the above popup will show. You can either send the fix or cancel.<br />
+ If the BSR is not for you then the following window will pop-up for a few seconds. </p><div class="image">
+<img src="bsr_nfy.png" alt="bsr_nfy.png"/>
+</div>
+ </div></div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="index.html">QSSTV 9.1</a></li>
+    <li class="footer">Generated on Sat Apr 16 2016 17:32:52 for QSSTV by
+    <a href="http://www.doxygen.org/index.html">
+    <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.9.1 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/qsstv/documentation/manual/manual/flrig1.png b/qsstv/documentation/manual/manual/flrig1.png
new file mode 100644
index 0000000..430c469
Binary files /dev/null and b/qsstv/documentation/manual/manual/flrig1.png differ
diff --git a/qsstv/documentation/manual/manual/folderclosed.png b/qsstv/documentation/manual/manual/folderclosed.png
new file mode 100644
index 0000000..bb8ab35
Binary files /dev/null and b/qsstv/documentation/manual/manual/folderclosed.png differ
diff --git a/qsstv/documentation/manual/manual/folderopen.png b/qsstv/documentation/manual/manual/folderopen.png
new file mode 100644
index 0000000..d6c7f67
Binary files /dev/null and b/qsstv/documentation/manual/manual/folderopen.png differ
diff --git a/qsstv/documentation/manual/manual/frect.png b/qsstv/documentation/manual/manual/frect.png
new file mode 100644
index 0000000..2aa6af8
Binary files /dev/null and b/qsstv/documentation/manual/manual/frect.png differ
diff --git a/qsstv/documentation/manual/manual/gallery.html b/qsstv/documentation/manual/manual/gallery.html
new file mode 100644
index 0000000..cc4febb
--- /dev/null
+++ b/qsstv/documentation/manual/manual/gallery.html
@@ -0,0 +1,89 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.9.1"/>
+<title>QSSTV: Gallery</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<script type="text/javascript">
+  $(document).ready(initResizable);
+  $(window).load(resizeHeight);
+</script>
+<link href="qsstv.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+  <td style="padding-left: 0.5em;">
+   <div id="projectname">QSSTV
+    <span id="projectnumber">9.1</span>
+   </div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.9.1 -->
+  <div id="navrow1" class="tabs">
+    <ul class="tablist">
+      <li><a href="index.html"><span>Main Page</span></a></li>
+      <li class="current"><a href="pages.html"><span>Related Pages</span></a></li>
+    </ul>
+  </div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+$(document).ready(function(){initNavTree('gallery.html','');});
+</script>
+<div id="doc-content">
+<div class="header">
+  <div class="headertitle">
+<div class="title">Gallery </div>  </div>
+</div><!--header-->
+<div class="contents">
+<div class="textblock"><p>The Gallery contains six tabs. The directories where the different images are stored are configured in the Directories tab of the Configuration. <br />
+ </p><div class="image">
+<img src="Gallery_rx.png" alt="Gallery_rx.png"/>
+</div>
+<p> <br />
+ -RX SSTV: SSTV images are stored on disk and shown here if the Auto-save is enabled in the receive window and the minimum percentage is reached -RX DRM: All images received in DRM mode are stored on disk and shown here. -TX SSTV: When sending an image in SSTV mode then the resulting images is stored on disk and shown here (this includes the template overlay). -TX DRM: When sending an image in SSTV mode then the resulting images is stored on disk and shown here (this includes the templat [...]
+ <br />
+ </p><div class="image">
+<img src="Gallery_tx.png" alt="Gallery_tx.png"/>
+</div>
+<p> -Templates: template images to be used as overlay on tx images </p><div class="image">
+<img src="Gallery_template.png" alt="Gallery_template.png"/>
+</div>
+ </div></div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="index.html">QSSTV 9.1</a></li>
+    <li class="footer">Generated on Sat Apr 16 2016 17:32:52 for QSSTV by
+    <a href="http://www.doxygen.org/index.html">
+    <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.9.1 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/qsstv/documentation/manual/manual/gettingstarted.html b/qsstv/documentation/manual/manual/gettingstarted.html
new file mode 100644
index 0000000..ccd33a9
--- /dev/null
+++ b/qsstv/documentation/manual/manual/gettingstarted.html
@@ -0,0 +1,366 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.9.1"/>
+<title>QSSTV: Getting Started</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<script type="text/javascript">
+  $(document).ready(initResizable);
+  $(window).load(resizeHeight);
+</script>
+<link href="qsstv.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+  <td style="padding-left: 0.5em;">
+   <div id="projectname">QSSTV
+    <span id="projectnumber">9.1</span>
+   </div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.9.1 -->
+  <div id="navrow1" class="tabs">
+    <ul class="tablist">
+      <li><a href="index.html"><span>Main Page</span></a></li>
+      <li class="current"><a href="pages.html"><span>Related Pages</span></a></li>
+    </ul>
+  </div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+$(document).ready(function(){initNavTree('gettingstarted.html','');});
+</script>
+<div id="doc-content">
+<div class="header">
+  <div class="headertitle">
+<div class="title">Getting Started </div>  </div>
+</div><!--header-->
+<div class="contents">
+<div class="textblock"><p>The program is build around 3 windows</p><ul>
+<li>Receive window: Receive functions and configuration</li>
+<li>Transmit window: Transmit functions and camera control</li>
+<li>Gallery window: History of received images, transmit images and templates The program will remember the last position and the size of each window on restart.</li>
+</ul>
+<h1><a class="anchor" id="config"></a>
+Configuration</h1>
+<p>Before we can use QSSTV you need to do some configuration. </p><div class="image">
+<img src="config.png" alt="config.png"/>
+</div>
+<p> The configuration tool is accessed through the "Options" menu in the receive window. The following tabs are available <br />
+<br />
+ </p><ul>
+<li>Personal Settings <br />
+<br />
+ <div class="image">
+<img src="config1.png" alt="config1.png"/>
+</div>
+ <br />
+<br />
+<ul>
+<li>Call sign</li>
+<li>First Name</li>
+<li>Last Name</li>
+<li>QTH</li>
+<li>Locator (Grid Square) <br />
+This information can also be used in templates (see also <a class="el" href="editor.html">Editor</a>) <br />
+<br />
+</li>
+</ul>
+</li>
+</ul>
+<ul>
+<li>Directories <br />
+<br />
+ <div class="image">
+<img src="config2.png" alt="config2.png"/>
+</div>
+ <br />
+<br />
+<ul>
+<li>RX SSTV Images: directory for saving the SSTV received images</li>
+<li>RX DRM Images: directory for saving the DRM received images</li>
+<li>TX Images: directory for images to transmit</li>
+<li>Templates: directory where the template files are stored</li>
+<li>Audio Records: directory for audio files (where you save/read recorded audio files)</li>
+<li>Documentation: URL of the user manual (if you copied the manual locally then you can point to it with e.g. <a href="file:///usr/share/doc/qsstv/manual">file:///usr/share/doc/qsstv/manual</a> <br />
+<br />
+</li>
+</ul>
+</li>
+</ul>
+<ul>
+<li>Gui <br />
+<br />
+ <div class="image">
+<img src="config3.png" alt="config3.png"/>
+</div>
+ <br />
+<br />
+<ul>
+<li>Stretch: if checked, the image will fill the receive window (keeping the aspect ratio) else it will be displayed as is.</li>
+<li>Background Colour: colour used for image borders and background in the gallery</li>
+<li>Image Background Colour: Default image background Push the push button to select the colour selector.</li>
+<li>Gallery: Rows and columns: set-up the number of rows and columns to be used in the Gallery tab. If you're running on a slow CPU (like on a Raspberry Pi) select row=1 and columns=1.</li>
+<li>Slow CPU: Select this option if you're running on a slow CPU (e.g. Rapsberry Pi)</li>
+</ul>
+</li>
+</ul>
+<p><br />
+<br />
+</p>
+<ul>
+<li>Audio <br />
+<br />
+ <div class="image">
+<img src="config4.png" alt="config4.png"/>
+</div>
+ <br />
+<br />
+<ul>
+<li>ALSA Input Audio Device : depending on your hardware (e.g. default,hw:0,0)</li>
+<li>ALSA Output Audio Device : depending on your hardware (e.g. default,hw:0,0)</li>
+<li>PulseAudio: native pulse audio interface Note: <b> Most distributions use Pulse Audio interface.. You can select the audio card settings through the audio applet by right clicking on the Speaker icon and selecting the Sound Preferences</b></li>
+<li>RX Clock frequency : clock used while receiving SSTV images,(see also <a class="el" href="gettingstarted.html#calib">Calibration</a>)</li>
+<li>TX Clock frequency : clock used while transmitting SSTV images,(see also <a class="el" href="gettingstarted.html#calib">Calibration</a>)</li>
+<li>Sound Input routing<ul>
+<li>From sound card: default mode</li>
+<li>From file: decode a previously recorded file</li>
+<li>From sound card and record: decode and record to a file (wav type, stereo 48000)</li>
+<li>Maximum recording size: limits the size of the recorded file</li>
+</ul>
+</li>
+<li>Sound Output routing<ul>
+<li>To sound card: default</li>
+<li>Playback: playback a wav-file (use 48000 samples per second recording in mono or stereo)</li>
+<li>Playback and record: playback the sound and record at the same time. <br />
+ Note: To playback an audio file, be sure the format is of type wav and has a samplerate of 48000 samples/second. You can always open the file with audacity and export the file to adapt the type and/or samplerate<br />
+</li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+<ul>
+<li>CAT <br />
+<br />
+ <div class="image">
+<img src="config5.png" alt="config5.png"/>
+</div>
+ <br />
+<br />
+</li>
+</ul>
+<ul>
+<li>Special Serial Port: If you have a separate serial interface to control the PTT you can enable Special Serial Port to control it. You can select RTS and or DTR in inverted or non-inverted mode (i.e. +RTS will assert RTS at +12V when the PTT is active and -RTS will assert RTS at -12V). +RTS and/or +DTR is used most of the time. The same goes for DTR. <br />
+ You cannot select both +RTS and -RTS or +DTR and -DTR at the same time.</li>
+<li>Enable Hamlib Cat Interface<ul>
+<li>Radio Model: drop down list from the radio models</li>
+<li>CIV Address: only used for ICOM, if left empty, the default address of the radio will be used</li>
+<li>Serial Port/host: either the serial port (e.g. /dev/ttyUSB0) or the host address (e.g. localhost:4532)</li>
+<li>Handshake, Parity, Data bits, Stop bits, Baud rate: serial port settings</li>
+<li>PTT Serial Port: serial port (e.g. /dev/ttyS0) only used if "Enable PTT serial Interface" is selected</li>
+<li>PTT Control via: If the radio uses a CAT command to activate Transmission then select "CAT". If you have a radio that does not support such a CAT command, you can let Hamlib use the RTS or DTR on the serial port specified by "PTT Serial Port". Example: IC-706MKIIG via a cat interface such as interfaceOne. <a class="anchor" id="flrigconfig"></a></li>
+</ul>
+</li>
+<li>Enable XMLRPC This allows you to connect to the Flrig program using the XMLRPC protocol. Flrig will handle all the communication with the transceiver (including PTT).</li>
+<li>TX Delay: The program will wait for the selected delay before transmitting any audio.</li>
+</ul>
+<p>Note: The option Enable XMLRPC excludes the use of hamlib.</p>
+<p>A sample set-up of Flrig is shown below. <br />
+<br />
+ </p><div class="image">
+<img src="flrig1.png" alt="flrig1.png"/>
+</div>
+<p> <br />
+<br />
+</p>
+<ul>
+<li>CW <br />
+<br />
+ <div class="image">
+<img src="config6.png" alt="config6.png"/>
+</div>
+ <br />
+<br />
+<ul>
+<li>Tone: frequency of the CW tone</li>
+<li>Words per Minute: CW transmission speed</li>
+<li>Text To Send: this text will be send at the end of an image transmission if the option is enabled.</li>
+</ul>
+</li>
+</ul>
+<ul>
+<li>Repeater <br />
+<br />
+ <div class="image">
+<img src="config7.png" alt="config7.png"/>
+</div>
+ <br />
+<br />
+<ul>
+<li>Enable repeater: enable repeater operation</li>
+<li>Image Interval (min): interval time before sending one of the Idle Images</li>
+<li>Repeater TX mode: the mode the repeater will use to send the images</li>
+<li>Idle Image[1-4]: images send by the repeater if there is no activity for more than the interval time</li>
+<li>Idle Template:template that will be super-imposed on the idle images</li>
+<li>Repeater Template: template that will be super-imposed on the repeated(received) images</li>
+</ul>
+</li>
+</ul>
+<ul>
+<li>FTP <br />
+<br />
+ <div class="image">
+<img src="config8.png" alt="config8.png"/>
+</div>
+ <br />
+<br />
+ This is used to save the received images to an FTP server. The images will also still be saved in the local rx folder.<ul>
+<li>Enable FTP: enable ftp operation</li>
+<li>FTP Port: default 21</li>
+<li>Default Image Format: select the image format from the drop down bow (used only in SSTV)</li>
+<li>Remote Hostname: hostname of the ftp server (e.g. myftp.home.net or 192.168.0.1)</li>
+<li>Remote directory:the ftp server directory where you'll store the images</li>
+<li>FTP Login name: your login name on the server (can be anonymous)</li>
+<li>FTP Password: if you need one, otherwise leave blank</li>
+<li>Image store:<ul>
+<li>Image1 - image30: The files will be saved under the generic name imageXX, where xx ranges from 1 to 30. When a new image arrives, the old images are shifted down (i.e. image29 becomes image30, image28 becomes image 29 etc ..) and the new one is stored as image1. -file name: the image (or other type of file) is stored with a file name derived from the mode (SSTV) or from the file name transmitted in DRM.</li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+<p>Note: This FTP server is unrelated to the FTP server for Hybrid Mode.</p>
+<p>You can test the connection by clicking the Test connection button. It will set-up a connection to the server and send a test file to check if all parameters are correct. You will either see a pop-up with "Connection OK" or an error message showing the reason of the fail.</p>
+<ul>
+<li>Waterfall <br />
+<br />
+ <div class="image">
+<img src="config9.png" alt="config9.png"/>
+</div>
+ <br />
+<br />
+<ul>
+<li>Start Pic: Waterfall text to send at the beginning of a DRM transmission</li>
+<li>End Pic: Waterfall text to send at the end of a DRM transmission</li>
+<li>FIX: Waterfall text to send at the beginning of a DRM retransmission</li>
+<li>BSR: Waterfall text to send at the beginning of a DRM request for retransmission <br />
+ Note: you can also use %m. This will be replaced by your call sign</li>
+</ul>
+</li>
+</ul>
+<ul>
+<li>Hybrid <br />
+<br />
+ <div class="image">
+<img src="config10.png" alt="config10.png"/>
+</div>
+ <br />
+<br />
+<ul>
+<li>Enable Reception in Hybrid Mode: allows reception of hamDRM in hybrid mode. If this is not enabled, hybrid mode files will not be shown or stored.</li>
+<li>Enable Special server: Activate only if you want to use a different server than the preprogrammed default one of VK4AES</li>
+<li>FTP Port: default 21</li>
+<li>Remote Hostname: hostname of your ftp server</li>
+<li>Remote directory:the ftp server directory where the stored images are</li>
+<li>FTP Login name: the login name on the server</li>
+<li>FTP Password: will be encrypted</li>
+</ul>
+</li>
+</ul>
+<p>Login name, password,hostname and directories will be encrypted before being sent on the air.</p>
+<p>If you want to use the special server, the directories to store images is relative to the directory HybridFiles1. So first create a top level directory HybridFiles1. If you leave the Remote Directory empty, then the files will be placed in the directory HybridFiles1. If you put for example "testdir" in the Remote Directory (as shown in the above screen shot), then you need to create testdir under HybridFiles (HybridFiles1/testdir).</p>
+<p>QSSTV will not create those directories for you.</p>
+<p>EasyPal also use two other directories on the same level as HybridFiles1</p><ul>
+<li>OnlineCallsigns1</li>
+<li>RxOkNotifications1</li>
+</ul>
+<p>You can create them on your server but they are not used by QSSTV at this moment.</p>
+<p>You can test the connection by clicking the Test connection button. It will setup a connection to the server and send a test file to check if all parameters are correct. You will either see a pop-up with "Connection OK" or an error message showing the reason of the fail.</p>
+<ul>
+<li>DRM Profiles <br />
+<br />
+ <div class="image">
+<img src="config11.png" alt="config11.png"/>
+</div>
+ <br />
+<br />
+ Used for quick selection of the most common settings you use in DRM. Choose a short name for the profile and make a selection for all the parameters. The name will appear in the Profiles drop-down box in the Transmit window for DRM.</li>
+</ul>
+<ul>
+<li>Frequencies <a class="anchor" id="configFreq"></a><br />
+<br />
+ <div class="image">
+<img src="config12.png" alt="config12.png"/>
+</div>
+ <br />
+<br />
+<ul>
+<li>List of selectable frequencies. Click Add to add a new combo frequency/mode/modulation. Enter the frequency and select the mode and modulation type.<br />
+ To move a frequency/mode/modulation up or down the list, click first on the entry in the table and then click on one of the arrow buttons.</li>
+<li>Hamlib Data Command: (only used with Hamlib) As far a I know Hamlib does not support switching the Icomxxx to data mode. As a result, if you for example selected USB-D1 on a Icom 7600,changing the frequency will switch the rig back to the regular USB (data mode off).<br />
+ Hamlib Data Command allows you to send a "raw command" that will be executed when you change frequencies.</li>
+<li>Example: FEFE7AE01A060101FD and Hex button checked: will put the Icom in data mode D1 (LSB, USB or FM) and the Filter 1.</li>
+<li>Hex: if checked the text is interpreted as hex values else it will be interpreted as a regular ASCII string.</li>
+<li>Note 1: you can put any valid raw command here, it will be send on every frequency change</li>
+<li>Note 2: Flrig does not support FM data modes.</li>
+</ul>
+</li>
+</ul>
+<h1><a class="anchor" id="calib"></a>
+Calibration</h1>
+<p>Note: Calibration is only needed for SSTV mode All SSTV applications need an accurate and stable clock. The accuracy of a PC clock is not always correct. Therefore it's necessary to execute some sort of calibration. You need to synchronize your PC with an network time server via the ntp protocol. Every Linux distribution has some configuration tool that allows you to install the ntp client. Be sure it's active. You can check it with: </p><pre>
+>ntpdc -p
+</pre><p>The selected ntp server should have an asterisk in the first column. </p><pre>
+remote           local      st poll reach  delay   offset    disp
+=======================================================================
+*stratum1dc1.bc  10.119.37.19     2   64  377 0.00386  0.036853 0.06850
+</pre><p>You can now launch the Calibration.<br />
+<br />
+ <b>It will take several minutes to complete. Be sure to wait long enough, the progress is extremely slow</b> <br />
+<br />
+ </p><div class="image">
+<img src="calibration.png" alt="calibration.png"/>
+</div>
+<p> When RX and TX calibration is finished, press the OK button to accept the new values.</p>
+<ul>
+<li>Note: You can always enter the clock values manually. </li>
+</ul>
+</div></div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="index.html">QSSTV 9.1</a></li>
+    <li class="footer">Generated on Sat Apr 16 2016 17:32:52 for QSSTV by
+    <a href="http://www.doxygen.org/index.html">
+    <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.9.1 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/qsstv/documentation/manual/manual/hybrid_checkbox.png b/qsstv/documentation/manual/manual/hybrid_checkbox.png
new file mode 100644
index 0000000..36bb44e
Binary files /dev/null and b/qsstv/documentation/manual/manual/hybrid_checkbox.png differ
diff --git a/qsstv/documentation/manual/manual/hybrid_dis_checkbox.png b/qsstv/documentation/manual/manual/hybrid_dis_checkbox.png
new file mode 100644
index 0000000..ee13f95
Binary files /dev/null and b/qsstv/documentation/manual/manual/hybrid_dis_checkbox.png differ
diff --git a/qsstv/documentation/manual/manual/imagepopup.html b/qsstv/documentation/manual/manual/imagepopup.html
new file mode 100644
index 0000000..f8b3899
--- /dev/null
+++ b/qsstv/documentation/manual/manual/imagepopup.html
@@ -0,0 +1,93 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.9.1"/>
+<title>QSSTV: Image Viewer</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<script type="text/javascript">
+  $(document).ready(initResizable);
+  $(window).load(resizeHeight);
+</script>
+<link href="qsstv.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+  <td style="padding-left: 0.5em;">
+   <div id="projectname">QSSTV
+    <span id="projectnumber">9.1</span>
+   </div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.9.1 -->
+  <div id="navrow1" class="tabs">
+    <ul class="tablist">
+      <li><a href="index.html"><span>Main Page</span></a></li>
+      <li class="current"><a href="pages.html"><span>Related Pages</span></a></li>
+    </ul>
+  </div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+$(document).ready(function(){initNavTree('imagepopup.html','');});
+</script>
+<div id="doc-content">
+<div class="header">
+  <div class="headertitle">
+<div class="title">Image Viewer </div>  </div>
+</div><!--header-->
+<div class="contents">
+<div class="textblock"><p>All the images displayed in QSSTV have pop-up actions. This is an example for the Gallery.</p>
+<p><br />
+ </p><div class="image">
+<img src="Gallery_image_options.png" alt="Gallery_image_options.png"/>
+</div>
+<p> <br />
+<br />
+ By right clicking on the images, a pop-up window appears that can have one or more of the following actions:</p><ul>
+<li>New: open the editor to create a new image.</li>
+<li>Load: load new file into window</li>
+<li>To TX: send image to TX window</li>
+<li>Edit: edit the selected image</li>
+<li>Print: print the selected image</li>
+<li>Delete: delete the selected image, a pop-up will ask if you want to delete the file also from disk., if so the file will be moved to the trash folder.</li>
+<li>View: Display the image in a new window actual size (the window is resizeable).</li>
+<li>Properties: displays the image and file properties if available </li>
+</ul>
+</div></div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="index.html">QSSTV 9.1</a></li>
+    <li class="footer">Generated on Sat Apr 16 2016 17:32:52 for QSSTV by
+    <a href="http://www.doxygen.org/index.html">
+    <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.9.1 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/qsstv/documentation/manual/manual/index.html b/qsstv/documentation/manual/manual/index.html
new file mode 100644
index 0000000..3760865
--- /dev/null
+++ b/qsstv/documentation/manual/manual/index.html
@@ -0,0 +1,101 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.9.1"/>
+<title>QSSTV: QSSTV 9.1</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<script type="text/javascript">
+  $(document).ready(initResizable);
+  $(window).load(resizeHeight);
+</script>
+<link href="qsstv.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+  <td style="padding-left: 0.5em;">
+   <div id="projectname">QSSTV
+    <span id="projectnumber">9.1</span>
+   </div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.9.1 -->
+  <div id="navrow1" class="tabs">
+    <ul class="tablist">
+      <li class="current"><a href="index.html"><span>Main Page</span></a></li>
+      <li><a href="pages.html"><span>Related Pages</span></a></li>
+    </ul>
+  </div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+$(document).ready(function(){initNavTree('index.html','');});
+</script>
+<div id="doc-content">
+<div class="header">
+  <div class="headertitle">
+<div class="title">QSSTV 9.1 </div>  </div>
+</div><!--header-->
+<div class="contents">
+<div class="textblock"><dl class="section author"><dt>Author</dt><dd>Johan Maes ON4QZ</dd></dl>
+<h1><a class="anchor" id="intro_sec"></a>
+Introduction</h1>
+<p>QSSTV 9 is a program for receiving and transmitting SSTV and HAMDRM (sometimes called DSSTV). It is compatible with most of MMSSTV and EasyPal<br />
+</p>
+<p>!!! ALSO READ THE FAQ AT <a href="http://users.telenet.be/on4qz/qsstv_9/faq.html">http://users.telenet.be/on4qz/qsstv_9/faq.html</a> !!!</p>
+<p>This manual is divided in the following sections:</p><ul>
+<li><a class="el" href="whatsnew.html">What's New</a></li>
+<li><a class="el" href="changelog.html">Change log</a></li>
+<li><a class="el" href="installation.html">Installation</a></li>
+<li><a class="el" href="gettingstarted.html">Getting Started</a></li>
+<li><a class="el" href="statusbar.html">Statusbar</a></li>
+<li><a class="el" href="imagepopup.html">Image Viewer</a></li>
+<li><a class="el" href="_r_x_s_s_t_v.html">Receive SSTV Window</a></li>
+<li><a class="el" href="_t_x_s_s_t_v.html">Transmit SSTV Window</a></li>
+<li><a class="el" href="_r_x_d_r_m.html">Receive DRM Window</a></li>
+<li><a class="el" href="_t_x_d_r_m.html">Transmit DRM Window</a></li>
+<li><a class="el" href="fixdrm.html">Sending FIX in DRM</a></li>
+<li><a class="el" href="gallery.html">Gallery</a></li>
+<li><a class="el" href="editor.html">Editor</a></li>
+<li><a class="el" href="externalprog.html">External Programs</a></li>
+<li><a class="el" href="todo1.html">To Do</a></li>
+<li><a class="el" href="credits.html">Credits</a></li>
+<li><a class="el" href="_copying.html">Copying</a></li>
+</ul>
+<p>73's Johan ON4QZ </p>
+</div></div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="footer">Generated on Sat Apr 16 2016 17:32:52 for QSSTV by
+    <a href="http://www.doxygen.org/index.html">
+    <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.9.1 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/qsstv/documentation/manual/manual/index.js b/qsstv/documentation/manual/manual/index.js
new file mode 100644
index 0000000..6d2edb5
--- /dev/null
+++ b/qsstv/documentation/manual/manual/index.js
@@ -0,0 +1,29 @@
+var index =
+[
+    [ "Introduction", "index.html#intro_sec", null ],
+    [ "What's New", "whatsnew.html", null ],
+    [ "Change log", "changelog.html", null ],
+    [ "Installation", "installation.html", [
+      [ "Step 1: Prerequisites", "installation.html#step1", null ],
+      [ "Step 2: Getting the software", "installation.html#step2", null ],
+      [ "Step 3: Compile and Install the software", "installation.html#step3", null ],
+      [ "Step 4: Run QSSTV", "installation.html#step4", null ]
+    ] ],
+    [ "Getting Started", "gettingstarted.html", [
+      [ "Configuration", "gettingstarted.html#config", null ],
+      [ "Calibration", "gettingstarted.html#calib", null ]
+    ] ],
+    [ "Statusbar", "statusbar.html", null ],
+    [ "Image Viewer", "imagepopup.html", null ],
+    [ "Receive SSTV Window", "_r_x_s_s_t_v.html", null ],
+    [ "Transmit SSTV Window", "_t_x_s_s_t_v.html", null ],
+    [ "Receive DRM Window", "_r_x_d_r_m.html", null ],
+    [ "Transmit DRM Window", "_t_x_d_r_m.html", null ],
+    [ "Sending FIX in DRM", "fixdrm.html", null ],
+    [ "Gallery", "gallery.html", null ],
+    [ "Editor", "editor.html", null ],
+    [ "External Programs", "externalprog.html", null ],
+    [ "To Do", "todo1.html", null ],
+    [ "Credits", "credits.html", null ],
+    [ "Copying", "_copying.html", null ]
+];
\ No newline at end of file
diff --git a/qsstv/documentation/manual/manual/installation.html b/qsstv/documentation/manual/manual/installation.html
new file mode 100644
index 0000000..493b160
--- /dev/null
+++ b/qsstv/documentation/manual/manual/installation.html
@@ -0,0 +1,114 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.9.1"/>
+<title>QSSTV: Installation</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<script type="text/javascript">
+  $(document).ready(initResizable);
+  $(window).load(resizeHeight);
+</script>
+<link href="qsstv.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+  <td style="padding-left: 0.5em;">
+   <div id="projectname">QSSTV
+    <span id="projectnumber">9.1</span>
+   </div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.9.1 -->
+  <div id="navrow1" class="tabs">
+    <ul class="tablist">
+      <li><a href="index.html"><span>Main Page</span></a></li>
+      <li class="current"><a href="pages.html"><span>Related Pages</span></a></li>
+    </ul>
+  </div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+$(document).ready(function(){initNavTree('installation.html','');});
+</script>
+<div id="doc-content">
+<div class="header">
+  <div class="headertitle">
+<div class="title">Installation </div>  </div>
+</div><!--header-->
+<div class="contents">
+<div class="textblock"><p>Warning: from version 9.1.1 and higher, Jasper library is dropped and openjpeg is used We need openjpeg2 (e.g. libopenjpeg2.1 or higher) and not libopenjpeg 1.5</p>
+<h1><a class="anchor" id="step1"></a>
+Step 1: Prerequisites</h1>
+<p>Before you can compile QSSTV make sure that you have installed the following software</p><ul>
+<li>g++</li>
+<li>libfftw3-dev</li>
+<li>qt5-default (qt4-default)</li>
+<li>hamlib-dev</li>
+<li>libasound2-dev</li>
+<li>libpulse-dev</li>
+<li>libopenjp2-7</li>
+<li>libopenjp2-7-dev</li>
+<li>libv4l-dev</li>
+</ul>
+<p>QSSTV is compatible with Qt 4.8.6 but mostly tested on Qt 5.4.x or higher</p>
+<p>On Ubuntu, Debian or Mint you can type:</p>
+<pre>sudo apt-get install g++ libfftw3-dev qt5-default libpulse-dev</pre> <pre>sudo apt-get install hamlib-dev libasound-dev  libv4l-dev</pre> <pre>sudo apt-get install libopenjp2-7 libopenjp2-7-dev</pre><p>If you don't find libopenjp2-7 you can download it with the follwing commands if you're running a Debian derived distribution:</p>
+<pre>wget <a href="http://ftp.de.debian.org/debian/pool/main/o/openjpeg2/libopenjp2-7_2.1.0-2_i386.deb">http://ftp.de.debian.org/debian/pool/main/o/openjpeg2/libopenjp2-7_2.1.0-2_i386.deb</a></pre> <pre>wget <a href="http://ftp.de.debian.org/debian/pool/main/o/openjpeg2/libopenjp2-7-dev_2.1.0-2_i386.deb">http://ftp.de.debian.org/debian/pool/main/o/openjpeg2/libopenjp2-7-dev_2.1.0-2_i386.deb</a></pre><p> or </p><pre>wget <a href="http://ftp.de.debian.org/debian/pool/main/o/openjpeg2/libop [...]
+<p>For specific instructions on installation on different distributions: have a look at the FAQ html <a href="http://users.telenet.be/on4qz/qsstv_9/faq.html">http://users.telenet.be/on4qz/qsstv_9/faq.html</a></p>
+<h1><a class="anchor" id="step2"></a>
+Step 2: Getting the software</h1>
+<p>The latest versions of QSSTV is always available at <a href="http://users.telenet.be/on4qz">http://users.telenet.be/on4qz</a> Download the latest tar file to a local directory (e.g. ~/Downloads)</p>
+<h1><a class="anchor" id="step3"></a>
+Step 3: Compile and Install the software</h1>
+<p>Go to the directory you have chosen and extract the tar file. Note: replace the 9.1.1 with the appropriate version you have downloaded </p><pre>
+>cd ~/Downloads
+>tar -xvzf qsstv_9.1.1.tar.gz
+>cd qsstv_9.1.1
+>qmake
+>make
+>sudo make install
+</pre> <h1><a class="anchor" id="step4"></a>
+Step 4: Run QSSTV</h1>
+<p>You can now run the program by typing qsstv at the prompt of a terminal session, or make a short cut on your desktop. </p><pre>>qsstv</pre><p> If you have problems compiling the software, please give as much information as possible but at least:</p><ul>
+<li>Linux Distribution (e.g. Ubuntu 12.10)</li>
+<li>QT Version (e.g Qt 5.4.1)</li>
+<li>Dump of the compile process showing the error </li>
+</ul>
+</div></div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="index.html">QSSTV 9.1</a></li>
+    <li class="footer">Generated on Sat Apr 16 2016 17:32:52 for QSSTV by
+    <a href="http://www.doxygen.org/index.html">
+    <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.9.1 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/qsstv/documentation/manual/manual/jquery.js b/qsstv/documentation/manual/manual/jquery.js
new file mode 100644
index 0000000..d52a1c7
--- /dev/null
+++ b/qsstv/documentation/manual/manual/jquery.js
@@ -0,0 +1,68 @@
+/*
+ * jQuery JavaScript Library v1.7.1
+ * http://jquery.com/
+ *
+ * Copyright 2011, John Resig
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ * Copyright 2011, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ *
+ * Date: Mon Nov 21 21:11:03 2011 -0500
+ */
+(function(bb,L){var av=bb.document,bu=bb.navigator,bl=bb.location;var b=(function(){var bF=function(b0,b1){return new bF.fn.init(b0,b1,bD)},bU=bb.jQuery,bH=bb.$,bD,bY=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,bM=/\S/,bI=/^\s+/,bE=/\s+$/,bA=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,bN=/^[\],:{}\s]*$/,bW=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,bP=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,bJ=/(?:^|:|,)(?:\s*\[)+/g,by=/(webkit)[ \/]([\w.]+)/,bR=/(opera)(?:.*version)?[ \/]([\w.]+)/ [...]
+/*
+ * Sizzle CSS Selector Engine
+ *  Copyright 2011, The Dojo Foundation
+ *  Released under the MIT, BSD, and GPL Licenses.
+ *  More information: http://sizzlejs.com/
+ */
+(function(){var bH=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,bC="sizcache"+(Math.random()+"").replace(".",""),bI=0,bL=Object.prototype.toString,bB=false,bA=true,bK=/\\/g,bO=/\r\n/g,bQ=/\W/;[0,0].sort(function(){bA=false;return 0});var by=function(bV,e,bY,bZ){bY=bY||[];e=e||av;var b1=e;if(e.nodeType!==1&&e.nodeType!==9){return[]}if(!bV||typeof bV!=="string"){return bY}var bS,b3,b6,bR,b2,b5,b4,bX,bU [...]
+ * jQuery UI 1.8.18
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI
+ */
+(function(a,d){a.ui=a.ui||{};if(a.ui.version){return}a.extend(a.ui,{version:"1.8.18",keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});a.fn.extend({propAttr:a.fn [...]
+ * jQuery UI Widget 1.8.18
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Widget
+ */
+(function(b,d){if(b.cleanData){var c=b.cleanData;b.cleanData=function(f){for(var g=0,h;(h=f[g])!=null;g++){try{b(h).triggerHandler("remove")}catch(j){}}c(f)}}else{var a=b.fn.remove;b.fn.remove=function(e,f){return this.each(function(){if(!f){if(!e||b.filter(e,[this]).length){b("*",this).add([this]).each(function(){try{b(this).triggerHandler("remove")}catch(g){}})}}return a.call(b(this),e,f)})}}b.widget=function(f,h,e){var g=f.split(".")[0],j;f=f.split(".")[1];j=g+"-"+f;if(!e){e=h;h=b.Wid [...]
+ * jQuery UI Mouse 1.8.18
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Mouse
+ *
+ * Depends:
+ *	jquery.ui.widget.js
+ */
+(function(b,c){var a=false;b(document).mouseup(function(d){a=false});b.widget("ui.mouse",{options:{cancel:":input,option",distance:1,delay:0},_mouseInit:function(){var d=this;this.element.bind("mousedown."+this.widgetName,function(e){return d._mouseDown(e)}).bind("click."+this.widgetName,function(e){if(true===b.data(e.target,d.widgetName+".preventClickEvent")){b.removeData(e.target,d.widgetName+".preventClickEvent");e.stopImmediatePropagation();return false}});this.started=false},_mouseD [...]
+ * jQuery hashchange event - v1.3 - 7/21/2010
+ * http://benalman.com/projects/jquery-hashchange-plugin/
+ * 
+ * Copyright (c) 2010 "Cowboy" Ben Alman
+ * Dual licensed under the MIT and GPL licenses.
+ * http://benalman.com/about/license/
+ */
+(function($,e,b){var c="hashchange",h=document,f,g=$.event.special,i=h.documentMode,d="on"+c in e&&(i===b||i>7);function a(j){j=j||location.href;return"#"+j.replace(/^[^#]*#?(.*)$/,"$1")}$.fn[c]=function(j){return j?this.bind(c,j):this.trigger(c)};$.fn[c].delay=50;g[c]=$.extend(g[c],{setup:function(){if(d){return false}$(f.start)},teardown:function(){if(d){return false}$(f.stop)}});f=(function(){var j={},p,m=a(),k=function(q){return q},l=k,o=k;j.start=function(){p||n()};j.stop=function() [...]
+ PowerTip - v1.2.0 - 2013-04-03
+ http://stevenbenner.github.com/jquery-powertip/
+ Copyright (c) 2013 Steven Benner (http://stevenbenner.com/).
+ Released under MIT license.
+ https://raw.github.com/stevenbenner/jquery-powertip/master/LICENSE.txt
+*/
+(function(a){if(typeof define==="function"&&define.amd){define(["jquery"],a)}else{a(jQuery)}}(function(k){var A=k(document),s=k(window),w=k("body");var n="displayController",e="hasActiveHover",d="forcedOpen",u="hasMouseMove",f="mouseOnToPopup",g="originalTitle",y="powertip",o="powertipjq",l="powertiptarget",E=180/Math.PI;var c={isTipOpen:false,isFixedTipOpen:false,isClosing:false,tipOpenImminent:false,activeHover:null,currentX:0,currentY:0,previousX:0,previousY:0,desyncTimeout:null,mouse [...]
\ No newline at end of file
diff --git a/qsstv/documentation/manual/manual/line.png b/qsstv/documentation/manual/manual/line.png
new file mode 100644
index 0000000..3b1dddd
Binary files /dev/null and b/qsstv/documentation/manual/manual/line.png differ
diff --git a/qsstv/documentation/manual/manual/multiline.png b/qsstv/documentation/manual/manual/multiline.png
new file mode 100644
index 0000000..f6f79ca
Binary files /dev/null and b/qsstv/documentation/manual/manual/multiline.png differ
diff --git a/qsstv/documentation/manual/manual/nav_f.png b/qsstv/documentation/manual/manual/nav_f.png
new file mode 100644
index 0000000..72a58a5
Binary files /dev/null and b/qsstv/documentation/manual/manual/nav_f.png differ
diff --git a/qsstv/documentation/manual/manual/nav_g.png b/qsstv/documentation/manual/manual/nav_g.png
new file mode 100644
index 0000000..2093a23
Binary files /dev/null and b/qsstv/documentation/manual/manual/nav_g.png differ
diff --git a/qsstv/documentation/manual/manual/nav_h.png b/qsstv/documentation/manual/manual/nav_h.png
new file mode 100644
index 0000000..33389b1
Binary files /dev/null and b/qsstv/documentation/manual/manual/nav_h.png differ
diff --git a/qsstv/documentation/manual/manual/navtree.css b/qsstv/documentation/manual/manual/navtree.css
new file mode 100644
index 0000000..1a868b3
--- /dev/null
+++ b/qsstv/documentation/manual/manual/navtree.css
@@ -0,0 +1,143 @@
+#nav-tree .children_ul {
+  margin:0;
+  padding:4px;
+}
+
+#nav-tree ul {
+  list-style:none outside none;
+  margin:0px;
+  padding:0px;
+}
+
+#nav-tree li {
+  white-space:nowrap;
+  margin:0px;
+  padding:0px;
+}
+
+#nav-tree .plus {
+  margin:0px;
+}
+
+#nav-tree .selected {
+  background-image: url('tab_a.png');
+  background-repeat:repeat-x;
+  color: #fff;
+  text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0);
+}
+
+#nav-tree img {
+  margin:0px;
+  padding:0px;
+  border:0px;
+  vertical-align: middle;
+}
+
+#nav-tree a {
+  text-decoration:none;
+  padding:0px;
+  margin:0px;
+  outline:none;
+}
+
+#nav-tree .label {
+  margin:0px;
+  padding:0px;
+  font: 12px 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif;
+}
+
+#nav-tree .label a {
+  padding:2px;
+}
+
+#nav-tree .selected a {
+  text-decoration:none;
+  color:#fff;
+}
+
+#nav-tree .children_ul {
+  margin:0px;
+  padding:0px;
+}
+
+#nav-tree .item {
+  margin:0px;
+  padding:0px;
+}
+
+#nav-tree {
+  padding: 0px 0px;
+  background-color: #FAFAFF; 
+  font-size:14px;
+  overflow:auto;
+}
+
+#doc-content {
+  overflow:auto;
+  display:block;
+  padding:0px;
+  margin:0px;
+  -webkit-overflow-scrolling : touch; /* iOS 5+ */
+}
+
+#side-nav {
+  padding:0 6px 0 0;
+  margin: 0px;
+  display:block;
+  position: absolute;
+  left: 0px;
+  width: 250px;
+}
+
+.ui-resizable .ui-resizable-handle {
+  display:block;
+}
+
+.ui-resizable-e {
+  background:url("splitbar.png") repeat scroll right center transparent;
+  cursor:e-resize;
+  height:100%;
+  right:0;
+  top:0;
+  width:6px;
+}
+
+.ui-resizable-handle {
+  display:none;
+  font-size:0.1px;
+  position:absolute;
+  z-index:1;
+}
+
+#nav-tree-contents {
+  margin: 6px 0px 0px 0px;
+}
+
+#nav-tree {
+  background-image:url('nav_h.png');
+  background-repeat:repeat-x;
+  background-color: #F9FAFC;
+  -webkit-overflow-scrolling : touch; /* iOS 5+ */
+}
+
+#nav-sync {
+  position:absolute;
+  top:5px;
+  right:24px;
+  z-index:0;
+}
+
+#nav-sync img {
+  opacity:0.3;
+}
+
+#nav-sync img:hover {
+  opacity:0.9;
+}
+
+ at media print
+{
+  #nav-tree { display: none; }
+  div.ui-resizable-handle { display: none; position: relative; }
+}
+
diff --git a/qsstv/documentation/manual/manual/navtree.js b/qsstv/documentation/manual/manual/navtree.js
new file mode 100644
index 0000000..9df45a7
--- /dev/null
+++ b/qsstv/documentation/manual/manual/navtree.js
@@ -0,0 +1,523 @@
+var navTreeSubIndices = new Array();
+
+function getData(varName)
+{
+  var i = varName.lastIndexOf('/');
+  var n = i>=0 ? varName.substring(i+1) : varName;
+  return eval(n.replace(/\-/g,'_'));
+}
+
+function stripPath(uri)
+{
+  return uri.substring(uri.lastIndexOf('/')+1);
+}
+
+function stripPath2(uri)
+{
+  var i = uri.lastIndexOf('/');
+  var s = uri.substring(i+1);
+  var m = uri.substring(0,i+1).match(/\/d\w\/d\w\w\/$/);
+  return m ? uri.substring(i-6) : s;
+}
+
+function hashValue()
+{
+  return $(location).attr('hash').substring(1).replace(/[^\w\-]/g,'');
+}
+
+function hashUrl()
+{
+  return '#'+hashValue();
+}
+
+function pathName()
+{
+  return $(location).attr('pathname').replace(/[^-A-Za-z0-9+&@#/%?=~_|!:,.;\(\)]/g, '');
+}
+
+function localStorageSupported()
+{
+  try {
+    return 'localStorage' in window && window['localStorage'] !== null && window.localStorage.getItem;
+  }
+  catch(e) {
+    return false;
+  }
+}
+
+
+function storeLink(link)
+{
+  if (!$("#nav-sync").hasClass('sync') && localStorageSupported()) {
+      window.localStorage.setItem('navpath',link);
+  }
+}
+
+function deleteLink()
+{
+  if (localStorageSupported()) {
+    window.localStorage.setItem('navpath','');
+  }
+}
+
+function cachedLink()
+{
+  if (localStorageSupported()) {
+    return window.localStorage.getItem('navpath');
+  } else {
+    return '';
+  }
+}
+
+function getScript(scriptName,func,show)
+{
+  var head = document.getElementsByTagName("head")[0]; 
+  var script = document.createElement('script');
+  script.id = scriptName;
+  script.type = 'text/javascript';
+  script.onload = func; 
+  script.src = scriptName+'.js'; 
+  if ($.browser.msie && $.browser.version<=8) { 
+    // script.onload does not work with older versions of IE
+    script.onreadystatechange = function() {
+      if (script.readyState=='complete' || script.readyState=='loaded') { 
+        func(); if (show) showRoot(); 
+      }
+    }
+  }
+  head.appendChild(script); 
+}
+
+function createIndent(o,domNode,node,level)
+{
+  var level=-1;
+  var n = node;
+  while (n.parentNode) { level++; n=n.parentNode; }
+  if (node.childrenData) {
+    var imgNode = document.createElement("img");
+    imgNode.style.paddingLeft=(16*level).toString()+'px';
+    imgNode.width  = 16;
+    imgNode.height = 22;
+    imgNode.border = 0;
+    node.plus_img = imgNode;
+    node.expandToggle = document.createElement("a");
+    node.expandToggle.href = "javascript:void(0)";
+    node.expandToggle.onclick = function() {
+      if (node.expanded) {
+        $(node.getChildrenUL()).slideUp("fast");
+        node.plus_img.src = node.relpath+"arrowright.png";
+        node.expanded = false;
+      } else {
+        expandNode(o, node, false, false);
+      }
+    }
+    node.expandToggle.appendChild(imgNode);
+    domNode.appendChild(node.expandToggle);
+    imgNode.src = node.relpath+"arrowright.png";
+  } else {
+    var span = document.createElement("span");
+    span.style.display = 'inline-block';
+    span.style.width   = 16*(level+1)+'px';
+    span.style.height  = '22px';
+    span.innerHTML = ' ';
+    domNode.appendChild(span);
+  } 
+}
+
+var animationInProgress = false;
+
+function gotoAnchor(anchor,aname,updateLocation)
+{
+  var pos, docContent = $('#doc-content');
+  var ancParent = $(anchor.parent());
+  if (ancParent.hasClass('memItemLeft') ||
+      ancParent.hasClass('fieldname') ||
+      ancParent.hasClass('fieldtype') ||
+      ancParent.is(':header'))
+  {
+    pos = ancParent.position().top;
+  } else if (anchor.position()) {
+    pos = anchor.position().top;
+  }
+  if (pos) {
+    var dist = Math.abs(Math.min(
+               pos-docContent.offset().top,
+               docContent[0].scrollHeight-
+               docContent.height()-docContent.scrollTop()));
+    animationInProgress=true;
+    docContent.animate({
+      scrollTop: pos + docContent.scrollTop() - docContent.offset().top
+    },Math.max(50,Math.min(500,dist)),function(){
+      if (updateLocation) window.location.href=aname;
+      animationInProgress=false;
+    });
+  }
+}
+
+function newNode(o, po, text, link, childrenData, lastNode)
+{
+  var node = new Object();
+  node.children = Array();
+  node.childrenData = childrenData;
+  node.depth = po.depth + 1;
+  node.relpath = po.relpath;
+  node.isLast = lastNode;
+
+  node.li = document.createElement("li");
+  po.getChildrenUL().appendChild(node.li);
+  node.parentNode = po;
+
+  node.itemDiv = document.createElement("div");
+  node.itemDiv.className = "item";
+
+  node.labelSpan = document.createElement("span");
+  node.labelSpan.className = "label";
+
+  createIndent(o,node.itemDiv,node,0);
+  node.itemDiv.appendChild(node.labelSpan);
+  node.li.appendChild(node.itemDiv);
+
+  var a = document.createElement("a");
+  node.labelSpan.appendChild(a);
+  node.label = document.createTextNode(text);
+  node.expanded = false;
+  a.appendChild(node.label);
+  if (link) {
+    var url;
+    if (link.substring(0,1)=='^') {
+      url = link.substring(1);
+      link = url;
+    } else {
+      url = node.relpath+link;
+    }
+    a.className = stripPath(link.replace('#',':'));
+    if (link.indexOf('#')!=-1) {
+      var aname = '#'+link.split('#')[1];
+      var srcPage = stripPath(pathName());
+      var targetPage = stripPath(link.split('#')[0]);
+      a.href = srcPage!=targetPage ? url : "javascript:void(0)"; 
+      a.onclick = function(){
+        storeLink(link);
+        if (!$(a).parent().parent().hasClass('selected'))
+        {
+          $('.item').removeClass('selected');
+          $('.item').removeAttr('id');
+          $(a).parent().parent().addClass('selected');
+          $(a).parent().parent().attr('id','selected');
+        }
+        var anchor = $(aname);
+        gotoAnchor(anchor,aname,true);
+      };
+    } else {
+      a.href = url;
+      a.onclick = function() { storeLink(link); }
+    }
+  } else {
+    if (childrenData != null) 
+    {
+      a.className = "nolink";
+      a.href = "javascript:void(0)";
+      a.onclick = node.expandToggle.onclick;
+    }
+  }
+
+  node.childrenUL = null;
+  node.getChildrenUL = function() {
+    if (!node.childrenUL) {
+      node.childrenUL = document.createElement("ul");
+      node.childrenUL.className = "children_ul";
+      node.childrenUL.style.display = "none";
+      node.li.appendChild(node.childrenUL);
+    }
+    return node.childrenUL;
+  };
+
+  return node;
+}
+
+function showRoot()
+{
+  var headerHeight = $("#top").height();
+  var footerHeight = $("#nav-path").height();
+  var windowHeight = $(window).height() - headerHeight - footerHeight;
+  (function (){ // retry until we can scroll to the selected item
+    try {
+      var navtree=$('#nav-tree');
+      navtree.scrollTo('#selected',0,{offset:-windowHeight/2});
+    } catch (err) {
+      setTimeout(arguments.callee, 0);
+    }
+  })();
+}
+
+function expandNode(o, node, imm, showRoot)
+{
+  if (node.childrenData && !node.expanded) {
+    if (typeof(node.childrenData)==='string') {
+      var varName    = node.childrenData;
+      getScript(node.relpath+varName,function(){
+        node.childrenData = getData(varName);
+        expandNode(o, node, imm, showRoot);
+      }, showRoot);
+    } else {
+      if (!node.childrenVisited) {
+        getNode(o, node);
+      } if (imm || ($.browser.msie && $.browser.version>8)) { 
+        // somehow slideDown jumps to the start of tree for IE9 :-(
+        $(node.getChildrenUL()).show();
+      } else {
+        $(node.getChildrenUL()).slideDown("fast");
+      }
+      if (node.isLast) {
+        node.plus_img.src = node.relpath+"arrowdown.png";
+      } else {
+        node.plus_img.src = node.relpath+"arrowdown.png";
+      }
+      node.expanded = true;
+    }
+  }
+}
+
+function glowEffect(n,duration)
+{
+  n.addClass('glow').delay(duration).queue(function(next){
+    $(this).removeClass('glow');next();
+  });
+}
+
+function highlightAnchor()
+{
+  var aname = hashUrl();
+  var anchor = $(aname);
+  if (anchor.parent().attr('class')=='memItemLeft'){
+    var rows = $('.memberdecls tr[class$="'+hashValue()+'"]');
+    glowEffect(rows.children(),300); // member without details
+  } else if (anchor.parent().attr('class')=='fieldname'){
+    glowEffect(anchor.parent().parent(),1000); // enum value
+  } else if (anchor.parent().attr('class')=='fieldtype'){
+    glowEffect(anchor.parent().parent(),1000); // struct field
+  } else if (anchor.parent().is(":header")) {
+    glowEffect(anchor.parent(),1000); // section header
+  } else {
+    glowEffect(anchor.next(),1000); // normal member
+  }
+  gotoAnchor(anchor,aname,false);
+}
+
+function selectAndHighlight(hash,n)
+{
+  var a;
+  if (hash) {
+    var link=stripPath(pathName())+':'+hash.substring(1);
+    a=$('.item a[class$="'+link+'"]');
+  }
+  if (a && a.length) {
+    a.parent().parent().addClass('selected');
+    a.parent().parent().attr('id','selected');
+    highlightAnchor();
+  } else if (n) {
+    $(n.itemDiv).addClass('selected');
+    $(n.itemDiv).attr('id','selected');
+  }
+  if ($('#nav-tree-contents .item:first').hasClass('selected')) {
+    $('#nav-sync').css('top','30px');
+  } else {
+    $('#nav-sync').css('top','5px');
+  }
+  showRoot();
+}
+
+function showNode(o, node, index, hash)
+{
+  if (node && node.childrenData) {
+    if (typeof(node.childrenData)==='string') {
+      var varName    = node.childrenData;
+      getScript(node.relpath+varName,function(){
+        node.childrenData = getData(varName);
+        showNode(o,node,index,hash);
+      },true);
+    } else {
+      if (!node.childrenVisited) {
+        getNode(o, node);
+      }
+      $(node.getChildrenUL()).css({'display':'block'});
+      node.plus_img.src = node.relpath+"arrowdown.png";
+      node.expanded = true;
+      var n = node.children[o.breadcrumbs[index]];
+      if (index+1<o.breadcrumbs.length) {
+        showNode(o,n,index+1,hash);
+      } else {
+        if (typeof(n.childrenData)==='string') {
+          var varName = n.childrenData;
+          getScript(n.relpath+varName,function(){
+            n.childrenData = getData(varName);
+            node.expanded=false;
+            showNode(o,node,index,hash); // retry with child node expanded
+          },true);
+        } else {
+          var rootBase = stripPath(o.toroot.replace(/\..+$/, ''));
+          if (rootBase=="index" || rootBase=="pages" || rootBase=="search") {
+            expandNode(o, n, true, true);
+          }
+          selectAndHighlight(hash,n);
+        }
+      }
+    }
+  } else {
+    selectAndHighlight(hash);
+  }
+}
+
+function removeToInsertLater(element) {
+  var parentNode = element.parentNode;
+  var nextSibling = element.nextSibling;
+  parentNode.removeChild(element);
+  return function() {
+    if (nextSibling) {
+      parentNode.insertBefore(element, nextSibling);
+    } else {
+      parentNode.appendChild(element);
+    }
+  };
+}
+
+function getNode(o, po)
+{
+  var insertFunction = removeToInsertLater(po.li);
+  po.childrenVisited = true;
+  var l = po.childrenData.length-1;
+  for (var i in po.childrenData) {
+    var nodeData = po.childrenData[i];
+    po.children[i] = newNode(o, po, nodeData[0], nodeData[1], nodeData[2],
+      i==l);
+  }
+  insertFunction();
+}
+
+function gotoNode(o,subIndex,root,hash,relpath)
+{
+  var nti = navTreeSubIndices[subIndex][root+hash];
+  o.breadcrumbs = $.extend(true, [], nti ? nti : navTreeSubIndices[subIndex][root]);
+  if (!o.breadcrumbs && root!=NAVTREE[0][1]) { // fallback: show index
+    navTo(o,NAVTREE[0][1],"",relpath);
+    $('.item').removeClass('selected');
+    $('.item').removeAttr('id');
+  }
+  if (o.breadcrumbs) {
+    o.breadcrumbs.unshift(0); // add 0 for root node
+    showNode(o, o.node, 0, hash);
+  }
+}
+
+function navTo(o,root,hash,relpath)
+{
+  var link = cachedLink();
+  if (link) {
+    var parts = link.split('#');
+    root = parts[0];
+    if (parts.length>1) hash = '#'+parts[1].replace(/[^\w\-]/g,'');
+    else hash='';
+  }
+  if (hash.match(/^#l\d+$/)) {
+    var anchor=$('a[name='+hash.substring(1)+']');
+    glowEffect(anchor.parent(),1000); // line number
+    hash=''; // strip line number anchors
+  }
+  var url=root+hash;
+  var i=-1;
+  while (NAVTREEINDEX[i+1]<=url) i++;
+  if (i==-1) { i=0; root=NAVTREE[0][1]; } // fallback: show index
+  if (navTreeSubIndices[i]) {
+    gotoNode(o,i,root,hash,relpath)
+  } else {
+    getScript(relpath+'navtreeindex'+i,function(){
+      navTreeSubIndices[i] = eval('NAVTREEINDEX'+i);
+      if (navTreeSubIndices[i]) {
+        gotoNode(o,i,root,hash,relpath);
+      }
+    },true);
+  }
+}
+
+function showSyncOff(n,relpath)
+{
+    n.html('<img src="'+relpath+'sync_off.png" title="'+SYNCOFFMSG+'"/>');
+}
+
+function showSyncOn(n,relpath)
+{
+    n.html('<img src="'+relpath+'sync_on.png" title="'+SYNCONMSG+'"/>');
+}
+
+function toggleSyncButton(relpath)
+{
+  var navSync = $('#nav-sync');
+  if (navSync.hasClass('sync')) {
+    navSync.removeClass('sync');
+    showSyncOff(navSync,relpath);
+    storeLink(stripPath2(pathName())+hashUrl());
+  } else {
+    navSync.addClass('sync');
+    showSyncOn(navSync,relpath);
+    deleteLink();
+  }
+}
+
+function initNavTree(toroot,relpath)
+{
+  var o = new Object();
+  o.toroot = toroot;
+  o.node = new Object();
+  o.node.li = document.getElementById("nav-tree-contents");
+  o.node.childrenData = NAVTREE;
+  o.node.children = new Array();
+  o.node.childrenUL = document.createElement("ul");
+  o.node.getChildrenUL = function() { return o.node.childrenUL; };
+  o.node.li.appendChild(o.node.childrenUL);
+  o.node.depth = 0;
+  o.node.relpath = relpath;
+  o.node.expanded = false;
+  o.node.isLast = true;
+  o.node.plus_img = document.createElement("img");
+  o.node.plus_img.src = relpath+"arrowright.png";
+  o.node.plus_img.width = 16;
+  o.node.plus_img.height = 22;
+
+  if (localStorageSupported()) {
+    var navSync = $('#nav-sync');
+    if (cachedLink()) {
+      showSyncOff(navSync,relpath);
+      navSync.removeClass('sync');
+    } else {
+      showSyncOn(navSync,relpath);
+    }
+    navSync.click(function(){ toggleSyncButton(relpath); });
+  }
+
+  $(window).load(function(){
+    navTo(o,toroot,hashUrl(),relpath);
+    showRoot();
+  });
+
+  $(window).bind('hashchange', function(){
+     if (window.location.hash && window.location.hash.length>1){
+       var a;
+       if ($(location).attr('hash')){
+         var clslink=stripPath(pathName())+':'+hashValue();
+         a=$('.item a[class$="'+clslink.replace(/</g,'\\3c ')+'"]');
+       }
+       if (a==null || !$(a).parent().parent().hasClass('selected')){
+         $('.item').removeClass('selected');
+         $('.item').removeAttr('id');
+       }
+       var link=stripPath2(pathName());
+       navTo(o,link,hashUrl(),relpath);
+     } else if (!animationInProgress) {
+       $('#doc-content').scrollTop(0);
+       $('.item').removeClass('selected');
+       $('.item').removeAttr('id');
+       navTo(o,toroot,hashUrl(),relpath);
+     }
+  })
+}
+
diff --git a/qsstv/documentation/manual/manual/navtreedata.js b/qsstv/documentation/manual/manual/navtreedata.js
new file mode 100644
index 0000000..bdb7cbd
--- /dev/null
+++ b/qsstv/documentation/manual/manual/navtreedata.js
@@ -0,0 +1,14 @@
+var NAVTREE =
+[
+  [ "QSSTV", "index.html", [
+    [ "QSSTV 9.1", "index.html", "index" ]
+  ] ]
+];
+
+var NAVTREEINDEX =
+[
+"_copying.html"
+];
+
+var SYNCONMSG = 'click to disable panel synchronisation';
+var SYNCOFFMSG = 'click to enable panel synchronisation';
\ No newline at end of file
diff --git a/qsstv/documentation/manual/manual/navtreeindex0.js b/qsstv/documentation/manual/manual/navtreeindex0.js
new file mode 100644
index 0000000..0c3d587
--- /dev/null
+++ b/qsstv/documentation/manual/manual/navtreeindex0.js
@@ -0,0 +1,30 @@
+var NAVTREEINDEX0 =
+{
+"_copying.html":[0,17],
+"_r_x_d_r_m.html":[0,9],
+"_r_x_s_s_t_v.html":[0,7],
+"_t_x_d_r_m.html":[0,10],
+"_t_x_s_s_t_v.html":[0,8],
+"changelog.html":[0,2],
+"credits.html":[0,16],
+"editor.html":[0,13],
+"externalprog.html":[0,14],
+"fixdrm.html":[0,11],
+"gallery.html":[0,12],
+"gettingstarted.html":[0,4],
+"gettingstarted.html#calib":[0,4,1],
+"gettingstarted.html#config":[0,4,0],
+"imagepopup.html":[0,6],
+"index.html":[0],
+"index.html":[],
+"index.html#intro_sec":[0,0],
+"installation.html":[0,3],
+"installation.html#step1":[0,3,0],
+"installation.html#step2":[0,3,1],
+"installation.html#step3":[0,3,2],
+"installation.html#step4":[0,3,3],
+"pages.html":[],
+"statusbar.html":[0,5],
+"todo1.html":[0,15],
+"whatsnew.html":[0,1]
+};
diff --git a/qsstv/documentation/manual/manual/open.png b/qsstv/documentation/manual/manual/open.png
new file mode 100644
index 0000000..30f75c7
Binary files /dev/null and b/qsstv/documentation/manual/manual/open.png differ
diff --git a/qsstv/documentation/manual/manual/pages.html b/qsstv/documentation/manual/manual/pages.html
new file mode 100644
index 0000000..f8950cb
--- /dev/null
+++ b/qsstv/documentation/manual/manual/pages.html
@@ -0,0 +1,79 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.9.1"/>
+<title>QSSTV: Related Pages</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<script type="text/javascript">
+  $(document).ready(initResizable);
+  $(window).load(resizeHeight);
+</script>
+<link href="qsstv.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+  <td style="padding-left: 0.5em;">
+   <div id="projectname">QSSTV
+    <span id="projectnumber">9.1</span>
+   </div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.9.1 -->
+  <div id="navrow1" class="tabs">
+    <ul class="tablist">
+      <li><a href="index.html"><span>Main Page</span></a></li>
+      <li class="current"><a href="pages.html"><span>Related Pages</span></a></li>
+    </ul>
+  </div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+$(document).ready(function(){initNavTree('pages.html','');});
+</script>
+<div id="doc-content">
+<div class="header">
+  <div class="headertitle">
+<div class="title">Related Pages</div>  </div>
+</div><!--header-->
+<div class="contents">
+<div class="textblock">Here is a list of all related documentation pages:</div><div class="directory">
+<table class="directory">
+</table>
+</div><!-- directory -->
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="footer">Generated on Sat Apr 16 2016 17:32:52 for QSSTV by
+    <a href="http://www.doxygen.org/index.html">
+    <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.9.1 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/qsstv/documentation/manual/manual/qsstv.css b/qsstv/documentation/manual/manual/qsstv.css
new file mode 100644
index 0000000..d7d0e12
--- /dev/null
+++ b/qsstv/documentation/manual/manual/qsstv.css
@@ -0,0 +1,835 @@
+/* The standard CSS for doxygen */
+
+body, table, div, p, dl {
+	font-family: Lucida Grande, Verdana, Geneva, Arial, sans-serif;
+	font-size: 12px;
+}
+
+/* @group Heading Levels */
+
+h1 {
+	font-size: 150%;
+}
+
+.title {
+	font-size: 150%;
+	font-weight: bold;
+	margin: 10px 2px;
+}
+
+h2 {
+	font-size: 120%;
+}
+
+h3 {
+	font-size: 100%;
+}
+
+dt {
+	font-weight: bold;
+}
+
+div.multicol {
+	-moz-column-gap: 1em;
+	-webkit-column-gap: 1em;
+	-moz-column-count: 3;
+	-webkit-column-count: 3;
+}
+
+p.startli, p.startdd, p.starttd {
+	margin-top: 2px;
+}
+
+p.endli {
+	margin-bottom: 0px;
+}
+
+p.enddd {
+	margin-bottom: 4px;
+}
+
+p.endtd {
+	margin-bottom: 2px;
+}
+
+/* @end */
+
+caption {
+	font-weight: bold;
+}
+
+span.legend {
+        font-size: 70%;
+        text-align: center;
+}
+
+h3.version {
+        font-size: 90%;
+        text-align: center;
+}
+
+div.qindex, div.navtab{
+	background-color: #EBEFF6;
+	border: 1px solid #A3B4D7;
+	text-align: center;
+	margin: 2px;
+	padding: 2px;
+}
+
+div.qindex, div.navpath {
+	width: 100%;
+	line-height: 140%;
+}
+
+div.navtab {
+	margin-right: 15px;
+}
+
+/* @group Link Styling */
+
+a {
+	color: #3D578C;
+	font-weight: normal;
+	text-decoration: none;
+}
+
+.contents a:visited {
+	color: #4665A2;
+}
+
+a:hover {
+	text-decoration: underline;
+}
+
+a.qindex {
+	font-weight: bold;
+}
+
+a.qindexHL {
+	font-weight: bold;
+	background-color: #9CAFD4;
+	color: #ffffff;
+	border: 1px double #869DCA;
+}
+
+.contents a.qindexHL:visited {
+        color: #ffffff;
+}
+
+a.el {
+	font-weight: bold;
+}
+
+a.elRef {
+}
+
+a.code {
+	color: #4665A2;
+}
+
+a.codeRef {
+	color: #4665A2;
+}
+
+/* @end */
+
+dl.el {
+	margin-left: -1cm;
+}
+
+.fragment {
+	font-family: monospace, fixed;
+	font-size: 105%;
+}
+
+pre.fragment {
+	border: 1px solid #C4CFE5;
+	background-color: #FBFCFD;
+	padding: 4px 6px;
+	margin: 4px 8px 4px 2px;
+	overflow: auto;
+	word-wrap: break-word;
+	font-size:  9pt;
+	line-height: 125%;
+}
+
+div.ah {
+	background-color: black;
+	font-weight: bold;
+	color: #ffffff;
+	margin-bottom: 3px;
+	margin-top: 3px;
+	padding: 0.2em;
+	border: solid thin #333;
+	border-radius: 0.5em;
+	-webkit-border-radius: .5em;
+	-moz-border-radius: .5em;
+	box-shadow: 2px 2px 3px #999;
+	-webkit-box-shadow: 2px 2px 3px #999;
+	-moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px;
+	background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444));
+	background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000);
+}
+
+div.groupHeader {
+	margin-left: 16px;
+	margin-top: 12px;
+	font-weight: bold;
+}
+
+div.groupText {
+	margin-left: 16px;
+	font-style: italic;
+}
+
+body {
+	background: white;
+	color: black;
+        margin: 0;
+}
+
+div.contents {
+	margin-top: 10px;
+	margin-left: 10px;
+	margin-right: 5px;
+}
+
+td.indexkey {
+	background-color: #EBEFF6;
+	font-weight: bold;
+	border: 1px solid #C4CFE5;
+	margin: 2px 0px 2px 0;
+	padding: 2px 10px;
+}
+
+td.indexvalue {
+	background-color: #EBEFF6;
+	border: 1px solid #C4CFE5;
+	padding: 2px 10px;
+	margin: 2px 0px;
+}
+
+tr.memlist {
+	background-color: #EEF1F7;
+}
+
+p.formulaDsp {
+	text-align: center;
+}
+
+img.formulaDsp {
+	
+}
+
+img.formulaInl {
+	vertical-align: middle;
+}
+
+div.center {
+	text-align: center;
+        margin-top: 0px;
+        margin-bottom: 0px;
+        padding: 0px;
+}
+
+div.center img {
+	border: 0px;
+}
+
+address.footer {
+	text-align: right;
+	padding-right: 12px;
+}
+
+img.footer {
+	border: 0px;
+	vertical-align: middle;
+}
+
+/* @group Code Colorization */
+
+span.keyword {
+	color: #008000
+}
+
+span.keywordtype {
+	color: #604020
+}
+
+span.keywordflow {
+	color: #e08000
+}
+
+span.comment {
+	color: #800000
+}
+
+span.preprocessor {
+	color: #806020
+}
+
+span.stringliteral {
+	color: #002080
+}
+
+span.charliteral {
+	color: #008080
+}
+
+span.vhdldigit { 
+	color: #ff00ff 
+}
+
+span.vhdlchar { 
+	color: #000000 
+}
+
+span.vhdlkeyword { 
+	color: #700070 
+}
+
+span.vhdllogic { 
+	color: #ff0000 
+}
+
+/* @end */
+
+/*
+.search {
+	color: #003399;
+	font-weight: bold;
+}
+
+form.search {
+	margin-bottom: 0px;
+	margin-top: 0px;
+}
+
+input.search {
+	font-size: 75%;
+	color: #000080;
+	font-weight: normal;
+	background-color: #e8eef2;
+}
+*/
+
+td.tiny {
+	font-size: 75%;
+}
+
+.dirtab {
+	padding: 4px;
+	border-collapse: collapse;
+	border: 1px solid #A3B4D7;
+}
+
+th.dirtab {
+	background: #EBEFF6;
+	font-weight: bold;
+}
+
+hr {
+	height: 0px;
+	border: none;
+	border-top: 1px solid #4A6AAA;
+}
+
+hr.footer {
+	height: 1px;
+}
+
+/* @group Member Descriptions */
+
+table.memberdecls {
+	border-spacing: 0px;
+	padding: 0px;
+}
+
+.mdescLeft, .mdescRight,
+.memItemLeft, .memItemRight,
+.memTemplItemLeft, .memTemplItemRight, .memTemplParams {
+	background-color: #F9FAFC;
+	border: none;
+	margin: 4px;
+	padding: 1px 0 0 8px;
+}
+
+.mdescLeft, .mdescRight {
+	padding: 0px 8px 4px 8px;
+	color: #555;
+}
+
+.memItemLeft, .memItemRight, .memTemplParams {
+	border-top: 1px solid #C4CFE5;
+}
+
+.memItemLeft, .memTemplItemLeft {
+        white-space: nowrap;
+}
+
+.memItemRight {
+	width: 100%;
+}
+
+.memTemplParams {
+	color: #4665A2;
+        white-space: nowrap;
+}
+
+/* @end */
+
+/* @group Member Details */
+
+/* Styles for detailed member documentation */
+
+.memtemplate {
+	font-size: 80%;
+	color: #4665A2;
+	font-weight: normal;
+	margin-left: 9px;
+}
+
+.memnav {
+	background-color: #EBEFF6;
+	border: 1px solid #A3B4D7;
+	text-align: center;
+	margin: 2px;
+	margin-right: 15px;
+	padding: 2px;
+}
+
+.mempage {
+	width: 100%;
+}
+
+.memitem {
+	padding: 0;
+	margin-bottom: 10px;
+	margin-right: 5px;
+}
+
+.memname {
+        white-space: nowrap;
+        font-weight: bold;
+        margin-left: 6px;
+}
+
+.memproto {
+        border-top: 1px solid #A8B8D9;
+        border-left: 1px solid #A8B8D9;
+        border-right: 1px solid #A8B8D9;
+        padding: 6px 0px 6px 0px;
+        color: #253555;
+        font-weight: bold;
+        text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);
+        /* opera specific markup */
+        box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+        border-top-right-radius: 8px;
+        border-top-left-radius: 8px;
+        /* firefox specific markup */
+        -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
+        -moz-border-radius-topright: 8px;
+        -moz-border-radius-topleft: 8px;
+        /* webkit specific markup */
+        -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+        -webkit-border-top-right-radius: 8px;
+        -webkit-border-top-left-radius: 8px;
+        background-image:url('nav_f.png');
+        background-repeat:repeat-x;
+        background-color: #E2E8F2;
+
+}
+
+.memdoc {
+        border-bottom: 1px solid #A8B8D9;      
+        border-left: 1px solid #A8B8D9;      
+        border-right: 1px solid #A8B8D9; 
+        padding: 2px 5px;
+        background-color: #FBFCFD;
+        border-top-width: 0;
+        /* opera specific markup */
+        border-bottom-left-radius: 8px;
+        border-bottom-right-radius: 8px;
+        box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+        /* firefox specific markup */
+        -moz-border-radius-bottomleft: 8px;
+        -moz-border-radius-bottomright: 8px;
+        -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
+        background-image: -moz-linear-gradient(center top, #FFFFFF 0%, #FFFFFF 60%, #F7F8FB 95%, #EEF1F7);
+        /* webkit specific markup */
+        -webkit-border-bottom-left-radius: 8px;
+        -webkit-border-bottom-right-radius: 8px;
+        -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+        background-image: -webkit-gradient(linear,center top,center bottom,from(#FFFFFF), color-stop(0.6,#FFFFFF), color-stop(0.60,#FFFFFF), color-stop(0.95,#F7F8FB), to(#EEF1F7));
+}
+
+.paramkey {
+	text-align: right;
+}
+
+.paramtype {
+	white-space: nowrap;
+}
+
+.paramname {
+	color: #602020;
+	white-space: nowrap;
+}
+.paramname em {
+	font-style: normal;
+}
+
+.params, .retval, .exception, .tparams {
+        border-spacing: 6px 2px;
+}       
+
+.params .paramname, .retval .paramname {
+        font-weight: bold;
+        vertical-align: top;
+}
+        
+.params .paramtype {
+        font-style: italic;
+        vertical-align: top;
+}       
+        
+.params .paramdir {
+        font-family: "courier new",courier,monospace;
+        vertical-align: top;
+}
+
+
+
+
+/* @end */
+
+/* @group Directory (tree) */
+
+/* for the tree view */
+
+.ftvtree {
+	font-family: sans-serif;
+	margin: 0px;
+}
+
+/* these are for tree view when used as main index */
+
+.directory {
+	font-size: 9pt;
+	font-weight: bold;
+	margin: 5px;
+}
+
+.directory h3 {
+	margin: 0px;
+	margin-top: 1em;
+	font-size: 11pt;
+}
+
+/*
+The following two styles can be used to replace the root node title
+with an image of your choice.  Simply uncomment the next two styles,
+specify the name of your image and be sure to set 'height' to the
+proper pixel height of your image.
+*/
+
+/*
+.directory h3.swap {
+	height: 61px;
+	background-repeat: no-repeat;
+	background-image: url("yourimage.gif");
+}
+.directory h3.swap span {
+	display: none;
+}
+*/
+
+.directory > h3 {
+	margin-top: 0;
+}
+
+.directory p {
+	margin: 0px;
+	white-space: nowrap;
+}
+
+.directory div {
+	display: none;
+	margin: 0px;
+}
+
+.directory img {
+	vertical-align: -30%;
+}
+
+/* these are for tree view when not used as main index */
+
+.directory-alt {
+	font-size: 100%;
+	font-weight: bold;
+}
+
+.directory-alt h3 {
+	margin: 0px;
+	margin-top: 1em;
+	font-size: 11pt;
+}
+
+.directory-alt > h3 {
+	margin-top: 0;
+}
+
+.directory-alt p {
+	margin: 0px;
+	white-space: nowrap;
+}
+
+.directory-alt div {
+	display: none;
+	margin: 0px;
+}
+
+.directory-alt img {
+	vertical-align: -30%;
+}
+
+/* @end */
+
+div.dynheader {
+        margin-top: 8px;
+}
+
+address {
+	font-style: normal;
+	color: #2A3D61;
+}
+
+table.doxtable {
+	border-collapse:collapse;
+}
+
+table.doxtable td, table.doxtable th {
+	border: 1px solid #2D4068;
+	padding: 3px 7px 2px;
+}
+
+table.doxtable th {
+	background-color: #374F7F;
+	color: #FFFFFF;
+	font-size: 110%;
+	padding-bottom: 4px;
+	padding-top: 5px;
+	text-align:left;
+}
+
+.tabsearch {
+	top: 0px;
+	left: 10px;
+	height: 36px;
+	background-image: url('tab_b.png');
+	z-index: 101;
+	overflow: hidden;
+	font-size: 13px;
+}
+
+.navpath ul
+{
+	font-size: 11px;
+	background-image:url('tab_b.png');
+	background-repeat:repeat-x;
+	height:30px;
+	line-height:30px;
+	color:#8AA0CC;
+	border:solid 1px #C2CDE4;
+	overflow:hidden;
+	margin:0px;
+	padding:0px;
+}
+
+.navpath li
+{
+	list-style-type:none;
+	float:left;
+	padding-left:10px;
+	padding-right:15px;
+	background-image:url('bc_s.png');
+	background-repeat:no-repeat;
+	background-position:right;
+	color:#364D7C;
+}
+
+.navpath li.navelem a
+{
+	height:32px;
+	display:block;
+	text-decoration: none;
+	outline: none;
+}
+
+.navpath li.navelem a:hover
+{
+	color:#6884BD;
+}
+
+.navpath li.footer
+{
+        list-style-type:none;
+        float:right;
+        padding-left:10px;
+        padding-right:15px;
+        background-image:none;
+        background-repeat:no-repeat;
+        background-position:right;
+        color:#364D7C;
+        font-size: 8pt;
+}
+
+
+div.summary
+{
+	float: right;
+	font-size: 8pt;
+	padding-right: 5px;
+	width: 50%;
+	text-align: right;
+}       
+
+div.summary a
+{
+	white-space: nowrap;
+}
+
+div.ingroups
+{
+	font-size: 8pt;
+	padding-left: 5px;
+	width: 50%;
+	text-align: left;
+}
+
+div.ingroups a
+{
+	white-space: nowrap;
+}
+
+div.header
+{
+        background-image:url('nav_h.png');
+        background-repeat:repeat-x;
+	background-color: #F9FAFC;
+	margin:  0px;
+	border-bottom: 1px solid #C4CFE5;
+}
+
+div.headertitle
+{
+	padding: 5px 5px 5px 10px;
+}
+
+dl
+{
+        padding: 0 0 0 10px;
+}
+
+dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug
+{
+        border-left:4px solid;
+        padding: 0 0 0 6px;
+}
+
+dl.note
+{
+        border-color: #D0C000;
+}
+
+dl.warning, dl.attention
+{
+        border-color: #FF0000;
+}
+
+dl.pre, dl.post, dl.invariant
+{
+        border-color: #00D000;
+}
+
+dl.deprecated
+{
+        border-color: #505050;
+}
+
+dl.todo
+{
+        border-color: #00C0E0;
+}
+
+dl.test
+{
+        border-color: #3030E0;
+}
+
+dl.bug
+{
+        border-color: #C08050;
+}
+
+#projectlogo
+{
+	text-align: center;
+	vertical-align: bottom;
+	border-collapse: separate;
+}
+ 
+#projectlogo img
+{ 
+	border: 0px none;
+}
+ 
+#projectname
+{
+	font: 300% Tahoma, Arial,sans-serif;
+	margin: 0px;
+	padding: 2px 0px;
+}
+    
+#projectbrief
+{
+	font: 120% Tahoma, Arial,sans-serif;
+	margin: 0px;
+	padding: 0px;
+}
+
+#projectnumber
+{
+	font: 50% Tahoma, Arial,sans-serif;
+	margin: 0px;
+	padding: 0px;
+}
+
+#titlearea
+{
+	padding: 0px;
+	margin: 0px;
+	width: 100%;
+	border-bottom: 1px solid #5373B4;
+}
+
+.image
+{
+        text-align: left;
+}
+
+.dotgraph
+{
+        text-align: center;
+}
+
+.mscgraph
+{
+        text-align: center;
+}
+
+.caption
+{
+	font-weight: bold;
+}
+
diff --git a/qsstv/documentation/manual/manual/receivedrm.png b/qsstv/documentation/manual/manual/receivedrm.png
new file mode 100644
index 0000000..7945ee2
Binary files /dev/null and b/qsstv/documentation/manual/manual/receivedrm.png differ
diff --git a/qsstv/documentation/manual/manual/refreshbutton.png b/qsstv/documentation/manual/manual/refreshbutton.png
new file mode 100644
index 0000000..85c0db8
Binary files /dev/null and b/qsstv/documentation/manual/manual/refreshbutton.png differ
diff --git a/qsstv/documentation/manual/manual/replay.png b/qsstv/documentation/manual/manual/replay.png
new file mode 100644
index 0000000..d8a386f
Binary files /dev/null and b/qsstv/documentation/manual/manual/replay.png differ
diff --git a/qsstv/documentation/manual/manual/resize.js b/qsstv/documentation/manual/manual/resize.js
new file mode 100644
index 0000000..304fcb6
--- /dev/null
+++ b/qsstv/documentation/manual/manual/resize.js
@@ -0,0 +1,97 @@
+var cookie_namespace = 'doxygen'; 
+var sidenav,navtree,content,header;
+
+function readCookie(cookie) 
+{
+  var myCookie = cookie_namespace+"_"+cookie+"=";
+  if (document.cookie) 
+  {
+    var index = document.cookie.indexOf(myCookie);
+    if (index != -1) 
+    {
+      var valStart = index + myCookie.length;
+      var valEnd = document.cookie.indexOf(";", valStart);
+      if (valEnd == -1) 
+      {
+        valEnd = document.cookie.length;
+      }
+      var val = document.cookie.substring(valStart, valEnd);
+      return val;
+    }
+  }
+  return 0;
+}
+
+function writeCookie(cookie, val, expiration) 
+{
+  if (val==undefined) return;
+  if (expiration == null) 
+  {
+    var date = new Date();
+    date.setTime(date.getTime()+(10*365*24*60*60*1000)); // default expiration is one week
+    expiration = date.toGMTString();
+  }
+  document.cookie = cookie_namespace + "_" + cookie + "=" + val + "; expires=" + expiration+"; path=/";
+}
+ 
+function resizeWidth() 
+{
+  var windowWidth = $(window).width() + "px";
+  var sidenavWidth = $(sidenav).outerWidth();
+  content.css({marginLeft:parseInt(sidenavWidth)+"px"}); 
+  writeCookie('width',sidenavWidth, null);
+}
+
+function restoreWidth(navWidth)
+{
+  var windowWidth = $(window).width() + "px";
+  content.css({marginLeft:parseInt(navWidth)+6+"px"});
+  sidenav.css({width:navWidth + "px"});
+}
+
+function resizeHeight() 
+{
+  var headerHeight = header.outerHeight();
+  var footerHeight = footer.outerHeight();
+  var windowHeight = $(window).height() - headerHeight - footerHeight;
+  content.css({height:windowHeight + "px"});
+  navtree.css({height:windowHeight + "px"});
+  sidenav.css({height:windowHeight + "px",top: headerHeight+"px"});
+}
+
+function initResizable()
+{
+  header  = $("#top");
+  sidenav = $("#side-nav");
+  content = $("#doc-content");
+  navtree = $("#nav-tree");
+  footer  = $("#nav-path");
+  $(".side-nav-resizable").resizable({resize: function(e, ui) { resizeWidth(); } });
+  $(window).resize(function() { resizeHeight(); });
+  var width = readCookie('width');
+  if (width) { restoreWidth(width); } else { resizeWidth(); }
+  resizeHeight();
+  var url = location.href;
+  var i=url.indexOf("#");
+  if (i>=0) window.location.hash=url.substr(i);
+  var _preventDefault = function(evt) { evt.preventDefault(); };
+  $("#splitbar").bind("dragstart", _preventDefault).bind("selectstart", _preventDefault);
+  $(document).bind('touchmove',function(e){
+    var device = navigator.userAgent.toLowerCase();
+    var ios = device.match(/(iphone|ipod|ipad)/);
+    if (ios) {
+      try {
+        var target = e.target;
+        while (target) {
+          if ($(target).css('-webkit-overflow-scrolling')=='touch') return;
+          target = target.parentNode;
+        }
+        e.preventDefault();
+      } catch(err) {
+        e.preventDefault();
+      }
+    }
+  });
+}
+
+
diff --git a/qsstv/documentation/manual/manual/rxdrm_constellation.png b/qsstv/documentation/manual/manual/rxdrm_constellation.png
new file mode 100644
index 0000000..9041cb7
Binary files /dev/null and b/qsstv/documentation/manual/manual/rxdrm_constellation.png differ
diff --git a/qsstv/documentation/manual/manual/rxdrm_segments.png b/qsstv/documentation/manual/manual/rxdrm_segments.png
new file mode 100644
index 0000000..8586a6b
Binary files /dev/null and b/qsstv/documentation/manual/manual/rxdrm_segments.png differ
diff --git a/qsstv/documentation/manual/manual/rxdrm_status.png b/qsstv/documentation/manual/manual/rxdrm_status.png
new file mode 100644
index 0000000..fd337bf
Binary files /dev/null and b/qsstv/documentation/manual/manual/rxdrm_status.png differ
diff --git a/qsstv/documentation/manual/manual/rxwidget1.png b/qsstv/documentation/manual/manual/rxwidget1.png
new file mode 100644
index 0000000..c276288
Binary files /dev/null and b/qsstv/documentation/manual/manual/rxwidget1.png differ
diff --git a/qsstv/documentation/manual/manual/splitbar.png b/qsstv/documentation/manual/manual/splitbar.png
new file mode 100644
index 0000000..fe895f2
Binary files /dev/null and b/qsstv/documentation/manual/manual/splitbar.png differ
diff --git a/qsstv/documentation/manual/manual/start.png b/qsstv/documentation/manual/manual/start.png
new file mode 100644
index 0000000..bc7336c
Binary files /dev/null and b/qsstv/documentation/manual/manual/start.png differ
diff --git a/qsstv/documentation/manual/manual/statusbar.html b/qsstv/documentation/manual/manual/statusbar.html
new file mode 100644
index 0000000..fd8209d
--- /dev/null
+++ b/qsstv/documentation/manual/manual/statusbar.html
@@ -0,0 +1,105 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.9.1"/>
+<title>QSSTV: Statusbar</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<script type="text/javascript">
+  $(document).ready(initResizable);
+  $(window).load(resizeHeight);
+</script>
+<link href="qsstv.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+  <td style="padding-left: 0.5em;">
+   <div id="projectname">QSSTV
+    <span id="projectnumber">9.1</span>
+   </div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.9.1 -->
+  <div id="navrow1" class="tabs">
+    <ul class="tablist">
+      <li><a href="index.html"><span>Main Page</span></a></li>
+      <li class="current"><a href="pages.html"><span>Related Pages</span></a></li>
+    </ul>
+  </div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+$(document).ready(function(){initNavTree('statusbar.html','');});
+</script>
+<div id="doc-content">
+<div class="header">
+  <div class="headertitle">
+<div class="title">Statusbar </div>  </div>
+</div><!--header-->
+<div class="contents">
+<div class="textblock"><div class="image">
+<img src="statusbar.png" alt="statusbar.png"/>
+</div>
+<ul>
+<li>Radio Frequency: the current frequency of the radio (only if CAT interface is enabled)</li>
+<li>Drop down menu to set the radio on the selected frequency (only if CAT interface is enabled) (see also <a class="el" href="gettingstarted.html#configFreq">configFreq</a> Config freq)</li>
+<li>WF Text: gives you a selection of user defined text you can send to appear as waterfall text. <br />
+<br />
+ <div class="image">
+<img src="wftextpopup.png" alt="wftextpopup.png"/>
+</div>
+ <br />
+ Send the text by clicking the tx button next to it<br />
+ The %m will be substituted by your callsign and the %s by the average SNR of the last received DRM stream. <br />
+<br />
+</li>
+<li>BSR: When a file is not completely received, you can ask for a retransmission. <div class="image">
+<img src="bsr_select.png" alt="bsr_select.png"/>
+</div>
+ By default the latest received file is selected (you can select another one through the drop-down box). <br />
+There are two modes: EasyPal and Compatible. EasyPal mode is more advanced and is normally used as EasyPal is the de facto standard on Windows and QSSTV also uses this mode in BSR reception. <br />
+Note: BSR is greyed out in SSTV. <br />
+<br />
+</li>
+<li>ID: send callsign in waterfall - this is a short-cut to send your own callsign in the waterfall <br />
+<br />
+</li>
+<li>PTT indicator: turns red while the PTT is activated. </li>
+</ul>
+</div></div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="index.html">QSSTV 9.1</a></li>
+    <li class="footer">Generated on Sat Apr 16 2016 17:32:52 for QSSTV by
+    <a href="http://www.doxygen.org/index.html">
+    <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.9.1 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/qsstv/documentation/manual/manual/statusbar.png b/qsstv/documentation/manual/manual/statusbar.png
new file mode 100644
index 0000000..3018aab
Binary files /dev/null and b/qsstv/documentation/manual/manual/statusbar.png differ
diff --git a/qsstv/documentation/manual/manual/statusleds.png b/qsstv/documentation/manual/manual/statusleds.png
new file mode 100644
index 0000000..36f8769
Binary files /dev/null and b/qsstv/documentation/manual/manual/statusleds.png differ
diff --git a/qsstv/documentation/manual/manual/stop.png b/qsstv/documentation/manual/manual/stop.png
new file mode 100644
index 0000000..2a7e1bf
Binary files /dev/null and b/qsstv/documentation/manual/manual/stop.png differ
diff --git a/qsstv/documentation/manual/manual/sweep.png b/qsstv/documentation/manual/manual/sweep.png
new file mode 100644
index 0000000..2ce104b
Binary files /dev/null and b/qsstv/documentation/manual/manual/sweep.png differ
diff --git a/qsstv/documentation/manual/manual/sync_off.png b/qsstv/documentation/manual/manual/sync_off.png
new file mode 100644
index 0000000..3b443fc
Binary files /dev/null and b/qsstv/documentation/manual/manual/sync_off.png differ
diff --git a/qsstv/documentation/manual/manual/sync_on.png b/qsstv/documentation/manual/manual/sync_on.png
new file mode 100644
index 0000000..e08320f
Binary files /dev/null and b/qsstv/documentation/manual/manual/sync_on.png differ
diff --git a/qsstv/documentation/manual/manual/tab_a.png b/qsstv/documentation/manual/manual/tab_a.png
new file mode 100644
index 0000000..3b725c4
Binary files /dev/null and b/qsstv/documentation/manual/manual/tab_a.png differ
diff --git a/qsstv/documentation/manual/manual/tab_b.png b/qsstv/documentation/manual/manual/tab_b.png
new file mode 100644
index 0000000..e2b4a86
Binary files /dev/null and b/qsstv/documentation/manual/manual/tab_b.png differ
diff --git a/qsstv/documentation/manual/manual/tab_h.png b/qsstv/documentation/manual/manual/tab_h.png
new file mode 100644
index 0000000..fd5cb70
Binary files /dev/null and b/qsstv/documentation/manual/manual/tab_h.png differ
diff --git a/qsstv/documentation/manual/manual/tab_s.png b/qsstv/documentation/manual/manual/tab_s.png
new file mode 100644
index 0000000..ab478c9
Binary files /dev/null and b/qsstv/documentation/manual/manual/tab_s.png differ
diff --git a/qsstv/documentation/manual/manual/tabs.css b/qsstv/documentation/manual/manual/tabs.css
new file mode 100644
index 0000000..9cf578f
--- /dev/null
+++ b/qsstv/documentation/manual/manual/tabs.css
@@ -0,0 +1,60 @@
+.tabs, .tabs2, .tabs3 {
+    background-image: url('tab_b.png');
+    width: 100%;
+    z-index: 101;
+    font-size: 13px;
+    font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif;
+}
+
+.tabs2 {
+    font-size: 10px;
+}
+.tabs3 {
+    font-size: 9px;
+}
+
+.tablist {
+    margin: 0;
+    padding: 0;
+    display: table;
+}
+
+.tablist li {
+    float: left;
+    display: table-cell;
+    background-image: url('tab_b.png');
+    line-height: 36px;
+    list-style: none;
+}
+
+.tablist a {
+    display: block;
+    padding: 0 20px;
+    font-weight: bold;
+    background-image:url('tab_s.png');
+    background-repeat:no-repeat;
+    background-position:right;
+    color: #283A5D;
+    text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);
+    text-decoration: none;
+    outline: none;
+}
+
+.tabs3 .tablist a {
+    padding: 0 10px;
+}
+
+.tablist a:hover {
+    background-image: url('tab_h.png');
+    background-repeat:repeat-x;
+    color: #fff;
+    text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0);
+    text-decoration: none;
+}
+
+.tablist li.current a {
+    background-image: url('tab_a.png');
+    background-repeat:repeat-x;
+    color: #fff;
+    text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0);
+}
diff --git a/qsstv/documentation/manual/manual/text.png b/qsstv/documentation/manual/manual/text.png
new file mode 100644
index 0000000..50af422
Binary files /dev/null and b/qsstv/documentation/manual/manual/text.png differ
diff --git a/qsstv/documentation/manual/manual/todo1.html b/qsstv/documentation/manual/manual/todo1.html
new file mode 100644
index 0000000..645cab5
--- /dev/null
+++ b/qsstv/documentation/manual/manual/todo1.html
@@ -0,0 +1,81 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.9.1"/>
+<title>QSSTV: To Do</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<script type="text/javascript">
+  $(document).ready(initResizable);
+  $(window).load(resizeHeight);
+</script>
+<link href="qsstv.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+  <td style="padding-left: 0.5em;">
+   <div id="projectname">QSSTV
+    <span id="projectnumber">9.1</span>
+   </div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.9.1 -->
+  <div id="navrow1" class="tabs">
+    <ul class="tablist">
+      <li><a href="index.html"><span>Main Page</span></a></li>
+      <li class="current"><a href="pages.html"><span>Related Pages</span></a></li>
+    </ul>
+  </div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+$(document).ready(function(){initNavTree('todo1.html','');});
+</script>
+<div id="doc-content">
+<div class="header">
+  <div class="headertitle">
+<div class="title">To Do </div>  </div>
+</div><!--header-->
+<div class="contents">
+<div class="textblock"><ul>
+<li>fax implementation and testing </li>
+<li>expand function in editor </li>
+<li>improve documentation </li>
+</ul>
+</div></div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="index.html">QSSTV 9.1</a></li>
+    <li class="footer">Generated on Sat Apr 16 2016 17:32:52 for QSSTV by
+    <a href="http://www.doxygen.org/index.html">
+    <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.9.1 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/qsstv/documentation/manual/manual/tone.png b/qsstv/documentation/manual/manual/tone.png
new file mode 100644
index 0000000..370775a
Binary files /dev/null and b/qsstv/documentation/manual/manual/tone.png differ
diff --git a/qsstv/documentation/manual/manual/transmitdrm.png b/qsstv/documentation/manual/manual/transmitdrm.png
new file mode 100644
index 0000000..e329d32
Binary files /dev/null and b/qsstv/documentation/manual/manual/transmitdrm.png differ
diff --git a/qsstv/documentation/manual/manual/txdrm_compression.png b/qsstv/documentation/manual/manual/txdrm_compression.png
new file mode 100644
index 0000000..55f1585
Binary files /dev/null and b/qsstv/documentation/manual/manual/txdrm_compression.png differ
diff --git a/qsstv/documentation/manual/manual/txdrm_options.png b/qsstv/documentation/manual/manual/txdrm_options.png
new file mode 100644
index 0000000..0b12bf2
Binary files /dev/null and b/qsstv/documentation/manual/manual/txdrm_options.png differ
diff --git a/qsstv/documentation/manual/manual/txdrm_status.png b/qsstv/documentation/manual/manual/txdrm_status.png
new file mode 100644
index 0000000..f9a69e8
Binary files /dev/null and b/qsstv/documentation/manual/manual/txdrm_status.png differ
diff --git a/qsstv/documentation/manual/manual/txwidget1.png b/qsstv/documentation/manual/manual/txwidget1.png
new file mode 100644
index 0000000..460a2d5
Binary files /dev/null and b/qsstv/documentation/manual/manual/txwidget1.png differ
diff --git a/qsstv/documentation/manual/manual/vk4aes.jpg b/qsstv/documentation/manual/manual/vk4aes.jpg
new file mode 100644
index 0000000..a18b81a
Binary files /dev/null and b/qsstv/documentation/manual/manual/vk4aes.jpg differ
diff --git a/qsstv/documentation/manual/manual/waterfall.png b/qsstv/documentation/manual/manual/waterfall.png
new file mode 100644
index 0000000..7564382
Binary files /dev/null and b/qsstv/documentation/manual/manual/waterfall.png differ
diff --git a/qsstv/documentation/manual/manual/wftextpopup.png b/qsstv/documentation/manual/manual/wftextpopup.png
new file mode 100644
index 0000000..7fb9b93
Binary files /dev/null and b/qsstv/documentation/manual/manual/wftextpopup.png differ
diff --git a/qsstv/documentation/manual/manual/whatsnew.html b/qsstv/documentation/manual/manual/whatsnew.html
new file mode 100644
index 0000000..4023a2b
--- /dev/null
+++ b/qsstv/documentation/manual/manual/whatsnew.html
@@ -0,0 +1,91 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.9.1"/>
+<title>QSSTV: What's New</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<script type="text/javascript">
+  $(document).ready(initResizable);
+  $(window).load(resizeHeight);
+</script>
+<link href="qsstv.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+  <td style="padding-left: 0.5em;">
+   <div id="projectname">QSSTV
+    <span id="projectnumber">9.1</span>
+   </div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.9.1 -->
+  <div id="navrow1" class="tabs">
+    <ul class="tablist">
+      <li><a href="index.html"><span>Main Page</span></a></li>
+      <li class="current"><a href="pages.html"><span>Related Pages</span></a></li>
+    </ul>
+  </div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+$(document).ready(function(){initNavTree('whatsnew.html','');});
+</script>
+<div id="doc-content">
+<div class="header">
+  <div class="headertitle">
+<div class="title">What's New </div>  </div>
+</div><!--header-->
+<div class="contents">
+<div class="textblock"><p>QSSTV 9.1.x has the following new features compared to QSSTV 8.2.x</p>
+<ul>
+<li>Build on top QT 5.x ( and also compatible with Qt 4.8)</li>
+<li>Better synchronization in SSTV mode</li>
+<li>New SSTV narrow band modes (MP73-N,MP110-N,MP140-N,MC110-N,MC140-N,MC180-N)</li>
+<li>Changed GUI layout</li>
+<li>Gallery window now shows all the rx/tx images.</li>
+<li>RX and TX images for SSTV and DRM now in separate gallery tab.</li>
+<li>TX Stock Images for fast selecting preferred TX Images.</li>
+<li>SSTV Images only saved after a configurable percentage completed</li>
+<li>Setting and reading frequency via CAT interface</li>
+<li>Preferred fast frequency selection for SSTV and DRM</li>
+<li>Editor/templates: multi-line inputs for x,y and z</li>
+<li>Pulse audio direct interface </li>
+</ul>
+</div></div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="index.html">QSSTV 9.1</a></li>
+    <li class="footer">Generated on Sat Apr 16 2016 17:32:52 for QSSTV by
+    <a href="http://www.doxygen.org/index.html">
+    <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.9.1 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/qsstv/documentation/manual/qsstv.css b/qsstv/documentation/manual/qsstv.css
new file mode 100644
index 0000000..d7d0e12
--- /dev/null
+++ b/qsstv/documentation/manual/qsstv.css
@@ -0,0 +1,835 @@
+/* The standard CSS for doxygen */
+
+body, table, div, p, dl {
+	font-family: Lucida Grande, Verdana, Geneva, Arial, sans-serif;
+	font-size: 12px;
+}
+
+/* @group Heading Levels */
+
+h1 {
+	font-size: 150%;
+}
+
+.title {
+	font-size: 150%;
+	font-weight: bold;
+	margin: 10px 2px;
+}
+
+h2 {
+	font-size: 120%;
+}
+
+h3 {
+	font-size: 100%;
+}
+
+dt {
+	font-weight: bold;
+}
+
+div.multicol {
+	-moz-column-gap: 1em;
+	-webkit-column-gap: 1em;
+	-moz-column-count: 3;
+	-webkit-column-count: 3;
+}
+
+p.startli, p.startdd, p.starttd {
+	margin-top: 2px;
+}
+
+p.endli {
+	margin-bottom: 0px;
+}
+
+p.enddd {
+	margin-bottom: 4px;
+}
+
+p.endtd {
+	margin-bottom: 2px;
+}
+
+/* @end */
+
+caption {
+	font-weight: bold;
+}
+
+span.legend {
+        font-size: 70%;
+        text-align: center;
+}
+
+h3.version {
+        font-size: 90%;
+        text-align: center;
+}
+
+div.qindex, div.navtab{
+	background-color: #EBEFF6;
+	border: 1px solid #A3B4D7;
+	text-align: center;
+	margin: 2px;
+	padding: 2px;
+}
+
+div.qindex, div.navpath {
+	width: 100%;
+	line-height: 140%;
+}
+
+div.navtab {
+	margin-right: 15px;
+}
+
+/* @group Link Styling */
+
+a {
+	color: #3D578C;
+	font-weight: normal;
+	text-decoration: none;
+}
+
+.contents a:visited {
+	color: #4665A2;
+}
+
+a:hover {
+	text-decoration: underline;
+}
+
+a.qindex {
+	font-weight: bold;
+}
+
+a.qindexHL {
+	font-weight: bold;
+	background-color: #9CAFD4;
+	color: #ffffff;
+	border: 1px double #869DCA;
+}
+
+.contents a.qindexHL:visited {
+        color: #ffffff;
+}
+
+a.el {
+	font-weight: bold;
+}
+
+a.elRef {
+}
+
+a.code {
+	color: #4665A2;
+}
+
+a.codeRef {
+	color: #4665A2;
+}
+
+/* @end */
+
+dl.el {
+	margin-left: -1cm;
+}
+
+.fragment {
+	font-family: monospace, fixed;
+	font-size: 105%;
+}
+
+pre.fragment {
+	border: 1px solid #C4CFE5;
+	background-color: #FBFCFD;
+	padding: 4px 6px;
+	margin: 4px 8px 4px 2px;
+	overflow: auto;
+	word-wrap: break-word;
+	font-size:  9pt;
+	line-height: 125%;
+}
+
+div.ah {
+	background-color: black;
+	font-weight: bold;
+	color: #ffffff;
+	margin-bottom: 3px;
+	margin-top: 3px;
+	padding: 0.2em;
+	border: solid thin #333;
+	border-radius: 0.5em;
+	-webkit-border-radius: .5em;
+	-moz-border-radius: .5em;
+	box-shadow: 2px 2px 3px #999;
+	-webkit-box-shadow: 2px 2px 3px #999;
+	-moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px;
+	background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444));
+	background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000);
+}
+
+div.groupHeader {
+	margin-left: 16px;
+	margin-top: 12px;
+	font-weight: bold;
+}
+
+div.groupText {
+	margin-left: 16px;
+	font-style: italic;
+}
+
+body {
+	background: white;
+	color: black;
+        margin: 0;
+}
+
+div.contents {
+	margin-top: 10px;
+	margin-left: 10px;
+	margin-right: 5px;
+}
+
+td.indexkey {
+	background-color: #EBEFF6;
+	font-weight: bold;
+	border: 1px solid #C4CFE5;
+	margin: 2px 0px 2px 0;
+	padding: 2px 10px;
+}
+
+td.indexvalue {
+	background-color: #EBEFF6;
+	border: 1px solid #C4CFE5;
+	padding: 2px 10px;
+	margin: 2px 0px;
+}
+
+tr.memlist {
+	background-color: #EEF1F7;
+}
+
+p.formulaDsp {
+	text-align: center;
+}
+
+img.formulaDsp {
+	
+}
+
+img.formulaInl {
+	vertical-align: middle;
+}
+
+div.center {
+	text-align: center;
+        margin-top: 0px;
+        margin-bottom: 0px;
+        padding: 0px;
+}
+
+div.center img {
+	border: 0px;
+}
+
+address.footer {
+	text-align: right;
+	padding-right: 12px;
+}
+
+img.footer {
+	border: 0px;
+	vertical-align: middle;
+}
+
+/* @group Code Colorization */
+
+span.keyword {
+	color: #008000
+}
+
+span.keywordtype {
+	color: #604020
+}
+
+span.keywordflow {
+	color: #e08000
+}
+
+span.comment {
+	color: #800000
+}
+
+span.preprocessor {
+	color: #806020
+}
+
+span.stringliteral {
+	color: #002080
+}
+
+span.charliteral {
+	color: #008080
+}
+
+span.vhdldigit { 
+	color: #ff00ff 
+}
+
+span.vhdlchar { 
+	color: #000000 
+}
+
+span.vhdlkeyword { 
+	color: #700070 
+}
+
+span.vhdllogic { 
+	color: #ff0000 
+}
+
+/* @end */
+
+/*
+.search {
+	color: #003399;
+	font-weight: bold;
+}
+
+form.search {
+	margin-bottom: 0px;
+	margin-top: 0px;
+}
+
+input.search {
+	font-size: 75%;
+	color: #000080;
+	font-weight: normal;
+	background-color: #e8eef2;
+}
+*/
+
+td.tiny {
+	font-size: 75%;
+}
+
+.dirtab {
+	padding: 4px;
+	border-collapse: collapse;
+	border: 1px solid #A3B4D7;
+}
+
+th.dirtab {
+	background: #EBEFF6;
+	font-weight: bold;
+}
+
+hr {
+	height: 0px;
+	border: none;
+	border-top: 1px solid #4A6AAA;
+}
+
+hr.footer {
+	height: 1px;
+}
+
+/* @group Member Descriptions */
+
+table.memberdecls {
+	border-spacing: 0px;
+	padding: 0px;
+}
+
+.mdescLeft, .mdescRight,
+.memItemLeft, .memItemRight,
+.memTemplItemLeft, .memTemplItemRight, .memTemplParams {
+	background-color: #F9FAFC;
+	border: none;
+	margin: 4px;
+	padding: 1px 0 0 8px;
+}
+
+.mdescLeft, .mdescRight {
+	padding: 0px 8px 4px 8px;
+	color: #555;
+}
+
+.memItemLeft, .memItemRight, .memTemplParams {
+	border-top: 1px solid #C4CFE5;
+}
+
+.memItemLeft, .memTemplItemLeft {
+        white-space: nowrap;
+}
+
+.memItemRight {
+	width: 100%;
+}
+
+.memTemplParams {
+	color: #4665A2;
+        white-space: nowrap;
+}
+
+/* @end */
+
+/* @group Member Details */
+
+/* Styles for detailed member documentation */
+
+.memtemplate {
+	font-size: 80%;
+	color: #4665A2;
+	font-weight: normal;
+	margin-left: 9px;
+}
+
+.memnav {
+	background-color: #EBEFF6;
+	border: 1px solid #A3B4D7;
+	text-align: center;
+	margin: 2px;
+	margin-right: 15px;
+	padding: 2px;
+}
+
+.mempage {
+	width: 100%;
+}
+
+.memitem {
+	padding: 0;
+	margin-bottom: 10px;
+	margin-right: 5px;
+}
+
+.memname {
+        white-space: nowrap;
+        font-weight: bold;
+        margin-left: 6px;
+}
+
+.memproto {
+        border-top: 1px solid #A8B8D9;
+        border-left: 1px solid #A8B8D9;
+        border-right: 1px solid #A8B8D9;
+        padding: 6px 0px 6px 0px;
+        color: #253555;
+        font-weight: bold;
+        text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);
+        /* opera specific markup */
+        box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+        border-top-right-radius: 8px;
+        border-top-left-radius: 8px;
+        /* firefox specific markup */
+        -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
+        -moz-border-radius-topright: 8px;
+        -moz-border-radius-topleft: 8px;
+        /* webkit specific markup */
+        -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+        -webkit-border-top-right-radius: 8px;
+        -webkit-border-top-left-radius: 8px;
+        background-image:url('nav_f.png');
+        background-repeat:repeat-x;
+        background-color: #E2E8F2;
+
+}
+
+.memdoc {
+        border-bottom: 1px solid #A8B8D9;      
+        border-left: 1px solid #A8B8D9;      
+        border-right: 1px solid #A8B8D9; 
+        padding: 2px 5px;
+        background-color: #FBFCFD;
+        border-top-width: 0;
+        /* opera specific markup */
+        border-bottom-left-radius: 8px;
+        border-bottom-right-radius: 8px;
+        box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+        /* firefox specific markup */
+        -moz-border-radius-bottomleft: 8px;
+        -moz-border-radius-bottomright: 8px;
+        -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
+        background-image: -moz-linear-gradient(center top, #FFFFFF 0%, #FFFFFF 60%, #F7F8FB 95%, #EEF1F7);
+        /* webkit specific markup */
+        -webkit-border-bottom-left-radius: 8px;
+        -webkit-border-bottom-right-radius: 8px;
+        -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+        background-image: -webkit-gradient(linear,center top,center bottom,from(#FFFFFF), color-stop(0.6,#FFFFFF), color-stop(0.60,#FFFFFF), color-stop(0.95,#F7F8FB), to(#EEF1F7));
+}
+
+.paramkey {
+	text-align: right;
+}
+
+.paramtype {
+	white-space: nowrap;
+}
+
+.paramname {
+	color: #602020;
+	white-space: nowrap;
+}
+.paramname em {
+	font-style: normal;
+}
+
+.params, .retval, .exception, .tparams {
+        border-spacing: 6px 2px;
+}       
+
+.params .paramname, .retval .paramname {
+        font-weight: bold;
+        vertical-align: top;
+}
+        
+.params .paramtype {
+        font-style: italic;
+        vertical-align: top;
+}       
+        
+.params .paramdir {
+        font-family: "courier new",courier,monospace;
+        vertical-align: top;
+}
+
+
+
+
+/* @end */
+
+/* @group Directory (tree) */
+
+/* for the tree view */
+
+.ftvtree {
+	font-family: sans-serif;
+	margin: 0px;
+}
+
+/* these are for tree view when used as main index */
+
+.directory {
+	font-size: 9pt;
+	font-weight: bold;
+	margin: 5px;
+}
+
+.directory h3 {
+	margin: 0px;
+	margin-top: 1em;
+	font-size: 11pt;
+}
+
+/*
+The following two styles can be used to replace the root node title
+with an image of your choice.  Simply uncomment the next two styles,
+specify the name of your image and be sure to set 'height' to the
+proper pixel height of your image.
+*/
+
+/*
+.directory h3.swap {
+	height: 61px;
+	background-repeat: no-repeat;
+	background-image: url("yourimage.gif");
+}
+.directory h3.swap span {
+	display: none;
+}
+*/
+
+.directory > h3 {
+	margin-top: 0;
+}
+
+.directory p {
+	margin: 0px;
+	white-space: nowrap;
+}
+
+.directory div {
+	display: none;
+	margin: 0px;
+}
+
+.directory img {
+	vertical-align: -30%;
+}
+
+/* these are for tree view when not used as main index */
+
+.directory-alt {
+	font-size: 100%;
+	font-weight: bold;
+}
+
+.directory-alt h3 {
+	margin: 0px;
+	margin-top: 1em;
+	font-size: 11pt;
+}
+
+.directory-alt > h3 {
+	margin-top: 0;
+}
+
+.directory-alt p {
+	margin: 0px;
+	white-space: nowrap;
+}
+
+.directory-alt div {
+	display: none;
+	margin: 0px;
+}
+
+.directory-alt img {
+	vertical-align: -30%;
+}
+
+/* @end */
+
+div.dynheader {
+        margin-top: 8px;
+}
+
+address {
+	font-style: normal;
+	color: #2A3D61;
+}
+
+table.doxtable {
+	border-collapse:collapse;
+}
+
+table.doxtable td, table.doxtable th {
+	border: 1px solid #2D4068;
+	padding: 3px 7px 2px;
+}
+
+table.doxtable th {
+	background-color: #374F7F;
+	color: #FFFFFF;
+	font-size: 110%;
+	padding-bottom: 4px;
+	padding-top: 5px;
+	text-align:left;
+}
+
+.tabsearch {
+	top: 0px;
+	left: 10px;
+	height: 36px;
+	background-image: url('tab_b.png');
+	z-index: 101;
+	overflow: hidden;
+	font-size: 13px;
+}
+
+.navpath ul
+{
+	font-size: 11px;
+	background-image:url('tab_b.png');
+	background-repeat:repeat-x;
+	height:30px;
+	line-height:30px;
+	color:#8AA0CC;
+	border:solid 1px #C2CDE4;
+	overflow:hidden;
+	margin:0px;
+	padding:0px;
+}
+
+.navpath li
+{
+	list-style-type:none;
+	float:left;
+	padding-left:10px;
+	padding-right:15px;
+	background-image:url('bc_s.png');
+	background-repeat:no-repeat;
+	background-position:right;
+	color:#364D7C;
+}
+
+.navpath li.navelem a
+{
+	height:32px;
+	display:block;
+	text-decoration: none;
+	outline: none;
+}
+
+.navpath li.navelem a:hover
+{
+	color:#6884BD;
+}
+
+.navpath li.footer
+{
+        list-style-type:none;
+        float:right;
+        padding-left:10px;
+        padding-right:15px;
+        background-image:none;
+        background-repeat:no-repeat;
+        background-position:right;
+        color:#364D7C;
+        font-size: 8pt;
+}
+
+
+div.summary
+{
+	float: right;
+	font-size: 8pt;
+	padding-right: 5px;
+	width: 50%;
+	text-align: right;
+}       
+
+div.summary a
+{
+	white-space: nowrap;
+}
+
+div.ingroups
+{
+	font-size: 8pt;
+	padding-left: 5px;
+	width: 50%;
+	text-align: left;
+}
+
+div.ingroups a
+{
+	white-space: nowrap;
+}
+
+div.header
+{
+        background-image:url('nav_h.png');
+        background-repeat:repeat-x;
+	background-color: #F9FAFC;
+	margin:  0px;
+	border-bottom: 1px solid #C4CFE5;
+}
+
+div.headertitle
+{
+	padding: 5px 5px 5px 10px;
+}
+
+dl
+{
+        padding: 0 0 0 10px;
+}
+
+dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug
+{
+        border-left:4px solid;
+        padding: 0 0 0 6px;
+}
+
+dl.note
+{
+        border-color: #D0C000;
+}
+
+dl.warning, dl.attention
+{
+        border-color: #FF0000;
+}
+
+dl.pre, dl.post, dl.invariant
+{
+        border-color: #00D000;
+}
+
+dl.deprecated
+{
+        border-color: #505050;
+}
+
+dl.todo
+{
+        border-color: #00C0E0;
+}
+
+dl.test
+{
+        border-color: #3030E0;
+}
+
+dl.bug
+{
+        border-color: #C08050;
+}
+
+#projectlogo
+{
+	text-align: center;
+	vertical-align: bottom;
+	border-collapse: separate;
+}
+ 
+#projectlogo img
+{ 
+	border: 0px none;
+}
+ 
+#projectname
+{
+	font: 300% Tahoma, Arial,sans-serif;
+	margin: 0px;
+	padding: 2px 0px;
+}
+    
+#projectbrief
+{
+	font: 120% Tahoma, Arial,sans-serif;
+	margin: 0px;
+	padding: 0px;
+}
+
+#projectnumber
+{
+	font: 50% Tahoma, Arial,sans-serif;
+	margin: 0px;
+	padding: 0px;
+}
+
+#titlearea
+{
+	padding: 0px;
+	margin: 0px;
+	width: 100%;
+	border-bottom: 1px solid #5373B4;
+}
+
+.image
+{
+        text-align: left;
+}
+
+.dotgraph
+{
+        text-align: center;
+}
+
+.mscgraph
+{
+        text-align: center;
+}
+
+.caption
+{
+	font-weight: bold;
+}
+
diff --git a/qsstv/drmprofileform.h b/qsstv/drmprofileform.h
deleted file mode 100644
index 0631e1b..0000000
--- a/qsstv/drmprofileform.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef DRMPROFILEFORM_H
-#define DRMPROFILEFORM_H
-#include "drmtx/drmtransmitter.h"
-
-#include <QWidget>
-
-#define NUMBEROFPROFILES 3
-
-struct sprofile
-{
-    QString name;
-    drmTxParams params;
-
-};
-
-namespace Ui {
-class drmProfileForm;
-}
-
-class drmProfileForm : public QWidget
-{
-    Q_OBJECT
-
-public:
-    explicit drmProfileForm(QWidget *parent = 0);
-    ~drmProfileForm();
-    void readSettings();
-    void writeSettings();
-    bool getDRMParams(int idx, drmTxParams &d);
-    bool getName(int idx,QString &n);
-    void setParams();
-
-private:
-    Ui::drmProfileForm *ui;
-    sprofile drmPFArray[NUMBEROFPROFILES];
-    void getParams();
-
-};
-
-#endif // DRMPROFILEFORM_H
diff --git a/qsstv/drmrx/channeldecode.cpp b/qsstv/drmrx/channeldecode.cpp
index d785557..f5715e5 100644
--- a/qsstv/drmrx/channeldecode.cpp
+++ b/qsstv/drmrx/channeldecode.cpp
@@ -24,23 +24,23 @@
 *    More details can be found in the accompanying file COPYING
 *************************************************************************/
 
-
+#include "appglobal.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/types.h>
 #include <math.h>
 #include <malloc.h>
 #include <float.h>
-#include "structtemplates.h"
 #include "drmproto.h"
 #include "drmdefs.h"
+#include "drm.h"
 #include <fftw3.h>
 #include "configparams.h"
 
 #define PI (4.0*atan(1.0))
 
 #define CHANNELDECODING 1
-char localDrmCallsign[9]= {0, 0, 0, 0, 0, 0, 0, 0, 0}; //changed joma
+char localDrmCallsign[9]= {0, 0, 0, 0, 0, 0, 0, 0, 0}; //changed ON4QZ
 
 #define MSD_ITER 4
 extern int transmission_frame_buffer_data_valid;
@@ -68,8 +68,8 @@ extern int audio_data_flag;
 extern int length_decoded_data;
 extern int MSC_Demapper[6][2959];
 
-int lMSC;  // joma
-float MSC_cells_sequence[2 * 2959]; //joma
+int lMSC;  //changed ON4QZ
+float MSC_cells_sequence[2 * 2959]; //changed ON4QZ
 bool MSCAvailable;
 int spectrum_occupancy_new;
 int msc_mode_new;
@@ -94,22 +94,15 @@ void channel_decoding(void)
   static int frame_count;
   static int msc_parameters_valid;
   static int robustness_mode_old;
-  //  static int sdc_mode;
   static int msc_mode;
   static int interleaver_depth;
-  //  static float z_SDC[2];
-
-
   static int MSC_Demapper_symbolwise[6][2959];
   static double SNR_estimation[2959];
   static double squared_noise_signal_buffer[121490];
   static double noise_power_density[461];
   static int SNR_estimation_valid;
-  //  int audio_service_index;
   int i, j, k, n;
-  //  int iterations;
   static int msc_parameters_changed;
-  //  static int sdc_parameters_changed;
   int symbol_period;
   int trxfrmbufptr;
   double received_real[3000], received_imag[3000], snr[3000];
@@ -121,13 +114,11 @@ void channel_decoding(void)
   static double fac_data[72];
   double checksum;
   static double channel_parameters[20];
-  //  static double service_parameters[44];
   double facblock[72];
   double temp;
   static int identity;
   static int identityCount;
   static int old_ptr;
-
   static int MSC_carrier_usage[288];
   static int cnt_MSC_used_carriers;
   static int MSC_used_carriers[288];
@@ -137,7 +128,6 @@ void channel_decoding(void)
   static int Deinterleaver[18000];
   int no_of_streams = 1;
   static int N_MUX;
-  //  static int rylcm;
   static int N1, N2;
   static int ratesA[3], ratesB[3], Lvspp, xin1, xin2;
   float sum1;
@@ -150,19 +140,14 @@ void channel_decoding(void)
   static double res_iters, calc_variance;
   static double noise_signal[2 * 2959];
   static double squared_noise_signal[2959];
-  //  static double calc_weighted_variance;
   double sum2;
   double weighted_noise_power_density[288];
-  //  double signal_to_noise_ratio[288];
-  //  static int cnt_npwrpos;
-  //  static int noise_power_positions[288];
   double samples_resorted[288][15];
   int posrow, poscolumn, totindex;
   int VSPPlength, HPPlength;
   int Tu_list[] = { Tu_A, Tu_B, Tu_C, Tu_D };
   double part1, part2;
 
-
   if (runstate == RUN_STATE_POWER_ON)
 
     {
@@ -181,11 +166,8 @@ void channel_decoding(void)
       frame_count = 0;
       msc_parameters_valid = 0;
       robustness_mode_old = -1;
-      //      sdc_mode = -1;
       msc_mode = -1;
       interleaver_depth = -1;
-      //      z_SDC[0] = 0.0;		/* complex */
-      //      z_SDC[1] = 1.0E-12;
       fac_valid = -1;
       multiplex_description.HM_length = 0;
       callsignValid=false;
@@ -340,15 +322,10 @@ void channel_decoding(void)
       if ((symbol_period != -1) & (symbols_per_frame != -1))
 
         {
-          transmission_frame_buffer_wptr =
-              (transmission_frame_buffer_wptr +
-               symbol_period * symbols_per_frame) % (symbol_period *
-                                                     symbols_per_frame * 6);
+          transmission_frame_buffer_wptr = (transmission_frame_buffer_wptr + symbol_period * symbols_per_frame) % (symbol_period * symbols_per_frame * 6);
 
         }
       SNR_estimation_valid = 0;
-
-
       return;
     }
   //  iterations = 0;
@@ -356,13 +333,11 @@ void channel_decoding(void)
   msc_parameters_changed = 0;
 
   if (robustness_mode != robustness_mode_old)
-
     {
       if (robustness_mode < 0)
         return;
       symbol_period = Tu_list[robustness_mode];
       lFAC = mkfacmap(robustness_mode, K_dc, K_modulo, FAC_cells_k);
-
     }
 
   /* FAC decoding */
@@ -371,97 +346,73 @@ void channel_decoding(void)
   for (i = 0; i < lFAC; i++)
 
     {
-      trxfrmbufptr =
-          (frame_index - 1) * symbol_period * symbols_per_frame +
-          FAC_cells_k[i];
+      trxfrmbufptr = (frame_index - 1) * symbol_period * symbols_per_frame + FAC_cells_k[i];
       received_real[i] = (double) transmission_frame_buffer[2 * trxfrmbufptr];
-      received_imag[i] =
-          (double) transmission_frame_buffer[2 * trxfrmbufptr + 1];
-      transfer_function_FAC[i * 2] =
-          channel_transfer_function_buffer[2 * trxfrmbufptr];
-      transfer_function_FAC[i * 2 + 1] =
-          channel_transfer_function_buffer[2 * trxfrmbufptr + 1];
-
-      snr[i] =
-          sqrt(transfer_function_FAC[i * 2] * transfer_function_FAC[i * 2] +
-               transfer_function_FAC[i * 2 + 1] * transfer_function_FAC[i * 2 +
-               1]);
+      received_imag[i] = (double) transmission_frame_buffer[2 * trxfrmbufptr + 1];
+      transfer_function_FAC[i * 2] = channel_transfer_function_buffer[2 * trxfrmbufptr];
+      transfer_function_FAC[i * 2 + 1] = channel_transfer_function_buffer[2 * trxfrmbufptr + 1];
+      snr[i] = sqrt(transfer_function_FAC[i * 2] * transfer_function_FAC[i * 2] +
+          transfer_function_FAC[i * 2 + 1] * transfer_function_FAC[i * 2 +1]);
 
-    } received_real[9] = 0.0;
+    }
+  received_real[9] = 0.0;
   received_imag[9] = 0.0;
   L_FAC[0] = 0.0;
   L_FAC[1] = 48.0;
   PL_FAC[0] = 0;
   PL_FAC[1] = 6;
-  (void) msdhardfac(received_real, received_imag, lFAC, snr, 0, L_FAC, 2, 0,
-                    FAC_Deinterleaver, PL_FAC, 4, 0, fac_data);
+  (void) msdhardfac(received_real, received_imag, lFAC, snr, 0, L_FAC, 2, 0, FAC_Deinterleaver, PL_FAC, 4, 0, fac_data);
 
   for (i = 0; i < 40; i++)
-
     {
       facblock[i] = fac_data[i];
     }
   for (i = 40; i < 48; i++)
-
-    {
+      {
       facblock[i] = 1.0 - fac_data[i];
     }
   for (i = 0; i < 10; i++)
-
-    {
+      {
       channel_parameters[i] = fac_data[i];
     }
 
   crc8_c(&checksum, facblock, 48);
 
   if (fabs(checksum) > DBL_EPSILON)
-
-    {
+     {
       spectrum_occupancy = -1;
       fac_valid = 0;
       identityCount=0;
-
       msc_parameters_valid = 0 ;  /* added pa0mbo 23 nov 2011 */
       return;
     }
   msc_parameters_valid = 1;
-
-  /* frame alignment */
+   /* frame alignment */
   temp = 2.0 * channel_parameters[0] + channel_parameters[1];
   identity = (int) temp % 3;
-
   if (identity != ((frame_index - 1) % 3))
-
-    {
+      {
       old_ptr = transmission_frame_buffer_wptr;
-      transmission_frame_buffer_wptr =
-          identity * symbol_period * symbols_per_frame;
+      transmission_frame_buffer_wptr = identity * symbol_period * symbols_per_frame;
       for (i = 0; i < symbol_period * symbols_per_frame; i++)
-
         {
           trxfrmbufptr = transmission_frame_buffer_wptr + i;
-          transmission_frame_buffer[2 * trxfrmbufptr] =
-              transmission_frame_buffer[2 * (old_ptr + i)];
-          transmission_frame_buffer[2 * trxfrmbufptr + 1] =
-              transmission_frame_buffer[2 * (old_ptr + i) + 1];
-          channel_transfer_function_buffer[2 * trxfrmbufptr] =
-              channel_transfer_function_buffer[2 * (old_ptr + i)];
-          channel_transfer_function_buffer[2 * trxfrmbufptr + 1] =
-              channel_transfer_function_buffer[2 * (old_ptr + i) + 1];
+          transmission_frame_buffer[2 * trxfrmbufptr] = transmission_frame_buffer[2 * (old_ptr + i)];
+          transmission_frame_buffer[2 * trxfrmbufptr + 1] =transmission_frame_buffer[2 * (old_ptr + i) + 1];
+          channel_transfer_function_buffer[2 * trxfrmbufptr] = channel_transfer_function_buffer[2 * (old_ptr + i)];
+          channel_transfer_function_buffer[2 * trxfrmbufptr + 1] =channel_transfer_function_buffer[2 * (old_ptr + i) + 1];
         }
       frame_index = identity + 1;
     }
   interleaver_depth_new = (int) channel_parameters[3];
   msc_mode_new = (int) channel_parameters[4];
   if (fabs(channel_parameters[6] - 1.0) < DBL_EPSILON)
-
     {
       msc_mode_new = msc_mode_new + 2 * (int) channel_parameters[9];
     }
   spectrum_occupancy_new = (int) channel_parameters[2];
   if (spectrum_occupancy_new > 1)
-
-    {
+   {
       spectrum_occupancy = -1;
       fac_valid = 0;
       identityCount=0;
@@ -472,56 +423,39 @@ void channel_decoding(void)
   // we need 3 consequetive valid fac's to have a complete call
 
   /* decoding of text in fac data */
-      localDrmCallsign[3*identity] = getfacchar(&facblock[10]);
-      localDrmCallsign[3*identity+1] = getfacchar(&facblock[17]);
-      localDrmCallsign[3*identity+2] = getfacchar(&facblock[24]);
-      localDrmCallsign[3*identity+3] = '\0';
-      if ((identity == 2) && (identityCount>=3))
-        {
-          identityCount=0;
-          drmCallsign=localDrmCallsign;
-          callsignValid=true;
-        }
-
-
-
-  if ((spectrum_occupancy != spectrum_occupancy_new)
-      || (robustness_mode_old != robustness_mode))
+  localDrmCallsign[3*identity]   = getfacchar(&facblock[10]);
+  localDrmCallsign[3*identity+1] = getfacchar(&facblock[17]);
+  localDrmCallsign[3*identity+2] = getfacchar(&facblock[24]);
+  localDrmCallsign[3*identity+3] = '\0';
+  if ((identity == 2) && (identityCount>=3))
+    {
+      identityCount=0;
+      drmCallsign=localDrmCallsign;
+      callsignValid=true;
+    }
 
+  if ((spectrum_occupancy != spectrum_occupancy_new) || (robustness_mode_old != robustness_mode))
     {
       spectrum_occupancy = spectrum_occupancy_new;
       interleaver_depth = interleaver_depth_new;
-
-
       lMSC = mkmscmap(robustness_mode, spectrum_occupancy, interleaver_depth, K_dc, K_modulo);
-
       for (j = 0; j < 6; j++)
-
         {
-
           for (i = 0; i < lMSC; i++)
-
             {
-              MSC_Demapper_symbolwise[j][i] =
-                  MSC_Demapper[j][i] % symbol_period;
-
-
+              MSC_Demapper_symbolwise[j][i] = MSC_Demapper[j][i] % symbol_period;
             }
         }
 
       /* do the binning and calc carrier usage */
       for (i = 0; i < symbol_period; i++)
-
         {
           MSC_carrier_usage[i] = 0;
           for (j = 0; j < 6; j++)
-
             {
               for (k = 0; k < lMSC; k++)
-
-                {
+               {
                   if (MSC_Demapper_symbolwise[j][k] == i)
-
                     {
                       (MSC_carrier_usage[i])++;
                     }
@@ -530,11 +464,9 @@ void channel_decoding(void)
         }
       cnt_MSC_used_carriers = 0;
       for (i = 0; i < symbol_period; i++)
-
         {
           if (MSC_carrier_usage[i] != 0)
-
-            {
+           {
               MSC_used_carriers[cnt_MSC_used_carriers++] = i;
             }
         }
@@ -546,27 +478,18 @@ void channel_decoding(void)
 
     {
       if (interleaver_depth != interleaver_depth_new)
-
         {
           interleaver_depth = interleaver_depth_new;
-
           lMSC = mkmscmap(robustness_mode, spectrum_occupancy, interleaver_depth,K_dc, K_modulo);
-
-
-
           /* do the binning and calc carrier usage */
           for (i = 0; i < symbol_period; i++)
-
             {
               MSC_carrier_usage[i] = 0;
               for (j = 0; j < 6; j++)
-
                 {
                   for (k = 0; k < lMSC; k++)
-
                     {
                       if (MSC_Demapper_symbolwise[j][k] == i)
-
                         {
                           (MSC_carrier_usage[i])++;
                         }
@@ -575,7 +498,6 @@ void channel_decoding(void)
             }
           cnt_MSC_used_carriers = 0;
           for (i = 0; i < symbol_period; i++)
-
             {
               if (MSC_carrier_usage[i] != 0)
 
@@ -584,49 +506,36 @@ void channel_decoding(void)
                 }
             }
           msc_parameters_changed = 1;
-
         }
     }
 
 
   robustness_mode_old = robustness_mode;
-
   interleaver_depth = interleaver_depth_new;
 
   /* frame count : deinterleaving possible after 2 received frames
      for short and after 6 received frames for long interleaving */
   frame_count++;
   if (frame_count >= 6 - 4 * interleaver_depth)
-
     {
       enough_frames = 1;
     }
-
   else
-
     {
       if (frame_count == 1)
-
         {
           min_index_equal_samples = transmission_frame_buffer_wptr;
           max_index_equal_samples = transmission_frame_buffer_wptr + symbol_period * symbols_per_frame;
         }
-
       else
-
         {
           if (transmission_frame_buffer_wptr < min_index_equal_samples)
-
             {
               min_index_equal_samples = transmission_frame_buffer_wptr;
             }
-          if (transmission_frame_buffer_wptr +
-              symbol_period * symbols_per_frame > max_index_equal_samples)
-
+          if (transmission_frame_buffer_wptr + symbol_period * symbols_per_frame > max_index_equal_samples)
             {
-              max_index_equal_samples =
-                  transmission_frame_buffer_wptr +
-                  symbol_period * symbols_per_frame;
+              max_index_equal_samples = transmission_frame_buffer_wptr + symbol_period * symbols_per_frame;
             }
         }
     }
@@ -640,19 +549,14 @@ void channel_decoding(void)
   multiplex_description.HM_length = 0;
   multiplex_description.PL_HM = 0;
   if (fabs(fac_data[5] - 1.0) < DBL_EPSILON)
-
     {
       multiplex_description.PL_PartA = 1;
       multiplex_description.PL_PartB = 1;
-
     }
-
   else
-
     {
       multiplex_description.PL_PartA = 0;
       multiplex_description.PL_PartB = 0;
-
     }
   application_information.stream_ID[0] = 0;
   application_information.stream_ID[1] = -1;
@@ -678,99 +582,75 @@ void channel_decoding(void)
 
   /* MSC parameters settings */
   if ((msc_parameters_changed == 1) && (msc_parameters_valid == 1))
-
     {
       if (msc_mode == 0)	/* 64-QAM SM */
-
         {
           //	  rylcm = RYlcmSM64[multiplex_description.PL_PartA];
           for (i = 0; i < 3; i++)
-
             {
               ratesA[i] = RatesSM64[multiplex_description.PL_PartA][i] - 1;
             }
           N1 = 0;
           N2 = N_MUX - N1;
           for (i = 0; i < 3; i++)
-
             {
               ratesB[i] = RatesSM64[multiplex_description.PL_PartB][i] - 1;
             }
           for (i = 0; i < 3; i++)
-
             {
               L[i] = 2 * N1 * (RX[ratesA[i]] / RY[ratesA[i]]);
-              L[i + 3] =
-                  (RX[ratesB[i]] * floor((2 * N2 - 12) / RY[ratesB[i]]));
-
+              L[i + 3] = (RX[ratesB[i]] * floor((2 * N2 - 12) / RY[ratesB[i]]));
             }
           Lvspp = 0;
           rowdimL = 3;
           coldimL = 2;
           xin1 = 2 * N1;
           xin2 = 2 * N2;
-
-          for (i = 0; i < xin1 + xin2; i++)
-            Deinterleaver[i] = i;
+          for (i = 0; i < xin1 + xin2; i++)  Deinterleaver[i] = i;
           if (Part_Deinterleaver != NULL) free(Part_Deinterleaver);
           Part_Deinterleaver = deinterleaver(xin1, 13, xin2, 13);
-          for (i = 0; i < xin1 + xin2; i++)
-            Deinterleaver[i + xin1 + xin2] = Part_Deinterleaver[i];
+          for (i = 0; i < xin1 + xin2; i++) Deinterleaver[i + xin1 + xin2] = Part_Deinterleaver[i];
           free(Part_Deinterleaver);
           Part_Deinterleaver = deinterleaver(xin1, 21, xin2, 21);
-          for (i = 0; i < xin1 + xin2; i++)
-            Deinterleaver[i + 2 * (xin1 + xin2)] = Part_Deinterleaver[i];
+          for (i = 0; i < xin1 + xin2; i++) Deinterleaver[i + 2 * (xin1 + xin2)] = Part_Deinterleaver[i];
 
           for (i = 0; i < 3; i++)
-
             {
               PL[i] = ratesA[i];
-
               PL[i + 3] = ratesB[i];
-
             }
         }
 
       else if (msc_mode == 1)	/* 16-QAM SM */
-
         {
           //	  rylcm = RYlcmSM16[multiplex_description.PL_PartA];
           for (i = 0; i < 2; i++) //joma
-
             {
               ratesA[i] = RatesSM16[multiplex_description.PL_PartA][i] - 1;
             }
           N1 = 0;
           N2 = N_MUX - N1;
-          for (i = 0; i < 2; i++) //joma
-
+          for (i = 0; i < 2; i++) //changed ON4QZ
             {
               ratesB[i] = RatesSM16[multiplex_description.PL_PartB][i] - 1;
             }
           for (i = 0; i < 2; i++)
-
             {
               L[i] = 2 * N1 * (RX[ratesA[i]] / RY[ratesA[i]]);
-              L[i + 2] =
-                  (RX[ratesB[i]] * floor((2 * N2 - 12) / RY[ratesB[i]]));
-
+              L[i + 2] = (RX[ratesB[i]] * floor((2 * N2 - 12) / RY[ratesB[i]]));
             }
           rowdimL = 2;
           coldimL = 2;
           Lvspp = 0;
           xin1 = 2 * N1;
           xin2 = 2 * N2;
-          if (Part_Deinterleaver != NULL)
-            free(Part_Deinterleaver);
+          if (Part_Deinterleaver != NULL) free(Part_Deinterleaver);
           Part_Deinterleaver = deinterleaver(xin1, 13, xin2, 13);
-          for (i = 0; i < xin1 + xin2; i++)
-            Deinterleaver[i] = Part_Deinterleaver[i];
+          for (i = 0; i < xin1 + xin2; i++)  Deinterleaver[i] = Part_Deinterleaver[i];
           free(Part_Deinterleaver);
           Part_Deinterleaver = deinterleaver(xin1, 21, xin2, 21);
-          for (i = 0; i < xin1 + xin2; i++)
-            Deinterleaver[i + (xin1 + xin2)] = Part_Deinterleaver[i];
+          for (i = 0; i < xin1 + xin2; i++)  Deinterleaver[i + (xin1 + xin2)] = Part_Deinterleaver[i];
           for (i = 0; i < 2; i++)
-
             {
               PL[i] = ratesA[i];
               PL[i + 2] = ratesB[i];
@@ -778,7 +658,6 @@ void channel_decoding(void)
         }
 
       else if (msc_mode == 3)	/* 4-QAM */
-
         {
           //	  rylcm = (int) RY[multiplex_description.PL_PartA];
           ratesA[0] = (int) RX[multiplex_description.PL_PartA] - 1;
@@ -786,24 +665,19 @@ void channel_decoding(void)
           N2 = N_MUX - N1;
           ratesB[0] = (int) RX[multiplex_description.PL_PartB] - 1;
           if (robustness_mode == 0)
-
             {
               if (spectrum_occupancy == 0)
-
                 {
                   L[0] = 0;
                   L[1] = 768;
                 }
-
               else
-
                 {
                   L[0] = 0;
                   L[1] = 837;
                 }
             }
           if (robustness_mode == 1)
-
             {
               if (spectrum_occupancy == 0)
 
@@ -811,16 +685,13 @@ void channel_decoding(void)
                   L[0] = 0;
                   L[1] = 537;
                 }
-
               else
-
                 {
                   L[0] = 0;
                   L[1] = 627;
                 }
             }
           if (robustness_mode == 2)
-
             {
               if (spectrum_occupancy == 0)
 
@@ -828,9 +699,7 @@ void channel_decoding(void)
                   L[0] = 0;
                   L[1] = 399;
                 }
-
               else
-
                 {
                   L[0] = 0;
                   L[1] = 435;
@@ -839,11 +708,9 @@ void channel_decoding(void)
           Lvspp = 0;
           xin1 = 2 * N1;
           xin2 = 2 * N2;
-          if (Part_Deinterleaver != NULL)
-            free(Part_Deinterleaver);
+          if (Part_Deinterleaver != NULL) free(Part_Deinterleaver);
           Part_Deinterleaver = deinterleaver(xin1, 21, xin2, 21);
-          for (i = 0; i < xin1 + xin2; i++)
-            Deinterleaver[i] = Part_Deinterleaver[i];
+          for (i = 0; i < xin1 + xin2; i++) Deinterleaver[i] = Part_Deinterleaver[i];
           PL[0] = 0;
           PL[1] = 6;
           rowdimL = 1;
@@ -852,34 +719,23 @@ void channel_decoding(void)
     }
 
   if (msc_parameters_valid != 0)
-
     {
       for (i = 0; i < lMSC; i++)
-
         {
           trxfrmbufptr = MSC_Demapper[frame_index - 1][i];
-          received_real[i] =
-              (double) transmission_frame_buffer[2 * trxfrmbufptr];
-          received_imag[i] =
-              (double) transmission_frame_buffer[2 * trxfrmbufptr + 1];
+          received_real[i] = (double) transmission_frame_buffer[2 * trxfrmbufptr];
+          received_imag[i] = (double) transmission_frame_buffer[2 * trxfrmbufptr + 1];
 
           MSC_cells_sequence[2 * i] = (float) received_real[i];
           MSC_cells_sequence[2 * i + 1] = (float) received_imag[i];
-          transfer_function_MSC[i * 2] =
-              channel_transfer_function_buffer[2 * trxfrmbufptr];
-          transfer_function_MSC[i * 2 + 1] =
-              channel_transfer_function_buffer[2 * trxfrmbufptr + 1];
+          transfer_function_MSC[i * 2] =  channel_transfer_function_buffer[2 * trxfrmbufptr];
+          transfer_function_MSC[i * 2 + 1] = channel_transfer_function_buffer[2 * trxfrmbufptr + 1];
         }
-
       if (enough_frames == 0)
-
         {
           for (i = 0; i < lMSC; i++)
-
             {
-              if ((MSC_Demapper[frame_index - 1][i] > max_index_equal_samples)
-                  || (MSC_Demapper[frame_index - 1][i] <
-                      min_index_equal_samples))
+              if ((MSC_Demapper[frame_index - 1][i] > max_index_equal_samples) || (MSC_Demapper[frame_index - 1][i] <  min_index_equal_samples))
 
                 {
                   transfer_function_MSC[2 * i] = 0.0;
@@ -887,10 +743,8 @@ void channel_decoding(void)
                 }
               SNR_estimation[i] =
                   sqrt(transfer_function_MSC[2 * i] *
-                       transfer_function_MSC[i * 2] +
-                       transfer_function_MSC[i * 2 +
-                       1] * transfer_function_MSC[i * 2 +
-                       1]);
+                  transfer_function_MSC[i * 2] +
+                  transfer_function_MSC[i * 2 + 1] * transfer_function_MSC[i * 2 + 1]);
             }
 
           n_SPPhard =
@@ -903,73 +757,41 @@ void channel_decoding(void)
         }
 
       else
-
         {
-
           MSCAvailable=true;
-
-
-
           SNR_estimation_valid = 0;
           if (SNR_estimation_valid < 1)
-
             {
               for (i = 0; i < lMSC; i++)
-
                 {
                   SNR_estimation[i] =
                       sqrt(transfer_function_MSC[2 * i] *
-                           transfer_function_MSC[i * 2] +
-                           transfer_function_MSC[i * 2 +
-                           1] * transfer_function_MSC[i *
-                           2 +
-                           1]);
+                      transfer_function_MSC[i * 2] +
+                      transfer_function_MSC[i * 2 + 1] * transfer_function_MSC[i * 2 + 1]);
                 }
             }
-
           else
-
             {
-
-
               for (i = 0; i < 461; i++)
-
                 {
-                  if (fabs(noise_power_density[i] - 0.0) < DBL_EPSILON)
-                    noise_power_density[i] = 1.0;
-
-
+                  if (fabs(noise_power_density[i] - 0.0) < DBL_EPSILON) noise_power_density[i] = 1.0;
                 }
               for (i = 0; i < lMSC; i++)
-
                 {
-
-
-                  if (noise_power_density
-                      [MSC_Demapper_symbolwise[frame_index - 1][i]] <= 0.0)
-
+                  if (noise_power_density[MSC_Demapper_symbolwise[frame_index - 1][i]] <= 0.0)
                     {
                       exit(EXIT_FAILURE);
                     }
-                  part1 =
-                      sqrt(transfer_function_MSC[i * 2] *
-                           transfer_function_MSC[i * 2] +
-                           transfer_function_MSC[i * 2 +
-                           1] * transfer_function_MSC[i *
-                           2 +
-                           1]);
-                  part2 =
-                      sqrt(noise_power_density
-                           [MSC_Demapper_symbolwise[frame_index - 1][i]]);
+                  part1 = sqrt(transfer_function_MSC[i * 2] *
+                      transfer_function_MSC[i * 2] +
+                      transfer_function_MSC[i * 2 +1] * transfer_function_MSC[i *2 + 1]);
+                  part2 =sqrt(noise_power_density[MSC_Demapper_symbolwise[frame_index - 1][i]]);
                   SNR_estimation[i] = part1 / part2;
-
-
                 }
             }
 
 
-          n_SPPhard =
-              msdhardmsc(received_real, received_imag, lMSC, SNR_estimation, N1,
+          n_SPPhard =  msdhardmsc(received_real, received_imag, lMSC, SNR_estimation, N1,
                          L, rowdimL, coldimL, Lvspp, Deinterleaver, PL,
                          MSD_ITER, 1, SPPhard, VSPPhard, &res_iters,
                          &calc_variance, noise_signal);
@@ -977,91 +799,53 @@ void channel_decoding(void)
           sum1 = 0.0;
           sum2 = 0.0;
           for (i = 0; i < lMSC; i++)
-
             {
               squared_noise_signal[i] =
                   noise_signal[2 * i] * noise_signal[2 * i] +
                   noise_signal[2 * i + 1] * noise_signal[2 * i + 1];
               sum1 +=
                   (transfer_function_MSC[2 * i] * transfer_function_MSC[2 * i] +
-                   transfer_function_MSC[2 * i +
-                   1] * transfer_function_MSC[2 * i +
-                   1]) *
+                  transfer_function_MSC[2 * i +
+                  1] * transfer_function_MSC[2 * i +
+                  1]) *
                   squared_noise_signal[i];
               sum2 +=
                   (transfer_function_MSC[2 * i] * transfer_function_MSC[2 * i] +
-                   transfer_function_MSC[2 * i +
-                   1] * transfer_function_MSC[2 * i +
-                   1]) *
+                  transfer_function_MSC[2 * i +
+                  1] * transfer_function_MSC[2 * i +
+                  1]) *
                   mean_energy_of_used_cells;
             }
 
           //	  calc_weighted_variance = sum1 / sum2;
           for (i = 0; i < lMSC; i++)
-
             {
-
-
-              squared_noise_signal_buffer[MSC_Demapper[frame_index - 1][i]] =
-                  squared_noise_signal[i];
+              squared_noise_signal_buffer[MSC_Demapper[frame_index - 1][i]] = squared_noise_signal[i];
             }
-
-
           /* now calc the sum of the reshaped "symbol_period" number of columns */
           for (i = 0; i < symbol_period; i++)
-
             {
               weighted_noise_power_density[i] = 0.0;
               for (j = 0; j < 6 * symbols_per_frame; j++)
-
                 {
-                  weighted_noise_power_density[i] +=
-                      squared_noise_signal_buffer[i + j * symbol_period];
+                  weighted_noise_power_density[i] += squared_noise_signal_buffer[i + j * symbol_period];
                 }
             }
 
-          //	  cnt_npwrpos = 0;
-          //    for (i = 0; i < symbol_period; i++)
-          //      {
-          //        if (fabs(weighted_noise_power_density[i]) > DBL_EPSILON)
-
-          //          {
-          //            noise_power_positions[cnt_npwrpos++] = i;
-          //          }
-          //      }
-
-          //	  for (i = 0; i < symbol_period; i++)
-
-          //	    {
-          //	      signal_to_noise_ratio[i] = 0.0;
-          //	    }
-          //	  for (i = 0; i < cnt_npwrpos; i++)
-
-          //	    {
-          //	      signal_to_noise_ratio[noise_power_positions[i]] = MSC_carrier_usage[noise_power_positions[i]] /weighted_noise_power_density[noise_power_positions[i]];
-          //	    }
-
-          for (i = 0; i < symbol_period; i++)	/* rows */
+         for (i = 0; i < symbol_period; i++)	/* rows */
             for (j = 0; j < symbols_per_frame; j++)	/* columns */
               samples_resorted[i][j] = 0.0;
 
           for (i = 0; i < lMSC; i++)
-
-            {
-              totindex =
-                  (MSC_Demapper[frame_index - 1][i]) % (symbol_period *
-                                                        symbols_per_frame);
+           {
+              totindex = (MSC_Demapper[frame_index - 1][i]) % (symbol_period * symbols_per_frame);
               posrow = totindex % symbol_period;
               poscolumn = totindex / symbol_period;
               samples_resorted[posrow][poscolumn] = squared_noise_signal[i] *
                   (transfer_function_MSC[i * 2] * transfer_function_MSC[i * 2] +
-                   transfer_function_MSC[i * 2 +
-                   1] * transfer_function_MSC[i * 2 + 1]);
+                  transfer_function_MSC[i * 2 + 1] * transfer_function_MSC[i * 2 + 1]);
             }
-
-
-          for (i = 0; i < cnt_MSC_used_carriers; i++)
-
+           for (i = 0; i < cnt_MSC_used_carriers; i++)
             {
               sum1 = 0.0;
               for (j = 0; j < symbols_per_frame; j++)
@@ -1071,51 +855,36 @@ void channel_decoding(void)
                   0.2 * sum1 / MSC_carrier_usage[MSC_used_carriers[i]];
             }
           if (SNR_estimation_valid < 1)
-
             {
               SNR_estimation_valid++;
             }
           channel_decoded_data_buffer_data_valid = 1;
         }
       if (Lvspp != 0)
-
         {
           VSPPlength =
               multiplex_description.stream_lengths[0][0] * 8 +
               multiplex_description.stream_lengths[1][0] * 8;
           HPPlength = 0;
           for (i = 0; i < no_of_streams; i++)
-
             {
               HPPlength += 8 * multiplex_description.stream_lengths[0][i];
             }
-
           n = 0;
-          for (i = 0; i < HPPlength; i++)
-            channel_decoded_data_buffer[n++] = SPPhard[i];
-          for (i = 0; i < VSPPlength; i++)
-            channel_decoded_data_buffer[n++] = VSPPhard[i];
-          for (i = 0; i < n_SPPhard - HPPlength; i++)
-            channel_decoded_data_buffer[n++] = SPPhard[HPPlength + i];
+          for (i = 0; i < HPPlength; i++) channel_decoded_data_buffer[n++] = SPPhard[i];
+          for (i = 0; i < VSPPlength; i++) channel_decoded_data_buffer[n++] = VSPPhard[i];
+          for (i = 0; i < n_SPPhard - HPPlength; i++)  channel_decoded_data_buffer[n++] = SPPhard[HPPlength + i];
         }
-
       else
-
         {
           for (i = 0; i < n_SPPhard; i++)
-
             {
               channel_decoded_data_buffer[i] = SPPhard[i];
-
-
             }
-
-
         }
     }
   frame_index = (frame_index % 6) + 1;
   transmission_frame_buffer_wptr =((transmission_frame_buffer_wptr +symbol_period * symbols_per_frame) % (symbol_period *symbols_per_frame * 6));
-
   return;
 }
 
@@ -1123,7 +892,6 @@ char getfacchar(double *facdata)
 {
   char karakter;
   int macht, i;
-
   macht=64;
   karakter =0;
   for (i=0; i < 7 ; i++)
diff --git a/qsstv/drmrx/deflate_uncompress.cpp b/qsstv/drmrx/deflate_uncompress.cpp
deleted file mode 100644
index 6188f23..0000000
--- a/qsstv/drmrx/deflate_uncompress.cpp
+++ /dev/null
@@ -1,294 +0,0 @@
-
-/******************************************************************************/
-
-/*                                                                            */
-
-/*  University of Kaiserslautern, Institute of Communications Engineering     */
-
-/*  Copyright (C) 2004 Torsten Schorr                                         */
-
-/*                                                                            */
-
-/*  Author(s)    : Torsten Schorr (schorr at eit.uni-kl.de)                      */
-
-/*  Project start: 15.07.2004                                                 */
-
-/*  Last change  : 03.08.2004                                                 */
-
-/*                                                                            */
-
-/******************************************************************************/
-
-/*                                                                            */
-
-/*  This program is free software; you can redistribute it and/or modify      */
-
-/*  it under the terms of the GNU General Public License as published by      */
-
-/*  the Free Software Foundation; either version 2 of the License, or         */
-
-/*  (at your option) any later version.                                       */
-
-/*                                                                            */
-
-/*  This program is distributed in the hope that it will be useful,           */
-
-/*  but WITHOUT ANY WARRANTY; without even the implied warranty of            */
-
-/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             */
-
-/*  GNU General Public License for more details.                              */
-
-/*                                                                            */
-
-/*  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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
-
-/*                                                                            */
-
-/******************************************************************************/
-
-
-/******************************************************************************/
-
-/*                                                                            */
-
-/*  deflate_uncompress.c                                                      */
-
-/*                                                                            */
-
-/******************************************************************************/
-
-/*  Description:                                                              */
-
-/*  Decompressor for data in gzip file format (RFC 1952)                      */
-
-/*  compressed with the DEFLATE compressed data format                        */
-
-/*  (RFC 1951). Used for Broadcast Web-Site application                       */
-
-/*  ETSI TS 101 498                                                           */
-
-/*                                                                            */
-
-/*  Usage:                                                                    */
-
-/*                                                                            */
-
-/*  [data, origname, zerror] = deflate_uncompress(input);                     */
-
-/*                                                                            */
-
-/*  uncompresses uint8 input bytes into uint8 data with original filename     */
-
-/*  origname. zerror: error during decompression                              */
-
-/*                                                                            */
-
-/******************************************************************************/
-
-
-/******************************************************************************/
-
-/*                                                                            */
-
-/*  This program is based on the 'zlib' general purpose compression library   */
-
-/*  version 1.1.3, July 9th, 1998 Jean-loup Gailly and Mark Adler             */
-
-/*                                                                            */
-
-/*                                                                            */
-
-/*  The data format used by the zlib library is described by RFCs (Request for*/
-
-/*  Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt */
-
-/*  (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).*/
-
-/*                                                                            */
-
-/******************************************************************************/
-
-
-/* code adjusted for use outside MATLAB
-*
-*  by M.Bos - PA0MBO
-*  
-*  date Jan 18th 2008
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <zlib.h>
-
-#define Nargs_rhs_str "1"
-#define Nargs_rhs 1
-#define PROGNAME "deflate_uncompress"
-static int gz_magic[2] = { 0x1f, 0x8b };	/* gzip magic header */
-
-
-
-/* gzip flag byte */
-#define ASCII_FLAG   0x01	/* bit 0 set: file probably ascii text */
-#define HEAD_CRC     0x02	/* bit 1 set: header CRC present */
-#define EXTRA_FIELD  0x04	/* bit 2 set: extra field present */
-#define ORIG_NAME    0x08	/* bit 3 set: original file name present */
-#define COMMENT      0x10	/* bit 4 set: file comment present */
-#define RESERVED     0xE0	/* bits 5..7: reserved */
-int
-deflate_uncompress(unsigned char *input, int l_in, char /*@out@ */ *origname,
-           int , unsigned char /*@out@ */ *data, int *,
-		   double /*@out@ */ *lhs2)
-{
-  unsigned char *compressed_data, *uncompressed_data;
-  int N, zerror;
-//  int dims[2];
-  int expected_size, len, method, flags, startpos, i;
-
-  uLong crc;
-  z_stream stream, *streamp = &stream;
-
-  /* in */
-  N = l_in;
-  compressed_data = input;
-  if (N < 10)
-    {
-      printf("not enough input data\n");
-      exit(EXIT_FAILURE);
-    }
-  streamp->zalloc = (alloc_func) NULL;
-  streamp->zfree = (free_func) NULL;
-  streamp->opaque = (voidpf) 0;
-  streamp->next_out = Z_NULL;
-  streamp->avail_in = 0;
-  streamp->next_in = compressed_data;
-  zerror = inflateInit2(streamp, -MAX_WBITS);
-
-  /* windowBits is passed < 0 to tell that there is no zlib header.
-   * Note that in this case inflate *requires* an extra "dummy" byte
-   * after the compressed stream in order to complete decompression and
-   * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are
-   * present after the compressed stream.
-   */
-  if (zerror != Z_OK)
-    {
-      inflateEnd(streamp);
-      printf("Error using inflateInit2\n");
-      exit(1);
-    }
-
-  /* Check the gzip magic header */
-  for (len = 0; len < 2; len++)
-    {
-      if (compressed_data[len] != gz_magic[len])
-	{
-	  printf("No gzip format\n");
-	  exit(1);
-	}
-    }
-  method = compressed_data[2];
-  flags = compressed_data[3];
-  if (method != Z_DEFLATED || (flags & RESERVED) != 0)
-    {
-      inflateEnd(streamp);
-      printf("No deflate format or reserved flags!\n");
-      exit(1);
-    }
-
-  /* Discard time, xflags and OS code: */
-  startpos = 10;
-  if ((flags & EXTRA_FIELD) != 0)
-    {				/* skip the extra field */
-      len = compressed_data[startpos] + (compressed_data[startpos + 1] << 8);
-      startpos += len + 2;
-    }
-  if ((flags & ORIG_NAME) != 0)
-
-    {				/* skip the original file name */
-      i = 0;
-
-      {
-	origname[i] = compressed_data[startpos];
-      }
-      while ((compressed_data[startpos++] != 0) && (startpos < N));
-    }
-  else
-
-    {
-      origname[0] = '\0';
-    }
-  if ((flags & COMMENT) != 0)
-    {				/* skip the .gz file comment */
-      while ((compressed_data[startpos++] != 0) && (startpos < N));
-    }
-  if ((flags & HEAD_CRC) != 0)
-    {				/* skip the header crc */
-      startpos += 2;
-    }
-  if (startpos > N - 8)
-    {
-      inflateEnd(streamp);
-      printf("not enough input data\n");
-      exit(1);
-    }
-  expected_size =
-    ((int) compressed_data[N - 1] << 24) +
-    ((int) compressed_data[N - 2] << 16) +
-    ((int) compressed_data[N - 3] << 8) + ((int) compressed_data[N - 4]);
-  if (expected_size > (0x01 << 30))
-    {
-      inflateEnd(streamp);
-      printf
-	("error in expected file size or file too large (support for 1GB files)\n");
-      exit(1);
-    }
-  uncompressed_data =
-    (unsigned char *) malloc(expected_size * sizeof(unsigned char));
-  if (uncompressed_data == NULL)
-    {
-      inflateEnd(streamp);
-      printf("error allocating memory\n");
-      exit(1);
-    }
-
-  /* prepare z_stream data structure */
-  streamp->avail_in = N - startpos;
-  streamp->next_in = compressed_data + startpos;
-  streamp->avail_out = expected_size;
-  streamp->next_out = uncompressed_data;
-
-  /* uncompress data */
-  zerror = inflate(streamp, Z_FINISH);
-  *lhs2 = 0.0;
-  if (zerror == Z_STREAM_END)
-    {
-
-      /* check crc over uncompressed data: */
-      crc = crc32(0L, Z_NULL, 0);
-      crc =
-	crc32(crc, uncompressed_data,
-	      (uInt) (streamp->next_out - uncompressed_data));
-      if ((((int) compressed_data[N - 5] << 24) +
-	   ((int) compressed_data[N - 6] << 16) +
-	   ((int) compressed_data[N - 7] << 8) +
-     ((uLong) compressed_data[N - 8]) != crc) | (expected_size != streamp->next_out - uncompressed_data))
-	{
-	  *lhs2 = -1.0;
-	}
-//      dims[0] = 1;
-//      dims[1] = streamp->next_out - uncompressed_data;
-      memcpy(data, uncompressed_data,
-	     (streamp->next_out - uncompressed_data) * sizeof(unsigned char));
-    }
-  else
-    {
-      *data = (double) zerror;
-    } inflateEnd(streamp);
-  free(uncompressed_data);
-  return zerror;
-}
diff --git a/qsstv/drmrx/demodulator.cpp b/qsstv/drmrx/demodulator.cpp
index d12f4c0..b2bcd9b 100644
--- a/qsstv/drmrx/demodulator.cpp
+++ b/qsstv/drmrx/demodulator.cpp
@@ -1,11 +1,12 @@
 #include "demodulator.h"
-#include "qsstvglobal.h"
+#include "appglobal.h"
 #include "drm.h"
 #include <math.h>
 #include <float.h>
 #include "nrutil.h"
 #include "utils/supportfunctions.h"
 
+#include <QDebug>
 
 
 demodulator *demodulatorPtr;
@@ -25,7 +26,6 @@ float tempbuf[30000];
 
 demodulator::demodulator()
 {
-  srcDecoder.init();
 }
 
 demodulator::~demodulator()
@@ -88,27 +88,28 @@ bool demodulator::demodulate(float *sigin,int numSamples)
   transmission_frame_buffer_data_valid = 0;
   // fac_valid can be -1,0,1
 
+
   addToLog(QString("block %1 samples %2" ).arg(iterationCounter).arg(numSamples),LOGDRMDEMOD);
-//  if(iterationCounter<40) arrayDump(QString("DEM %1").arg(iterationCounter),sigin,128,true);
-//  arrayDump(QString("bl%1").arg(iterationCounter),sigin,32,true);
-//  logfile->addToAux(QString("block %1").arg(iterationCounter));
-//  arrayDump(QString("rs"),sigin,numSamples*2,true);
-//  if (fac_valid == 0)
-//    {
-//      fac_not_valid_counter--;
-//      if (fac_not_valid_counter <= 0)
-//        {
-//          doSynchronize = true;
-//          fac_not_valid_counter = FACVALIDCNTR;
-//        }
-//    }
-//  else
-//    {
-//      if (fac_valid == 1)
-//        {
-//          fac_not_valid_counter = FACVALIDCNTR;
-//        }
-//    }
+  //  if(iterationCounter<40) arrayDump(QString("DEM %1").arg(iterationCounter),sigin,128,true);
+  //  arrayDump(QString("bl%1").arg(iterationCounter),sigin,32,true);
+  //  logfile->addToAux(QString("block %1").arg(iterationCounter));
+  //  arrayDump(QString("rs"),sigin,numSamples*2,true);
+  //  if (fac_valid == 0)
+  //    {
+  //      fac_not_valid_counter--;
+  //      if (fac_not_valid_counter <= 0)
+  //        {
+  //          doSynchronize = true;
+  //          fac_not_valid_counter = FACVALIDCNTR;
+  //        }
+  //    }
+  //  else
+  //    {
+  //      if (fac_valid == 1)
+  //        {
+  //          fac_not_valid_counter = FACVALIDCNTR;
+  //        }
+  //    }
   if (doSynchronize)
     {
       doSynchronize = false;
@@ -117,11 +118,11 @@ bool demodulator::demodulate(float *sigin,int numSamples)
   if (numberOfSamples> 0)
     {
       ++iterationCounter;
-//      logfile->addToAux(QString("iterationCounter %1").arg(iterationCounter));
-//      arrayDump("sig1",sigin,RXSTRIPE,true);
-//      logfile->addToAux(QString("rsbufwidx %1 offset %2").arg(rsbufwidx).arg(320 * N_symbols_mode_detection/2));
+      //      logfile->addToAux(QString("iterationCounter %1").arg(iterationCounter));
+      //      arrayDump("sig1",sigin,RXSTRIPE,true);
+      //      logfile->addToAux(QString("rsbufwidx %1 offset %2").arg(rsbufwidx).arg(320 * N_symbols_mode_detection/2));
 
-//      arrayDump("sigD",&rs_buffer[320 * N_symbols_mode_detection],16,true);
+      //      arrayDump("sigD",&rs_buffer[320 * N_symbols_mode_detection],16,true);
       for(i=0;i<numberOfSamples;i++)
         {
           rs_buffer[(i + rsbufwidx)*2] = sigin[i*2];
@@ -138,21 +139,30 @@ bool demodulator::demodulate(float *sigin,int numSamples)
         }
 
     }
- if(!timeSync()) return false;
- if(!frequencySync()) return false;
- if(!frameSync()) return false;
- if(channelEstimation())
-   {
-     channel_decoding();
-     srcDecoder.decode();
-   }
- if(doSynchronize)
-   {
-     // see if we have to save the data (for BSR and endOfImage)
-//     srcDecoder.checkSaveImage();
-   }
-
- return true;
+  if(!timeSync())
+    {
+      return false;
+    }
+  if(!frequencySync())
+    {
+      return false;
+    }
+  if(!frameSync())
+    {
+      return false;
+    }
+  if(channelEstimation())
+    {
+      channel_decoding();
+      srcDecoder->decode();
+    }
+  if(doSynchronize)
+    {
+      // see if we have to save the data (for BSR and endOfImage)
+      //     srcDecoder.checkSaveImage();
+    }
+
+  return true;
 }
 
 bool demodulator::timeSync()
@@ -179,8 +189,8 @@ bool demodulator::timeSync()
       time_offset_integer = (int) floor(time_offset + 0.5);
       if(robustness_mode!=99)
         {
-      addToLog(QString("numSamples %1, robustmode %2,timeoffset %3,smplrateOffsetEst %4,freqOffsetFracInit %5,timeOffsetInteger %6")
-               .arg(numberOfSamples).arg( robustness_mode).arg(time_offset).arg(samplerate_offset_estimation).arg(frequency_offset_fractional_init).arg(time_offset_integer),LOGDRMDEMOD);
+          addToLog(QString("numSamples %1, robustmode %2,timeoffset %3,smplrateOffsetEst %4,freqOffsetFracInit %5,timeOffsetInteger %6")
+                   .arg(numberOfSamples).arg( robustness_mode).arg(time_offset).arg(samplerate_offset_estimation).arg(frequency_offset_fractional_init).arg(time_offset_integer),LOGDRMDEMOD);
         }
 
       if ((fabsf(samplerate_offset_estimation) > 200.0E-5) && (robustness_mode != 99))
@@ -189,12 +199,12 @@ bool demodulator::timeSync()
           N_samples_needed = N_symbols_mode_detection * 320;
           input_samples_buffer_request = N_samples_needed;
           rsbufwidx = 0;
-//          samplerate_offset_estimation=0;
+          //          samplerate_offset_estimation=0;
           return false;
         }
       if (robustness_mode != 99)
         {
-//          logfile->addToAux("timesync found");
+          //          logfile->addToAux("timesync found");
           addToLog(QString("found robustness_mode: %1").arg(robustness_mode),LOGDRMDEMOD);
           timeSyncFlag = true;
           Ts = Ts_list[robustness_mode];
@@ -225,15 +235,15 @@ bool demodulator::timeSync()
         {
           samplerate_offset_estimation = 0.0;
           int shift=320 * N_symbols_mode_detection;
-//          int shift=512;
+          //          int shift=512;
           memmove(rs_buffer,&rs_buffer[shift*2],sizeof(float)*2*(rsbufwidx-shift));
           rsbufwidx -= shift;
-//          arrayDump("sig2",rs_buffer,16,true);
-//          for (i = 0; i < rsbufwidx; i++)	/* pa0mbo was rsbufwidx-1 ? */
-//            {
-//              rs_buffer[i * 2] = rs_buffer[(shift + i) * 2];
-//              rs_buffer[i * 2 + 1] = rs_buffer[(shift + i) * 2 + 1];
-//            }
+          //          arrayDump("sig2",rs_buffer,16,true);
+          //          for (i = 0; i < rsbufwidx; i++)	/* pa0mbo was rsbufwidx-1 ? */
+          //            {
+          //              rs_buffer[i * 2] = rs_buffer[(shift + i) * 2];
+          //              rs_buffer[i * 2 + 1] = rs_buffer[(shift + i) * 2 + 1];
+          //            }
           N_samples_needed = N_symbols_mode_detection * 320 - rsbufwidx;
           if (N_samples_needed > 0)
             {
@@ -286,14 +296,14 @@ bool demodulator::frequencySync()
       for (i = 0; i < N_symbols_frequency_pilot_search; i++)
         {
           delta_time_offset_integer = getofdm(&rs_buffer[2 * t_smp], time_offset_fractional_init,freq_offset_init, delta_time_offset_I_init, Ts, Tu, Zi,
-                                              symbol_temp, 0, 1,1);
+              symbol_temp, 0, 1,1);
           for (j = 0; j < K_modulo; j++)
             {
               symbol_buffer[(i * K_modulo + j) * 2] = symbol_temp[j * 2];
               symbol_buffer[(i * K_modulo + j) * 2 + 1] = symbol_temp[j * 2 + 1];
             }
           t_smp = t_smp + Ts + delta_time_offset_integer;
-         }
+        }
 
       freq_offset_integer = getfoffsint(symbol_buffer, N_symbols_frequency_pilot_search, K_dc,K_modulo, Tu);
       //  prepare for new round
@@ -406,7 +416,7 @@ bool demodulator::frequencySync()
 
 bool demodulator::frameSync()
 {
- int i,j,k;
+  int i,j,k;
   int symbol0;
 
   int symbol_no_to_equalize;
@@ -466,7 +476,7 @@ bool demodulator::frameSync()
 
         {
           delta_time_offset_integer =  getofdm(&rs_buffer[2 * t_smp], time_offset_fractional_init,freq_offset_init, delta_time_offset_I_init, Ts, Tu, Zi,symbol_temp, 0, 1,1);
-//          arrayDump("sm1",symbol_temp,symbols_per_2D_window*2,true);
+          //          arrayDump("sm1",symbol_temp,symbols_per_2D_window*2,true);
           for (j = 0; j < K_modulo; j++)
             {
               symbol_buffer[(i * K_modulo + j) * 2] = symbol_temp[j * 2];
@@ -476,7 +486,7 @@ bool demodulator::frameSync()
           symbufwidx++;
           t_smp += Ts + delta_time_offset_integer;
         }
-//       arrayDump("sm1",symbol_buffer,symbols_per_2D_window*K_modulo*2,true);
+      //       arrayDump("sm1",symbol_buffer,symbols_per_2D_window*K_modulo*2,true);
       // symbol align rs_buffer
       rsbufwidx -= t_smp;
 
@@ -496,9 +506,9 @@ bool demodulator::frameSync()
       for(i=0;i<5;i++)
         for(j=0;j<208;j++)
           for (k=0;k<205;k++)
-        {
-         W_pilots_blk[i][j][k]=0;
-        }
+            {
+              W_pilots_blk[i][j][k]=0;
+            }
 
     }
 
@@ -568,13 +578,13 @@ bool demodulator::channelEstimation()
       spectrum_occupancy = 1;
       mode_and_occupancy_code = mode_and_occupancy_code_table[robustness_mode * 6 + spectrum_occupancy];
     }
+
   if (mode_and_occupancy_code != mode_and_occupancy_code_last)
     {
       K_min = K_min_K_max_list[0][spectrum_occupancy + robustness_mode * 6];
       K_max = K_min_K_max_list[1][spectrum_occupancy + robustness_mode * 6];
       carrier_per_symbol = K_max - K_min + 1;
       (void) getofdmsync(NULL, Ts, Tu, NULL, K_max - K_min + 1, 0, NULL, NULL, 1, 1, 1);	/* initialisation */
-
       //  reformat pilot index stuff into th K_dc/K_modulo block
       //  first call listsinit to get gain_ref_cells_k etc
       //  Jan 5th 2009 changed listsinit() call to an include of all code from listsinit.c
@@ -593,8 +603,7 @@ bool demodulator::channelEstimation()
       for (i = 0; i < cnt_time_ref_cells; i++)
         {
           time_ref_cells_k[i] = time_ref_cells_k_list[robustness_mode][i];
-          time_ref_cells_theta_1024[i] =
-              time_ref_cells_theta_1024_list[robustness_mode][i];
+          time_ref_cells_theta_1024[i] =time_ref_cells_theta_1024_list[robustness_mode][i];
         }
       K_min =
           K_min_K_max_list[0][spectrum_occupancy_estimation +
@@ -690,7 +699,7 @@ bool demodulator::channelEstimation()
 
             }
 
-//          cnt_tr_cells[nnn] = 0;
+          //          cnt_tr_cells[nnn] = 0;
           for (i = 0; i < rndcnt; i++)
             {
               if ((training_cells_k[nnn][i] - K_min) <(carrier_per_symbol * symbols_per_2D_window))
@@ -710,7 +719,6 @@ bool demodulator::channelEstimation()
                   next_pilot_cells_k[nnn][(cnt_next_pilot_cells[nnn])++] = ((training_cells_k[nnn][i]- K_min) % carrier_per_symbol) + K_min;
                 }
             }
-
           //  now sort training cells in subset if necessary
           sortbrkpnt = 0;
           for (i = 1; i < cnt_tr_cells[nnn]; i++)
@@ -741,13 +749,11 @@ bool demodulator::channelEstimation()
                 }
               sortbrkpnt = 0;
             }
-
           //  copy to training_cells_k
           for (i = 0; i < cnt_tr_cells[nnn]; i++)
             {
               training_cells_k[nnn][i] = gain_ref_cells_subset[nnn][i];
             }
-
           gain_ref_cells_per_window = cnt_tr_cells[nnn];
           for (k_index1 = 0; k_index1 < gain_ref_cells_per_window; k_index1++)
             {
@@ -780,7 +786,6 @@ bool demodulator::channelEstimation()
             }
 
           //   now the matrix inversion from numerical recipes
-
           NP = gain_ref_cells_per_window;
           amatrix = matrix(1, NP, 1, NP);
           indxlu = ivector(1, NP);
@@ -909,8 +914,8 @@ bool demodulator::channelEstimation()
           training_cells_relative_index[j] =(gain_ref_cells_k[gain_ref_cells_subset_nn[j]] +(symbols_per_frame -nn) * K_modulo) % (K_modulo * symbols_per_frame);
         }
 
-     cnt_actual_pilots_rel_indx = 0;
-//     logfile->addToAux(QString("block %1").arg(iterationCounter));
+      cnt_actual_pilots_rel_indx = 0;
+      //     logfile->addToAux(QString("block %1").arg(iterationCounter));
       for (j = 0; j < cnt_tr_cells[ntwee]; j++)
         {
           if ((training_cells_relative_index[j] - (symbols_per_2D_window-1) * K_modulo) >= 0)
@@ -986,14 +991,14 @@ bool demodulator::channelEstimation()
       //  get next symbol
       if ((iterationCounter>=0) && (iterationCounter<=180))
         {
-//          arrayDump("b179",&rs_buffer[2 * t_smp],Ts,true);
-//          logfile->addToAux(QString("block %1").arg(iterationCounter));
-//          arrayDump("h179",H,K_max - K_min + 1,true);
+          //          arrayDump("b179",&rs_buffer[2 * t_smp],Ts,true);
+          //          logfile->addToAux(QString("block %1").arg(iterationCounter));
+          //          arrayDump("h179",H,K_max - K_min + 1,true);
         }
       delta_time_offset_integer =getofdmsync(&rs_buffer[2 * t_smp], Ts, Tu, H, K_max - K_min + 1,delta_freq_offset, Zi, symbol_temp, 0, 1,1);
-//      arrayDump("symtmp",symbol_temp,K_modulo,true);
+      //      arrayDump("symtmp",symbol_temp,K_modulo,true);
 
-//      addToLog(QString("delta_time_offset_integer %1").arg(delta_time_offset_integer),LOGDRMDEMOD);
+      //      addToLog(QString("delta_time_offset_integer %1").arg(delta_time_offset_integer),LOGDRMDEMOD);
       for (j = 0; j < K_modulo; j++)
         {
           symbol_buffer[(symbufwidx * K_modulo + j) * 2] = symbol_temp[j * 2];
@@ -1066,6 +1071,7 @@ bool demodulator::channelEstimation()
     }
 
   FACAvailable=true;
+  avgSNRAvailable=true;
   MERFAC = (float) (log(sum_MERFAC / lFAC + 1.0E-10));
   MERFAC /= (log(10.0));
   MERFAC *= -10.0;
@@ -1075,7 +1081,7 @@ bool demodulator::channelEstimation()
   SNR_dB = WMERFAC;
 
   addToLog(QString("SNR-FAC =%1").arg(SNR_dB),LOGDRMDEMOD);
-//  N_samples_needed = (symbols_per_frame + 1) * Ts - rsbufwidx;
+  //  N_samples_needed = (symbols_per_frame + 1) * Ts - rsbufwidx;
 
   if (SNR_dB < SNR_MIN_DB)
     {
diff --git a/qsstv/drmrx/demodulator.h b/qsstv/drmrx/demodulator.h
index 62b7830..58c721e 100644
--- a/qsstv/drmrx/demodulator.h
+++ b/qsstv/drmrx/demodulator.h
@@ -18,10 +18,11 @@
 //#define SNR_MIN_DB 5
 //#define FAC_NOT_VALID_TIMEOUT 4
 
-
 extern int Ts_list[DRMNUMMODES];
 extern int Tu_list[DRMNUMMODES];
 extern int Tg_list[DRMNUMMODES];
+extern bool FACAvailable;
+
 class demodulator
 {
 public:
@@ -32,13 +33,13 @@ public:
   bool isTimeSync() {return timeSyncFlag;}
   bool isFrequencySync() {return frequencySyncFlag;}
   bool isFrameSync() {return frameSyncFlag;}
+  bool isFACAvailable() {return FACAvailable;}
 private:
   int iterationCounter;
   bool timeSync();
   bool frequencySync();
   bool frameSync();
   bool channelEstimation();
-//  bool FACAvailable;
   int symbol_counter;
   int N_samples_needed;
   int SNR_time_out_counter;
diff --git a/qsstv/drmrx/drm.cpp b/qsstv/drmrx/drm.cpp
index 2c904d4..00a2b1f 100644
--- a/qsstv/drmrx/drm.cpp
+++ b/qsstv/drmrx/drm.cpp
@@ -142,5 +142,20 @@ int length_decoded_data;
 int MSC_Demapper[6][2959];
 long bufaucnt[2048];
 
+emscStatus msc_valid;
+int bodyTotalSegments;
+int rxSegments;
+int currentSegmentNumber;
+unsigned int rxTransportID;
+QList<short unsigned int> drmBlockList;
+sourceDecoder *srcDecoder;
+uint txTransportID;
+bool stopDRM;
+float avgSNR;
+float lastAvgSNR;
+bool avgSNRAvailable;
+QString drmCallsign;
+
+
 
 
diff --git a/qsstv/drmrx/drm.h b/qsstv/drmrx/drm.h
index aeec164..ca02719 100644
--- a/qsstv/drmrx/drm.h
+++ b/qsstv/drmrx/drm.h
@@ -27,8 +27,13 @@
 #include "drmdefs.h"
 #include "structtemplates.h"
 
+#include <QString>
+#include <QList>
+
 
 class demodulator;
+class sourceDecoder;
+
 extern int input_samples_buffer_request;
 extern int symbols_per_frame_list[4];
 extern int time_ref_cells_k_list[4][21];
@@ -57,7 +62,7 @@ extern int power_boost_list[4][6][4];
 extern int mode_and_occupancy_code_table[14];
 extern int robustness_mode, spectrum_occupancy_estimation;
 extern int spectrum_occupancy;
-extern int symbols_per_frame;
+extern int symbols_per_frame;extern QString drmCallsign;
 extern int time_ref_cells_cnt_list[4];
 extern int K_modulo, K_dc;
 extern float mean_energy_of_used_cells;
@@ -84,6 +89,7 @@ extern struct dfltMOTobj default_MOT_object;
 extern int channel_decoded_data_buffer_data_valid;
 extern double channel_decoded_data_buffer[110000];
 extern float WMERFAC;
+
 extern bool callsignValid;
 
 
@@ -102,6 +108,25 @@ extern float deltaFS;
 //extern char drmCallsign[9];
 extern demodulator *demodulatorPtr;
 
+
+enum emscStatus {INVALID,VALID,ALREADYRECEIVED};
+extern emscStatus msc_valid;
+extern int bodyTotalSegments;
+extern int rxSegments;
+extern int currentSegmentNumber;
+extern unsigned int rxTransportID;
+extern QList<short unsigned int> drmBlockList;
+extern uint txTransportID;
+extern bool stopDRM;
+extern float avgSNR;
+extern float lastAvgSNR;
+extern bool avgSNRAvailable;
+extern sourceDecoder *srcDecoder;
+extern QString drmCallsign;
+
+
+
+
 #endif
 
 
diff --git a/qsstv/drmrx/drmconstellationframe.cpp b/qsstv/drmrx/drmconstellationframe.cpp
index 907942c..bc42847 100644
--- a/qsstv/drmrx/drmconstellationframe.cpp
+++ b/qsstv/drmrx/drmconstellationframe.cpp
@@ -3,7 +3,7 @@
 #include <QPainter>
 #include "drm.h"
 #include "math.h"
-#include "qsstvdefs.h"
+#include "appdefs.h"
 
 
 extern float MSC_cells_sequence[2 * 2959];
diff --git a/qsstv/drmrx/drmdatainput.cpp b/qsstv/drmrx/drmdatainput.cpp
deleted file mode 100644
index 08f173c..0000000
--- a/qsstv/drmrx/drmdatainput.cpp
+++ /dev/null
@@ -1,879 +0,0 @@
-#include "drmdatainput.h"
-#include "qsstvglobal.h"
-#include "dsp/filter.h"
-#include "dsp/downsamplefilter.h"
-#include "drm.h"
-#include "drmproto.h"
-#include "sound/soundio.h"
-#include "utils/supportfunctions.h"
-#include "dsp/filterparam.h"
-
-
-#define FILTERLENGTH 8
-//#define HILBERT83
-#define HILBERT151
-//#define HILBERT360
-#ifdef HILBERT83
-#define HILBERTTAPS 83
-#endif
-
-#ifdef HILBERT151
-#define HILBERTTAPS 151
-#endif
-
-#ifdef HILBERT360
-#define HILBERTTAPS 360
-#endif
-
-//static float subfilt1[FILTERLENGTH] =
-
-//{
-//  -6.304691e-004,
-//  2.369513e-003,
-//  -9.174512e-003,
-//  3.102797e-002,
-//  2.437302e-001,
-//  -2.230165e-002,
-//  6.759297e-003,
-//  -1.587494e-003
-//};
-
-
-//static float subfilt2[FILTERLENGTH] =
-//{
-//  -1.818568e-003,
-//  8.332497e-003,
-//  -2.973091e-002,
-//  1.111435e-001,
-//  1.924554e-001,
-//  -3.981645e-002,
-//  1.180361e-002,
-//  -2.561942e-003
-//};
-
-//static float subfilt3[FILTERLENGTH] =
-//{
-//  -2.561942e-003,
-//  1.180361e-002,
-//  -3.981645e-002,
-//  1.924554e-001,
-//  1.111435e-001,
-//  -2.973091e-002,
-//  8.332497e-003,
-//  -1.818568e-003
-//};
-
-//static float subfilt4[FILTERLENGTH] =
-//{
-//  -1.587494e-003,
-//  6.759297e-003,
-//  -2.230165e-002,
-//  2.437302e-001,
-//  3.102797e-002,
-//  -9.174512e-003,
-//  2.369513e-003,
-//  -6.304691e-004
-//};
-
-//static float B_Inphase[HILBERTTAPS] =
-//{
-//  -0.000013096429498,
-//  0.000000663887755,
-//  -0.000069635287780,
-//  -0.000011931707517,
-//  -0.000144533153108,
-//  -0.000025373980217,
-//  -0.000391789228659,
-//  -0.000232426477943,
-//  -0.000478143393960,
-//  -0.000487558968789,
-//  -0.000685650336825,
-//  -0.001354704880460,
-//  -0.000546201344479,
-//  -0.002342397998132,
-//  -0.000346673289958,
-//  -0.004288405547670,
-//  0.000076514567549,
-//  -0.006214057213030,
-//  0.000471140764452,
-//  -0.008869259301553,
-//  0.000310928936475,
-//  -0.010853542810835,
-//  -0.000618723760850,
-//  -0.012558669622822,
-//  -0.003528318293013,
-//  -0.012565638823234,
-//  -0.008458796942648,
-//  -0.010998473138919,
-//  -0.016909533624041,
-//  -0.007029340421051,
-//  -0.028648813220546,
-//  -0.000916074544044,
-//  -0.045239295406484,
-//  0.007126861010101,
-//  -0.067146558987974,
-//  0.016470713456071,
-//  -0.099200587662524,
-//  0.025927955112860,
-//  -0.157545675961710,
-//  0.034759206835915,
-//  -0.403756659009051,
-//  0.872044314623357,
-//  0.298152956415124,
-//  0.045762401414113,
-//  0.057682372386628,
-//  0.046612304642337,
-//  0.009812557897304,
-//  0.044738697480695,
-//  -0.007877026958678,
-//  0.039793922738241,
-//  -0.014019542011307,
-//  0.033363547774391,
-//  -0.014228247558443,
-//  0.025586601071249,
-//  -0.011722710151015,
-//  0.018169441690637,
-//  -0.007774072820479,
-//  0.011227152592688,
-//  -0.004254206945683,
-//  0.005868718139545,
-//  -0.001002308783387,
-//  0.001901375136305,
-//  0.000729336127630,
-//  -0.000472570900136,
-//  0.001969539594901,
-//  -0.001560255803054,
-//  0.001905716822635,
-//  -0.001878235948282,
-//  0.001813958429404,
-//  -0.001475079548897,
-//  0.001117144708583,
-//  -0.001143142395249,
-//  0.000739068897549,
-//  -0.000539580485663,
-//  0.000277728151810,
-//  -0.000341625345467,
-//  0.000100860733753,
-//  -0.000052333537017,
-//  0.000001973643242,
-//  -0.000040013168559,
-//  -0.000013316614262,
-//  0.000006340573991,
-//  -0.000004973750149
-//};
-
-//static float B_Quad[HILBERTTAPS] =
-//  { 0.000000000000000, -0.000006581551523, -0.000014192774668,
-//0.000038355453153, -0.000061469802717, 0.000046155098672,
-//  -0.000269873790862, 0.000273874035623, -0.000496517495085,
-//    0.000383120218360, -0.001080412050939, 0.000679569009380,
-//    -0.001431859472243,
-//  0.000632904747289, -0.002103194937170, 0.000269803608080,
-//    -0.002028650339142, -0.000864482682011, -0.001935633229621,
-//    -0.003130320749406,
-//  -0.000660757624173, -0.006511157948451, 0.000829477180331,
-//    -0.011499838339182, 0.003150251021340, -0.017295118095470,
-//    0.004931046332886,
-//  -0.024156288476640, 0.005730140929231, -0.030544691199518,
-//    0.003619186767370, -0.036441773169957, -0.003417440897749,
-//    -0.040091021199004,
-//  -0.019051201727783, -0.041600273509535, -0.051332869304505,
-//    -0.039743071204460, -0.127032560999817, -0.035198771562362,
-//    -0.488057960837085,
-//  -0.584664836150859, 0.558860293285832, -0.018787192344116,
-//    0.193986224985834, -0.008891772659445, 0.111263353226189,
-//    0.000562232648398,
-//  0.069350999397921, 0.008632835092782, 0.043147713646936,
-//    0.014687263334153, 0.025127872636149, 0.018102917799341,
-//    0.013466436394485,
-//  0.019348490199617, 0.005952331932605, 0.018192510371929,
-//    0.002067567347773, 0.015985137219339, 0.000257349155187,
-//    0.012513166744168,
-//  -0.000036691339210, 0.009393580004274, 0.000299271454802,
-//    0.006076795140808, 0.000699657108499, 0.003864640455567,
-//    0.001119449029703,
-//  0.001926535004930, 0.001049068709402, 0.000995120503174,
-//    0.001044597409952, 0.000305528639009, 0.000630886520545,
-//    0.000111000803475,
-//  0.000464927709514, 0.000005944149118, 0.000157049271650,
-//    -0.000003528848644, 0.000069808136642, 0.000001885388254,
-//    0.000012115208419,
-//};
-
-#ifdef HILBERT83
-
-// blFIR  Hilbert
-// localSamplingrate = 12000.000000
-// number of taps = 83
-// corner frequency = 1000.000000
-// beta = 0.500000
-// window applied
-//Coefficients:
-const FILTERPARAMTYPE hilbert[HILBERTTAPS]=
-{
-
-     0.00195121951219512,
-     0,
-     0.00218951295028307,
-     0,
-     0.00274155836904681,
-     0,
-     0.00365039553708327,
-     0,
-     0.00496219678931242,
-     0,
-     0.00672774409495607,
-     0,
-     0.00900470037777058,
-     0,
-     0.01186106975868,
-     0,
-     0.0153804894372836,
-     0,
-     0.0196704386862718,
-     0,
-     0.024875273452504,
-     0,
-     0.0311975987201718,
-     0,
-     0.0389347935888508,
-     0,
-     0.0485447715399211,
-     0,
-     0.0607723902308125,
-     0,
-     0.0769136201887418,
-     0,
-     0.0994316691908993,
-     0,
-     0.13362885988773,
-     0,
-     0.193330225501393,
-     0,
-     0.329299964994593,
-     0,
-     0.998650268544521,
-     0,
-     -0.998650268544521,
-     0,
-     -0.329299964994593,
-     0,
-     -0.193330225501393,
-     0,
-     -0.13362885988773,
-     0,
-     -0.0994316691908993,
-     0,
-     -0.0769136201887418,
-     0,
-     -0.0607723902308125,
-     0,
-     -0.0485447715399211,
-     0,
-     -0.0389347935888508,
-     0,
-     -0.0311975987201718,
-     0,
-     -0.024875273452504,
-     0,
-     -0.0196704386862718,
-     0,
-     -0.0153804894372836,
-     0,
-     -0.01186106975868,
-     0,
-     -0.00900470037777058,
-     0,
-     -0.00672774409495607,
-     0,
-     -0.00496219678931242,
-     0,
-     -0.00365039553708327,
-     0,
-     -0.00274155836904681,
-     0,
-     -0.00218951295028307,
-     0,
-     -0.00195121951219512
-  };
-#endif
-
-#ifdef HILBERT151
-
-// blFIR  Hilbert
-// localSamplingrate = 12000.000000
-// number of taps = 151
-// corner frequency = 1000.000000
-// beta = 0.500000
-// window applied
-//Coefficients:
-
-const FILTERPARAMTYPE hilbert[HILBERTTAPS]=
-{
-     0.00106666666666667,
-     0,
-     0.00111799020198943,
-     0,
-     0.00121749046405025,
-     0,
-     0.00136886588233087,
-     0,
-     0.00157592342822028,
-     0,
-     0.00184260137668314,
-     0,
-     0.00217299884412417,
-     0,
-     0.00257141359464515,
-     0,
-     0.00304238999373074,
-     0,
-     0.00359077949800265,
-     0,
-     0.00422181674681683,
-     0,
-     0.00494121522949637,
-     0,
-     0.00575528773156199,
-     0,
-     0.00667109844581354,
-     0,
-     0.00769665596238367,
-     0,
-     0.0088411596130561,
-     0,
-     0.0101153162732349,
-     0,
-     0.0115317513868608,
-     0,
-     0.0131055477183722,
-     0,
-     0.0148549598147661,
-     0,
-     0.0168023740886606,
-     0,
-     0.0189756183245283,
-     0,
-     0.0214097779833233,
-     0,
-     0.0241497635092426,
-     0,
-     0.0272540175599975,
-     0,
-     0.0308,
-     0,
-     0.0348925322232539,
-     0,
-     0.0396769064421141,
-     0,
-     0.045360270349271,
-     0,
-     0.0522481015058711,
-     0,
-     0.0608098544941651,
-     0,
-     0.0718051968979872,
-     0,
-     0.0865479463372845,
-     0,
-     0.107521909278733,
-     0,
-     0.140052424123536,
-     0,
-     0.19798957926751,
-     0,
-     0.332124254201553,
-     0,
-     0.999596501845475,
-     0,
-     -0.999596501845475,
-     0,
-     -0.332124254201553,
-     0,
-     -0.19798957926751,
-     0,
-     -0.140052424123536,
-     0,
-     -0.107521909278733,
-     0,
-     -0.0865479463372845,
-     0,
-     -0.0718051968979872,
-     0,
-     -0.0608098544941651,
-     0,
-     -0.0522481015058711,
-     0,
-     -0.045360270349271,
-     0,
-     -0.0396769064421141,
-     0,
-     -0.0348925322232539,
-     0,
-     -0.0308,
-     0,
-     -0.0272540175599975,
-     0,
-     -0.0241497635092426,
-     0,
-     -0.0214097779833233,
-     0,
-     -0.0189756183245283,
-     0,
-     -0.0168023740886606,
-     0,
-     -0.0148549598147661,
-     0,
-     -0.0131055477183722,
-     0,
-     -0.0115317513868608,
-     0,
-     -0.0101153162732349,
-     0,
-     -0.0088411596130561,
-     0,
-     -0.00769665596238367,
-     0,
-     -0.00667109844581354,
-     0,
-     -0.00575528773156199,
-     0,
-     -0.00494121522949637,
-     0,
-     -0.00422181674681683,
-     0,
-     -0.00359077949800265,
-     0,
-     -0.00304238999373074,
-     0,
-     -0.00257141359464515,
-     0,
-     -0.00217299884412417,
-     0,
-     -0.00184260137668314,
-     0,
-     -0.00157592342822028,
-     0,
-     -0.00136886588233087,
-     0,
-     -0.00121749046405025,
-     0,
-     -0.00111799020198943,
-     0,
-     -0.00106666666666667
-  };
-#endif
-
-#ifdef HILBERT360
-
-// blFIR  Hilbert
-// localSamplingrate = 12000.000000
-// number of taps = 360
-// corner frequency = 8000.000000
-// beta = 1.000000
-// window applied
-//Coefficients:
-
-const FILTERPARAMTYPE hilbert[HILBERTTAPS]=
-{
-   0.000447320955694772,
-   0,
-   0.000455558927413046,
-   0,
-   0.000467201131289238,
-   0,
-   0.000482357657235191,
-   0,
-   0.000501139723312327,
-   0,
-   0.000523659757475149,
-   0,
-   0.000550031490215828,
-   0,
-   0.000580370059009746,
-   0,
-   0.000614792125543957,
-   0,
-   0.000653416006801779,
-   0,
-   0.000696361821178391,
-   0,
-   0.000743751650915635,
-   0,
-   0.000795709722270862,
-   0,
-   0.000852362604976147,
-   0,
-   0.000913839432702755,
-   0,
-   0.000980272146423472,
-   0,
-   0.00105179576276502,
-   0,
-   0.0011285486696673,
-   0,
-   0.001210672951919,
-   0,
-   0.0012983147494246,
-   0,
-   0.00139162465137996,
-   0,
-   0.00149075812989859,
-   0,
-   0.00159587601704457,
-   0,
-   0.00170714502969781,
-   0,
-   0.00182473834721175,
-   0,
-   0.00194883624743331,
-   0,
-   0.0020796268073506,
-   0,
-   0.0022173066754303,
-   0,
-   0.00236208192361964,
-   0,
-   0.00251416898803742,
-   0,
-   0.00267379570858608,
-   0,
-   0.00284120247911163,
-   0,
-   0.00301664352135053,
-   0,
-   0.00320038829777273,
-   0,
-   0.00339272308060342,
-   0,
-   0.00359395269683864,
-   0,
-   0.00380440247202873,
-   0,
-   0.00402442039907038,
-   0,
-   0.00425437956232035,
-   0,
-   0.00449468085214296,
-   0,
-   0.00474575601067502,
-   0,
-   0.0050080710563162,
-   0,
-   0.00528213014245216,
-   0,
-   0.00556847991546485,
-   0,
-   0.00586771444852104,
-   0,
-   0.00618048084138014,
-   0,
-   0.00650748559305694,
-   0,
-   0.00684950187428514,
-   0,
-   0.00720737785119832,
-   0,
-   0.00758204624155527,
-   0,
-   0.00797453532156124,
-   0,
-   0.00838598164664784,
-   0,
-   0.00881764480575967,
-   0,
-   0.00927092459873636,
-   0,
-   0.00974738111417594,
-   0,
-   0.0102487582958671,
-   0,
-   0.0107770117263209,
-   0,
-   0.0113343415352682,
-   0,
-   0.0119232315715625,
-   0,
-   0.0125464962755426,
-   0,
-   0.0132073370786259,
-   0,
-   0.0139094106696869,
-   0,
-   0.0146569121483854,
-   0,
-   0.015454676997362,
-   0,
-   0.0163083070387749,
-   0,
-   0.0172243272273486,
-   0,
-   0.0182103824647697,
-   0,
-   0.019275486886001,
-   0,
-   0.0204303427008687,
-   0,
-   0.0216877523409707,
-   0,
-   0.0230631574055806,
-   0,
-   0.0245753523839949,
-   0,
-   0.0262474430643373,
-   0,
-   0.028108153434625,
-   0,
-   0.0301936384591154,
-   0,
-   0.0325500469449935,
-   0,
-   0.0352372234345217,
-   0,
-   0.0383341869762954,
-   0,
-   0.0419474683535509,
-   0,
-   0.0462242114069099,
-   0,
-   0.0513735488362621,
-   0,
-   0.0577030667580263,
-   0,
-   0.0656844408554181,
-   0,
-   0.0760796596826624,
-   0,
-   0.0902049460455389,
-   0,
-   0.110546573465011,
-   0,
-   0.142432367889117,
-   0,
-   0.199714813347055,
-   0,
-   0.333186579940791,
-   0,
-   0.999982386895462,
-   0,
-   -0.999982386895462,
-   0,
-   -0.333186579940791,
-   0,
-   -0.199714813347055,
-   0,
-   -0.142432367889117,
-   0,
-   -0.110546573465011,
-   0,
-   -0.0902049460455389,
-   0,
-   -0.0760796596826624,
-   0,
-   -0.0656844408554181,
-   0,
-   -0.0577030667580263,
-   0,
-   -0.0513735488362621,
-   0,
-   -0.0462242114069099,
-   0,
-   -0.0419474683535509,
-   0,
-   -0.0383341869762954,
-   0,
-   -0.0352372234345217,
-   0,
-   -0.0325500469449935,
-   0,
-   -0.0301936384591154,
-   0,
-   -0.028108153434625,
-   0,
-   -0.0262474430643373,
-   0,
-   -0.0245753523839949,
-   0,
-   -0.0230631574055806,
-   0,
-   -0.0216877523409707,
-   0,
-   -0.0204303427008687,
-   0,
-   -0.019275486886001,
-   0,
-   -0.0182103824647697,
-   0,
-   -0.0172243272273486,
-   0,
-   -0.0163083070387749,
-   0,
-   -0.015454676997362,
-   0,
-   -0.0146569121483854,
-   0,
-   -0.0139094106696869,
-   0,
-   -0.0132073370786259,
-   0,
-   -0.0125464962755426,
-   0,
-   -0.0119232315715625,
-   0,
-   -0.0113343415352682,
-   0,
-   -0.0107770117263209,
-   0,
-   -0.0102487582958671,
-   0,
-   -0.00974738111417594,
-   0,
-   -0.00927092459873636,
-   0,
-   -0.00881764480575967,
-   0,
-   -0.00838598164664784,
-   0,
-   -0.00797453532156124,
-   0,
-   -0.00758204624155527,
-   0,
-   -0.00720737785119832,
-   0,
-   -0.00684950187428514,
-   0,
-   -0.00650748559305694,
-   0,
-   -0.00618048084138014,
-   0,
-   -0.00586771444852104,
-   0,
-   -0.00556847991546485,
-   0,
-   -0.00528213014245216,
-   0,
-   -0.0050080710563162,
-   0,
-   -0.00474575601067502,
-   0,
-   -0.00449468085214296,
-   0,
-   -0.00425437956232035,
-   0,
-   -0.00402442039907038,
-   0,
-   -0.00380440247202873,
-   0,
-   -0.00359395269683864,
-   0,
-   -0.00339272308060342,
-   0,
-   -0.00320038829777273,
-   0,
-   -0.00301664352135053,
-   0,
-   -0.00284120247911163,
-   0,
-   -0.00267379570858608,
-   0,
-   -0.00251416898803742,
-   0,
-   -0.00236208192361964,
-   0,
-   -0.0022173066754303,
-   0,
-   -0.0020796268073506,
-   0,
-   -0.00194883624743331,
-   0,
-   -0.00182473834721175,
-   0,
-   -0.00170714502969781,
-   0,
-   -0.00159587601704457,
-   0,
-   -0.00149075812989859,
-   0,
-   -0.00139162465137996,
-   0,
-   -0.0012983147494246,
-   0,
-   -0.001210672951919,
-   0,
-   -0.0011285486696673,
-   0,
-   -0.00105179576276502,
-   0,
-   -0.000980272146423472,
-   0,
-   -0.000913839432702755,
-   0,
-   -0.000852362604976147,
-   0,
-   -0.000795709722270862,
-   0,
-   -0.000743751650915635,
-   0,
-   -0.000696361821178391,
-   0,
-   -0.000653416006801779,
-   0,
-   -0.000614792125543957,
-   0,
-   -0.000580370059009746,
-   0,
-   -0.000550031490215828,
-   0,
-   -0.000523659757475149,
-   0,
-   -0.000501139723312327,
-   0,
-   -0.000482357657235191,
-   0,
-   -0.000467201131289238,
-   0,
-   -0.000455558927413046,
-   0,
-   -0.000447320955694772,
-   0
-};
-#endif
-
-
-//double lowpass[4*FILTERLENGTH];
-
-drmDataInput::drmDataInput(int blockSize)
-{
-  iqFilter=NULL;
-  init(blockSize);
-}
-
-drmDataInput::~drmDataInput()
-{
-//  delete downFilter;
-  delete iqFilter;
-}
-
-void drmDataInput::init(int blockSize)
-{
-
-  if(iqFilter) delete iqFilter;
-  iqFilter=new filter(0,hilbert,HILBERTTAPS,0,48000,false,1);
-  inputResampler.init(blockSize);
-  iterationCounter=0;
-}
-
-
-unsigned int drmDataInput::getData(DSPFLOAT *inputBuf,DSPFLOAT *outputBuf,DSPFLOAT rRation)
-{
-  int processedSamples;
-  inputResampler.resample(rRation,inputBuf);
-  processedSamples=inputResampler.rxBuffer.count();
-  inputResampler.rxBuffer.copy(outputBuf,processedSamples);
-  inputResampler.rxBuffer.skip(processedSamples);
-  iqFilter->processIQ(inputBuf,outputBuf,processedSamples);
-  return (processedSamples);
-}
-
-
-
diff --git a/qsstv/drmrx/drmdatainput.h b/qsstv/drmrx/drmdatainput.h
deleted file mode 100644
index 26a3b63..0000000
--- a/qsstv/drmrx/drmdatainput.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef DRMDATAINPUT_H
-#define DRMDATAINPUT_H
-#include "qsstvglobal.h"
-#include "qsstvdefs.h"
-#include "drmrx/drmdefs.h"
-#include "sound/resampler.h"
-
-#define RESAMPLINGLEN 2048
-
-class filter;
-class downsampleFilter;
-
-class drmDataInput
-{
-public:
-  drmDataInput(int blockSize);
-  ~drmDataInput();
-//  void doResample(DSPFLOAT rRation,short int *inputBuffer);
-  unsigned int getData(DSPFLOAT *inputBuf, DSPFLOAT *outputBuf, DSPFLOAT rRation);
-  void init(int blockSize);
-
-private:
-//  downsampleFilter *downFilter;
-  filter *iqFilter;
-  resampler inputResampler;
-  int iterationCounter;
-};
-
-#endif // DRMDATAINPUT_H
diff --git a/qsstv/drmrx/drmrx.cpp b/qsstv/drmrx/drmrx.cpp
new file mode 100644
index 0000000..1207e58
--- /dev/null
+++ b/qsstv/drmrx/drmrx.cpp
@@ -0,0 +1,76 @@
+#include "drmrx.h"
+#include "appglobal.h"
+#include "drm.h"
+#include "demodulator.h"
+#include "dispatcher.h"
+#include "filters.h"
+
+
+drmRx::drmRx(QObject *parent) : QObject(parent),iqFilter(RXSTRIPE)
+{
+  srcDecoder=new sourceDecoder;
+  demodulatorPtr=new demodulator;
+}
+
+drmRx::~drmRx()
+{
+  delete srcDecoder;
+}
+
+void drmRx::init()
+{
+  avgSNR=0;
+  avgSNRAvailable=false;
+  n = DRMBUFSIZE;
+  /* initialisations */
+  demodulatorPtr->init();
+  initGetmode( n / 4);
+  rRation = 1.000;
+  samplerate_offset_estimation = 0.0;
+  runstate = RUN_STATE_POWER_ON;		/* POWER_ON */
+  channel_decoding();
+  runstate = RUN_STATE_INIT;		/* INIT */
+  channel_decoding();
+  runstate = RUN_STATE_FIRST;			/* FIRSTRUN */
+  runstate = RUN_STATE_NORMAL;			/* NORMAL RUN */
+  srcDecoder->init();
+}
+
+
+
+void drmRx::run(DSPFLOAT *dataPtr)
+{
+  bool done=false;
+  DSPFLOAT temp;
+  displayDRMStatEvent *ce1;
+  displayDRMInfoEvent *ce2 ;
+
+  temp=WMERFAC;
+  if(temp<0) temp=0;
+  if(avgSNRAvailable)
+    {
+      avgSNR=(1-0.05)*avgSNR+0.05*temp;
+      ce1 = new displayDRMStatEvent(avgSNR);
+      ce1->waitFor(&done);
+      QApplication::postEvent(dispatcherPtr, ce1);
+      while(!done) { usleep(10);}
+
+    }
+
+ if(input_samples_buffer_request ==0)
+    {
+      demodulatorPtr->demodulate(resamp_signal,0);
+    }
+  iqFilter.process(dataPtr,resamp_signal,RXSTRIPE);
+  im=RXSTRIPE;
+
+  demodulatorPtr->demodulate(resamp_signal,im);
+
+  done=false;
+  ce2 = new displayDRMInfoEvent;
+  ce2->waitFor(&done);
+  QApplication::postEvent(dispatcherPtr, ce2);
+  while(!done) { usleep(10);}
+
+}
+
diff --git a/qsstv/drmrx/drmrx.h b/qsstv/drmrx/drmrx.h
new file mode 100644
index 0000000..98493da
--- /dev/null
+++ b/qsstv/drmrx/drmrx.h
@@ -0,0 +1,32 @@
+#ifndef DRMRX_H
+#define DRMRX_H
+
+#include <QObject>
+#include "appdefs.h"
+#include "drmdefs.h"
+#include "filters.h"
+
+
+class drmRx : public QObject
+{
+  Q_OBJECT
+public:
+  explicit drmRx(QObject *parent = 0);
+  ~drmRx();
+  void init();
+  void run(DSPFLOAT *dataPtr);
+  void eraseImage(){}
+
+signals:
+
+public slots:
+  private:
+  int n,im;
+  float rRation;
+  float resamp_signal[2 * DRMBUFSIZE];
+  drmHilbertFilter iqFilter;
+
+
+};
+
+#endif // DRMRX_H
diff --git a/qsstv/drmrx/drmstatusframe.cpp b/qsstv/drmrx/drmstatusframe.cpp
index cfa209e..47e3c52 100644
--- a/qsstv/drmrx/drmstatusframe.cpp
+++ b/qsstv/drmrx/drmstatusframe.cpp
@@ -1,7 +1,6 @@
 #include "drmstatusframe.h"
 #include "ui_drmstatusframe.h"
-#include "drm.h"
-#include "qsstvglobal.h"
+#include "appglobal.h"
 #include "drmrx/demodulator.h"
 #include <math.h>
 #include "configparams.h"
@@ -32,58 +31,89 @@ void drmStatusFrame::init()
   interleave="";
   protection="";
   qam=0;
-  call="";
-  currentSegment=0;
-  transportID=0;
-  totalSeg=0;
-  rxSeg=0;
+  call.clear();
   ui->mscLED->setPixmap(*redPXM);
   ui->facLED->setPixmap(*redPXM);
   ui->frameLED->setPixmap(*redPXM);
   ui->timeLED->setPixmap(*redPXM);
-}
 
-void drmStatusFrame::paintEvent (QPaintEvent *)
-{
-  int freqOff;
-  ui->modeEdit->setText(mode);
-  ui->bandwidthEdit->setText(QString::number(bandwidth));
-  ui->interleaveEdit->setText(interleave);
-  ui->protectionEdit->setText(protection);
-  ui->qamEdit->setText(QString::number(qam));
-  ui->snrEdit->setText(QString::number(WMERFAC,'g',2)+" dB");
-  freqOff=(int)round(freqOffset-350);
-  ui->offsetEdit->setText(QString::number(freqOff)+" Hz");
-  //  ui->dfsEdit->setText(QString::number(deltaFS,'g',3) + " ppm");
-  ui->totalSegmentsEdit->setText(QString::number(totalSeg));
-  ui->blocksReceivedFrame->setMaxBlocks(totalSeg);
-  ui->rxSegmentsEdit->setText(QString::number(rxSeg));
-  ui->callEdit->setText(call.toUpper());
-  ui->transportIDEdit->setText(QString::number(transportID));
-  ui->currentSegmentEdit->setText(QString::number(currentSegment));
-  ui->blocksReceivedFrame->setBlocks(drmBlockList);
+  prevTimeSync=false;
+  prevFacValid=0;
+  prevFrameSync=false;
+  prevMscValid=INVALID;
+  prevCurrentSegment=-1;
+  prevTransportID=0;
+  prevRxSeg=-1;
+  prevRobustnessMode=-1;
+  QString prevCall="";
+  prevSspectrumOccupancy=-1;
+  prevProtection=-1;
+  prevInterleaverDepth=-1;
+  prevMscMode=-1;
+  prevBodyTotalSegments=-1;
+  prevWMERFAC=-9999;
+  prevFreqOff=-9999;
+  prevBlockCount=-1;
 }
 
+
+
+
 void drmStatusFrame::setStatus()
 {
+  bool tmp;
 
-  if(demodulatorPtr->isTimeSync())
+  tmp=demodulatorPtr->isTimeSync();
+  if(tmp!=prevTimeSync)
     {
-      ui->timeLED->setPixmap(*greenPXM);
+      prevTimeSync=tmp;
+      if(prevTimeSync)
+        {
+          ui->timeLED->setPixmap(*greenPXM);
+        }
+      else
+        {
+          ui->timeLED->setPixmap(*redPXM);
+          if(prevFacValid) ui->facLED->setPixmap(*redPXM);
+          if(prevFrameSync) ui->frameLED->setPixmap(*redPXM);
+          if(prevMscValid!=INVALID) ui->mscLED->setPixmap(*redPXM);
+          prevFacValid=0;
+          prevFrameSync=false;
+          prevMscValid=INVALID;
+          return;
+        }
     }
-  else
+  tmp=demodulatorPtr->isFrameSync();
+  if(tmp!=prevFrameSync)
     {
-      ui->timeLED->setPixmap(*redPXM);
-      ui->facLED->setPixmap(*redPXM);
-      ui->frameLED->setPixmap(*redPXM);
-      ui->mscLED->setPixmap(*redPXM);
-      // update();
-      return;
+      prevFrameSync=tmp;
+      if(tmp)  ui->frameLED->setPixmap(*greenPXM);
+      else
+        {
+          ui->frameLED->setPixmap(*redPXM);
+          if(prevFacValid==1) ui->facLED->setPixmap(*redPXM);
+          if(prevMscValid!=INVALID) ui->mscLED->setPixmap(*redPXM);
+          prevFacValid=0;
+          prevMscValid=INVALID;
+          return;
+        }
     }
-  currentSegment=currentSegmentNumber;
-  transportID=rxTransportID;
-  totalSeg=bodyTotalSegments;
-  rxSeg=rxSegments;
+
+
+  if(prevFacValid!=fac_valid)
+    {
+      prevFacValid=fac_valid;
+      if(fac_valid==1)  ui->facLED->setPixmap(*greenPXM);
+      else
+        {
+          ui->facLED->setPixmap(*redPXM);
+          if(prevMscValid!=INVALID) ui->mscLED->setPixmap(*redPXM);
+          prevMscValid=INVALID;
+          return;
+        }
+    }
+
+
   switch(robustness_mode)
     {
     case 0: mode="A"; break;
@@ -91,74 +121,125 @@ void drmStatusFrame::setStatus()
     case 2: mode="E"; break;
     default: mode=""; break;
     }
+  if(mode=="") return;
+  if(prevRobustnessMode!=robustness_mode)
+    {
+      prevRobustnessMode=robustness_mode;
+      ui->modeEdit->setText(mode);
+    }
+
   if(callsignValid)
     {
       call=drmCallsign;
+      if(prevCall!=call)
+        {
+          prevCall=call;
+          ui->callEdit->setText(call);
+          lastReceivedCall=call;
+        }
     }
 
-  if(fac_valid==1)
+  if(prevMscValid!=msc_valid)
     {
-      ui->facLED->setPixmap(*greenPXM);
+      prevMscValid=msc_valid;
+      switch(msc_valid)
+        {
+
+        case INVALID:  ui->mscLED->setPixmap(*redPXM); break;
+        case VALID: ui->mscLED->setPixmap(*greenPXM); break;
+        case ALREADYRECEIVED: ui->mscLED->setPixmap(*yellowPXM); break;
+        }
     }
-  else
+
+  if(prevSspectrumOccupancy!=spectrum_occupancy_new)
     {
-      ui->facLED->setPixmap(*redPXM);
+      prevSspectrumOccupancy=spectrum_occupancy_new;
+      switch(spectrum_occupancy_new)
+        {
+        case 0: bandwidth=2.3; break;
+        case 1: bandwidth=2.5;; break;
+        default:bandwidth=0; break;
+        }
+      ui->bandwidthEdit->setText(QString::number(bandwidth));
     }
 
-  switch(msc_valid)
-    {
 
-    case INVALID:  ui->mscLED->setPixmap(*redPXM); break;
-    case VALID: ui->mscLED->setPixmap(*greenPXM); break;
-    case ALREADYRECEIVED: ui->mscLED->setPixmap(*yellowPXM); break;
+  if(prevProtection!=multiplex_description.PL_PartB)
+    {
+      prevProtection=multiplex_description.PL_PartB;
+      switch (multiplex_description.PL_PartB)
+        {
+        case 0: protection="High"; break;
+        case 1: protection="Low"; break;
+        default: ; break;
+        }
+      ui->protectionEdit->setText(protection);
     }
-  if(demodulatorPtr->isFrameSync())
+  if(prevInterleaverDepth!=interleaver_depth_new)
     {
-      ui->frameLED->setPixmap(*greenPXM);
+      prevInterleaverDepth=interleaver_depth_new;
+      switch(interleaver_depth_new)
+        {
+        case 0: interleave="Long"; break;
+        case 1: interleave="Short"; break;
+        default: ; break;
+        }
+      ui->interleaveEdit->setText(interleave);
     }
-  else
+
+
+  if(prevMscMode!=msc_mode_new)
     {
-      ui->frameLED->setPixmap(*redPXM);
+      prevMscMode=msc_mode_new;
+      switch(msc_mode_new)
+        {
+        case 0: qam=64; break;
+        case 1: qam=16; break;
+        case 3: qam=4; break;
+        default: qam=0; break;
+        }
+      ui->qamEdit->setText(QString::number(qam));
     }
-  if(demodulatorPtr->isTimeSync())
+
+  if(prevRxSeg!=rxSegments)
     {
-      ui->timeLED->setPixmap(*greenPXM);
+      prevRxSeg=rxSegments;
+      ui->rxSegmentsEdit->setText(QString::number(rxSegments));
     }
-  else
+  int tempWMERFAC =round(WMERFAC);
+  if(prevWMERFAC!=tempWMERFAC)
     {
-      ui->timeLED->setPixmap(*redPXM);
+      prevWMERFAC=tempWMERFAC;
+      ui->snrEdit->setText(QString::number(prevWMERFAC)+" dB");
     }
-
-  if(mode=="") return;
-  switch(spectrum_occupancy_new)
+  if(prevFreqOff!=((int)round(freqOffset-350)))
     {
-    case 0: bandwidth=2.3; break;
-    case 1: bandwidth=2.5;; break;
-    default:bandwidth=0; break;
+      prevFreqOff=((int)round(freqOffset-350));
+      ui->offsetEdit->setText(QString::number(prevFreqOff)+" Hz");
     }
-  switch (multiplex_description.PL_PartB)
+  if(prevBodyTotalSegments!=bodyTotalSegments)
     {
-    case 0: protection="High"; break;
-    case 1: protection="Low"; break;
-    default: ; break;
+      prevBodyTotalSegments=bodyTotalSegments;
+      ui->totalSegmentsEdit->setText(QString::number(bodyTotalSegments));
+      ui->blocksReceivedLabel->setMaxBlocks(bodyTotalSegments);
     }
-  switch(interleaver_depth_new)
+  if(prevTransportID!=rxTransportID)
     {
-    case 0: interleave="Long"; break;
-    case 1: interleave="Short"; break;
-    default: ; break;
+      prevTransportID=rxTransportID;
+      ui->transportIDEdit->setText(QString::number(prevTransportID));
     }
 
-  switch(msc_mode_new)
+  if(prevCurrentSegment!=currentSegmentNumber)
+    {
+      prevCurrentSegment=currentSegmentNumber;
+      ui->currentSegmentEdit->setText(QString::number(prevCurrentSegment));
+    }
+  if(prevBlockCount!=drmBlockList.count())
     {
-    case 0: qam=64; break;
-    case 1: qam=16; break;
-    case 3: qam=4; break;
-    default: qam=0; break;
+      prevBlockCount=drmBlockList.count();
+      ui->blocksReceivedLabel->setBlocks(drmBlockList);
     }
-  ui->totalSegmentsEdit->setText(QString::number(bodyTotalSegments));
-  ui->rxSegmentsEdit->setText(QString::number(rxSegments));
-  update();
+
 }
 
 
@@ -246,8 +327,6 @@ QString compactModeToString(uint mode)
     case 1: tmp+="Short"; break;
     default:tmp+="--" ; break;
     }
-
-
   return tmp;
 }
 
diff --git a/qsstv/drmrx/drmstatusframe.h b/qsstv/drmrx/drmstatusframe.h
index d1119ff..496af37 100644
--- a/qsstv/drmrx/drmstatusframe.h
+++ b/qsstv/drmrx/drmstatusframe.h
@@ -1,5 +1,6 @@
 #ifndef DRMSTATUSFRAME_H
 #define DRMSTATUSFRAME_H
+#include "drm.h"
 
 #include <QFrame>
 #include <QPixmap>
@@ -22,20 +23,39 @@ public:
 
 private:
   Ui::drmStatusFrame *ui;
-  void paintEvent (QPaintEvent *);
+  QString call;
+//  void paintEvent (QPaintEvent *e);
   QString mode;
   float bandwidth;
   QString interleave;
   QString protection;
   int qam;
-  QString call;
+
   QPixmap *greenPXM;
   QPixmap *redPXM;
   QPixmap *yellowPXM;
-  int currentSegment;
-  int transportID;
-  int totalSeg;
-  int rxSeg;
+
+  bool prevTimeSync;
+  int prevFacValid;
+  bool prevFrameSync;
+  emscStatus prevMscValid;
+  int prevCurrentSegment;
+  uint prevTransportID;
+  int prevRxSeg;
+  int prevRobustnessMode;
+  QString prevCall;
+  int prevSspectrumOccupancy;
+  int prevProtection;
+  int prevInterleaverDepth;
+  int prevMscMode;
+  int prevBodyTotalSegments;
+  float prevWMERFAC;
+  int prevFreqOff;
+  int prevBlockCount;
+
+
+
+
 };
 
 QString modeToString(uint mode);
diff --git a/qsstv/drmrx/drmstatusframe.ui b/qsstv/drmrx/drmstatusframe.ui
index 63e38aa..fe9db29 100644
--- a/qsstv/drmrx/drmstatusframe.ui
+++ b/qsstv/drmrx/drmstatusframe.ui
@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>415</width>
-    <height>399</height>
+    <width>410</width>
+    <height>581</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -21,41 +21,55 @@
   </property>
   <layout class="QVBoxLayout" name="verticalLayout">
    <property name="spacing">
-    <number>2</number>
-   </property>
-   <property name="margin">
     <number>1</number>
    </property>
+   <property name="leftMargin">
+    <number>0</number>
+   </property>
+   <property name="topMargin">
+    <number>0</number>
+   </property>
+   <property name="rightMargin">
+    <number>0</number>
+   </property>
+   <property name="bottomMargin">
+    <number>0</number>
+   </property>
    <item>
     <layout class="QGridLayout" name="gridLayout">
-     <item row="3" column="1">
-      <widget class="QLabel" name="protectionEdit">
-       <property name="minimumSize">
-        <size>
-         <width>40</width>
-         <height>0</height>
-        </size>
+     <property name="spacing">
+      <number>1</number>
+     </property>
+     <item row="1" column="0">
+      <widget class="QLabel" name="bandwidthLabel">
+       <property name="text">
+        <string>Bandwidth</string>
        </property>
+      </widget>
+     </item>
+     <item row="3" column="0">
+      <widget class="QLabel" name="protectionLabel">
        <property name="text">
-        <string/>
+        <string>Protection</string>
        </property>
       </widget>
      </item>
-     <item row="2" column="3">
-      <widget class="QLabel" name="rxSegmentsEdit">
-       <property name="minimumSize">
-        <size>
-         <width>40</width>
-         <height>0</height>
-        </size>
+     <item row="2" column="0">
+      <widget class="QLabel" name="interleaveLabel">
+       <property name="text">
+        <string>InterLeave</string>
        </property>
+      </widget>
+     </item>
+     <item row="4" column="0">
+      <widget class="QLabel" name="qamLabel">
        <property name="text">
-        <string/>
+        <string>QAM</string>
        </property>
       </widget>
      </item>
-     <item row="0" column="3">
-      <widget class="QLabel" name="offsetEdit">
+     <item row="8" column="1">
+      <widget class="QLabel" name="rxSegmentsEdit">
        <property name="minimumSize">
         <size>
          <width>40</width>
@@ -67,22 +81,15 @@
        </property>
       </widget>
      </item>
-     <item row="5" column="0">
-      <widget class="QLabel" name="snrLabel">
-       <property name="text">
-        <string>SNR</string>
-       </property>
-      </widget>
-     </item>
-     <item row="1" column="0">
-      <widget class="QLabel" name="bandwidthLabel">
+     <item row="8" column="0">
+      <widget class="QLabel" name="rxSegmentsLabel">
        <property name="text">
-        <string>Bandwidth</string>
+        <string>RX  Sgmnts</string>
        </property>
       </widget>
      </item>
-     <item row="1" column="3">
-      <widget class="QLabel" name="totalSegmentsEdit">
+     <item row="1" column="1">
+      <widget class="QLabel" name="bandwidthEdit">
        <property name="minimumSize">
         <size>
          <width>40</width>
@@ -94,22 +101,22 @@
        </property>
       </widget>
      </item>
-     <item row="1" column="2">
-      <widget class="QLabel" name="totalSegmentsLabel">
+     <item row="6" column="0">
+      <widget class="QLabel" name="offsetLabel">
        <property name="text">
-        <string>Total Segm.</string>
+        <string>Offset</string>
        </property>
       </widget>
      </item>
-     <item row="2" column="2">
-      <widget class="QLabel" name="rxSegmentsLabel">
+     <item row="0" column="0">
+      <widget class="QLabel" name="modeLabel">
        <property name="text">
-        <string>RX  Sgmnts</string>
+        <string>Mode</string>
        </property>
       </widget>
      </item>
-     <item row="5" column="1">
-      <widget class="QLabel" name="snrEdit">
+     <item row="0" column="1">
+      <widget class="QLabel" name="modeEdit">
        <property name="minimumSize">
         <size>
          <width>40</width>
@@ -121,8 +128,8 @@
        </property>
       </widget>
      </item>
-     <item row="1" column="1">
-      <widget class="QLabel" name="bandwidthEdit">
+     <item row="5" column="1">
+      <widget class="QLabel" name="snrEdit">
        <property name="minimumSize">
         <size>
          <width>40</width>
@@ -147,21 +154,15 @@
        </property>
       </widget>
      </item>
-     <item row="2" column="1">
-      <widget class="QLabel" name="interleaveEdit">
-       <property name="minimumSize">
-        <size>
-         <width>40</width>
-         <height>0</height>
-        </size>
-       </property>
+     <item row="5" column="0">
+      <widget class="QLabel" name="snrLabel">
        <property name="text">
-        <string/>
+        <string>SNR</string>
        </property>
       </widget>
      </item>
-     <item row="3" column="3">
-      <widget class="QLabel" name="currentSegmentEdit">
+     <item row="3" column="1">
+      <widget class="QLabel" name="protectionEdit">
        <property name="minimumSize">
         <size>
          <width>40</width>
@@ -173,22 +174,28 @@
        </property>
       </widget>
      </item>
-     <item row="2" column="0">
-      <widget class="QLabel" name="interleaveLabel">
+     <item row="7" column="0">
+      <widget class="QLabel" name="totalSegmentsLabel">
        <property name="text">
-        <string>InterLeave</string>
+        <string>Total Segm.</string>
        </property>
       </widget>
      </item>
-     <item row="3" column="0">
-      <widget class="QLabel" name="protectionLabel">
+     <item row="2" column="1">
+      <widget class="QLabel" name="interleaveEdit">
+       <property name="minimumSize">
+        <size>
+         <width>40</width>
+         <height>0</height>
+        </size>
+       </property>
        <property name="text">
-        <string>Protection</string>
+        <string/>
        </property>
       </widget>
      </item>
-     <item row="4" column="3">
-      <widget class="QLabel" name="transportIDEdit">
+     <item row="7" column="1">
+      <widget class="QLabel" name="totalSegmentsEdit">
        <property name="minimumSize">
         <size>
          <width>40</width>
@@ -200,8 +207,8 @@
        </property>
       </widget>
      </item>
-     <item row="0" column="1">
-      <widget class="QLabel" name="modeEdit">
+     <item row="6" column="1">
+      <widget class="QLabel" name="offsetEdit">
        <property name="minimumSize">
         <size>
          <width>40</width>
@@ -213,49 +220,54 @@
        </property>
       </widget>
      </item>
-     <item row="0" column="2">
-      <widget class="QLabel" name="offsetLabel">
+     <item row="9" column="0">
+      <widget class="QLabel" name="curSegmentLabel">
        <property name="text">
-        <string>Offset</string>
+        <string>Cur. Sgmnt</string>
        </property>
       </widget>
      </item>
-     <item row="0" column="0">
-      <widget class="QLabel" name="modeLabel">
-       <property name="text">
-        <string>Mode</string>
+     <item row="9" column="1">
+      <widget class="QLabel" name="currentSegmentEdit">
+       <property name="minimumSize">
+        <size>
+         <width>40</width>
+         <height>0</height>
+        </size>
        </property>
-      </widget>
-     </item>
-     <item row="4" column="0">
-      <widget class="QLabel" name="qamLabel">
        <property name="text">
-        <string>QAM</string>
+        <string/>
        </property>
       </widget>
      </item>
-     <item row="3" column="2">
-      <widget class="QLabel" name="curSegmentLabel">
+     <item row="10" column="1">
+      <widget class="QLabel" name="transportIDEdit">
+       <property name="minimumSize">
+        <size>
+         <width>40</width>
+         <height>0</height>
+        </size>
+       </property>
        <property name="text">
-        <string>Cur. Sgmnt</string>
+        <string/>
        </property>
       </widget>
      </item>
-     <item row="4" column="2">
+     <item row="10" column="0">
       <widget class="QLabel" name="transportIDLabel">
        <property name="text">
         <string>Transp. ID</string>
        </property>
       </widget>
      </item>
-     <item row="5" column="2">
+     <item row="11" column="0">
       <widget class="QLabel" name="callsignLabel">
        <property name="text">
         <string>Callsign</string>
        </property>
       </widget>
      </item>
-     <item row="5" column="3">
+     <item row="11" column="1">
       <widget class="QLabel" name="callEdit">
        <property name="font">
         <font>
@@ -275,21 +287,12 @@
     </layout>
    </item>
    <item>
-    <widget class="blockView" name="blocksReceivedFrame">
-     <property name="minimumSize">
-      <size>
-       <width>0</width>
-       <height>18</height>
-      </size>
-     </property>
-     <property name="frameShape">
-      <enum>QFrame::StyledPanel</enum>
-     </property>
-     <property name="frameShadow">
-      <enum>QFrame::Sunken</enum>
+    <widget class="drmSegmentsView" name="blocksReceivedLabel">
+     <property name="autoFillBackground">
+      <bool>false</bool>
      </property>
-     <property name="lineWidth">
-      <number>3</number>
+     <property name="text">
+      <string/>
      </property>
     </widget>
    </item>
@@ -1146,10 +1149,9 @@
  </widget>
  <customwidgets>
   <customwidget>
-   <class>blockView</class>
-   <extends>QFrame</extends>
-   <header>widgets/blockview.h</header>
-   <container>1</container>
+   <class>drmSegmentsView</class>
+   <extends>QLabel</extends>
+   <header>drmsegmentsview.h</header>
   </customwidget>
  </customwidgets>
  <resources/>
diff --git a/qsstv/drmrx/fixform.cpp b/qsstv/drmrx/fixform.cpp
index f0681bf..a7a4d6d 100644
--- a/qsstv/drmrx/fixform.cpp
+++ b/qsstv/drmrx/fixform.cpp
@@ -1,7 +1,7 @@
 #include "fixform.h"
 #include "ui_fixform.h"
 #include "drmstatusframe.h"
-#include "qsstvglobal.h"
+#include "appglobal.h"
 #include "drmrx/drm.h"
 #include "configparams.h"
 
@@ -29,7 +29,7 @@ void fixForm::setInfoExternal(int mode, QString fileName, int missing)
 {
   common(mode,fileName,missing);
   ui->infoTextEdit->appendPlainText("BSR for a picture you received");
-  ui->previewWidget->openImage(fileName,false,false);
+  ui->previewWidget->openImage(fileName,false,false,false);
 }
 
 void fixForm::common(int mode,QString fileName,int missing)
diff --git a/qsstv/drmrx/fixform.ui b/qsstv/drmrx/fixform.ui
index be1f804..a0937e8 100644
--- a/qsstv/drmrx/fixform.ui
+++ b/qsstv/drmrx/fixform.ui
@@ -41,21 +41,9 @@
     </layout>
    </item>
    <item>
-    <widget class="blockView" name="blocksReceivedFrame">
-     <property name="minimumSize">
-      <size>
-       <width>0</width>
-       <height>18</height>
-      </size>
-     </property>
-     <property name="frameShape">
-      <enum>QFrame::StyledPanel</enum>
-     </property>
-     <property name="frameShadow">
-      <enum>QFrame::Sunken</enum>
-     </property>
-     <property name="lineWidth">
-      <number>3</number>
+    <widget class="drmSegmentsView" name="label">
+     <property name="text">
+      <string/>
      </property>
     </widget>
    </item>
@@ -107,17 +95,16 @@
  </widget>
  <customwidgets>
   <customwidget>
-   <class>blockView</class>
-   <extends>QFrame</extends>
-   <header>widgets/blockview.h</header>
-   <container>1</container>
-  </customwidget>
-  <customwidget>
    <class>imageViewer</class>
    <extends>QWidget</extends>
    <header>widgets/imageviewer.h</header>
    <container>1</container>
   </customwidget>
+  <customwidget>
+   <class>drmSegmentsView</class>
+   <extends>QLabel</extends>
+   <header>drmsegmentsview.h</header>
+  </customwidget>
  </customwidgets>
  <resources/>
  <connections>
diff --git a/qsstv/drmrx/getmode.cpp b/qsstv/drmrx/getmode.cpp
index fd266bf..c0a00ce 100644
--- a/qsstv/drmrx/getmode.cpp
+++ b/qsstv/drmrx/getmode.cpp
@@ -38,7 +38,7 @@
 #include "structtemplates.h"
 #include "drmproto.h"
 #include "drmdefs.h"
-#include "qsstvglobal.h"
+#include "appglobal.h"
 #include "utils/supportfunctions.h"
 
 static /*@only@ */ float *in_, *abs_in_, *abs_in_in_;
diff --git a/qsstv/drmrx/getofdm.cpp b/qsstv/drmrx/getofdm.cpp
index ceaa25b..e1a3781 100644
--- a/qsstv/drmrx/getofdm.cpp
+++ b/qsstv/drmrx/getofdm.cpp
@@ -32,7 +32,7 @@
 #include <math.h>
 #include <fftw3.h>
 #include "drmproto.h"
-#include "qsstvglobal.h"
+#include "appglobal.h"
 
 #define PI (atan(1.0)*4.0)
 int getofdm( /*@null@ */ float *rs, float time_offset_fractional_init,
diff --git a/qsstv/drmrx/getofdmsync.cpp b/qsstv/drmrx/getofdmsync.cpp
index a78cca8..f4a1f02 100644
--- a/qsstv/drmrx/getofdmsync.cpp
+++ b/qsstv/drmrx/getofdmsync.cpp
@@ -31,7 +31,7 @@
 #include <math.h>
 #include <fftw3.h>
 #include "drmproto.h"
-#include "qsstvglobal.h"
+#include "appglobal.h"
 #include "utils/supportfunctions.h"
 
 extern int FREQ_SYNC_ENABLE;
@@ -39,27 +39,34 @@ extern int FREQ_SYNC_ENABLE;
 
 #define PI (atan(1.0)*4.0)
 void filter1(float *, float *, float *, int, int);
-int
-getofdmsync( /*@null@ */ float *rs, int Ts, int Tu, /*@null@ */ float *H,
+
+static int Tg, Tgh;
+static int Tc;
+static int Tgs, Tgsh;
+static float kP_small_timing_controller = 0.0005;
+static float kP_large_timing_controller = 0.003;	/* pa0mbo was 0.01 */
+static float threshold_timing_small_large = 2.0;	/* was 2.0 */
+static float kI_timing_controller = 0.000020;	/* was 0.00005 */
+static drmComplex s[512], S[512];
+static drmComplex s1[512], S1[512];
+static fftwf_plan p1=NULL;
+static fftwf_plan p2=NULL;
+static float /*@only@ */ *exp_temp=NULL;
+static float /*@only@ */ *out1=NULL;
+
+
+int getofdmsync( /*@null@ */ float *rs, int Ts, int Tu, /*@null@ */ float *H,
              int lH,
              float delta_freq_offset, /*@null@ */ float *Zi, /*@null@ */
              float *out, int init,
              int TIME_SYNC_ENABLE, int FREQ_SYNC_ENABLE)
 {
-  static int Tg, Tgh;
-  static int Tc;
-  static int Tgs, Tgsh;
-  static float kP_small_timing_controller = 0.0005;
-  static float kP_large_timing_controller = 0.003;	/* pa0mbo was 0.01 */
-  static float threshold_timing_small_large = 2.0;	/* was 2.0 */
-  static float kI_timing_controller = 0.000020;	/* was 0.00005 */
+
   int max_delta_theta;
   int max_delta_time_offset_integer = 3;
   int max_symbol_position_offset;
 
-  static drmComplex s[512], S[512];
-  static drmComplex s1[512], S1[512];
-  static fftwf_plan p1, p2;
+
   float h_absq[512];		/* 2 x max el */
   static float sinfilter[256];	/* too long */
   float h_absq_filtered[512];
@@ -67,8 +74,7 @@ getofdmsync( /*@null@ */ float *rs, int Ts, int Tu, /*@null@ */ float *H,
   float delta_theta, delta_theta_tmp;
   int dftmp, symbol_position_offset, spotmp;
   float freq_offset_ctrl;
-  static float /*@only@ */ *exp_temp;
-  static float /*@only@ */ *out1;
+
   int i;
   float kP_freq_controller;
 //  float *pinput;
@@ -94,6 +100,9 @@ getofdmsync( /*@null@ */ float *rs, int Ts, int Tu, /*@null@ */ float *H,
       /* printf("Tg %d, Tgh %d, Tc %d,Tu %d,  Tgs %d, Tgsh %d\n",
          Tg, Tgh, Tc, Tu, Tgs, Tgsh);   */
       /* malloc space for arrays */
+      if(exp_temp!=NULL) free(exp_temp);
+      if(out1!=NULL) free(out1);
+
       if ((exp_temp = (float *)malloc((Tu * 2 + 2) * sizeof(float))) == NULL)
 
         {
@@ -106,11 +115,19 @@ getofdmsync( /*@null@ */ float *rs, int Ts, int Tu, /*@null@ */ float *H,
           printf("cannot malloc space for out1 in get_ofdm_symbol\n");
           exit(EXIT_FAILURE);
         }
-      if (p1 != NULL) fftwf_destroy_plan(p1);
-      if (p2 != NULL) fftwf_destroy_plan(p2);
+      addToLog("syn 1",LOGPERFORM);
+      if (p1 != NULL)
+        {
+          fftwf_destroy_plan(p1);
+        }
+      if (p2 != NULL)
+        {
+          fftwf_destroy_plan(p2);
+        }
       p1 = fftwf_plan_dft_1d(Tc,(fftwf_complex *)s,(fftwf_complex *)S,FFTW_FORWARD, FFTW_PATIENT);
+       addToLog("syn 2",LOGPERFORM);
       p2 = fftwf_plan_dft_1d(Tu,(fftwf_complex *)s1,(fftwf_complex *)S1, FFTW_FORWARD, FFTW_PATIENT);
-
+       addToLog("syn 3",LOGPERFORM);
 
       /*      printf("xxxx sinfilter\n");   */
       for (i = 0; i < Tgs; i++)
diff --git a/qsstv/drmrx/hybridcrypt.cpp b/qsstv/drmrx/hybridcrypt.cpp
deleted file mode 100644
index f94045a..0000000
--- a/qsstv/drmrx/hybridcrypt.cpp
+++ /dev/null
@@ -1,135 +0,0 @@
-#include "hybridcrypt.h"
-#include <QDebug>
-#include "configparams.h"
-#include "QResource"
-
-
-
-hybridCrypt::hybridCrypt()
-{
-  const uchar *d;
-  QResource qrc(":/icons/mgc.raw");
-  d=qrc.data();
-  key1=d[32]-0x36;
-  key2=d[33]-0x72;
-  key3=d[34]-0xd8;
-  key4=d[35]-0xFE;
-}
-
-
-bool hybridCrypt::deCrypt(QByteArray *ba, QString &result)
-{
-  int baSize;
-  bool ok;
-  int charCount=0;
-  QString tempStr="0x00";
-  short int bufI, bufI2, divzr, num1, num2, num3, num4, res1, res2, res3, res4;
-  QString bufS, hexa, hexa1, hexa2;
-  unsigned char r1,r2;
-  result="";
-  res1=res2=res3=res4=0;
-  divzr=key1*key4;
-  bufI2=key3*key2;
-  divzr-=bufI2;
-  if(divzr==0) return FALSE;
-  baSize=ba->size()-2; //drop /r/n
-  if(baSize<20)
-    {
-      hcFtpRemoteHost=hybridFtpRemoteHost;
-      hcFtpLogin=hybridFtpLogin;
-      hcFtpPassword=hybridFtpPassword;
-      hcFtpRemoteDirectory=hybridFtpRemoteDirectory2;
-      return TRUE;
-    }
-  do
-    {
-      for(bufI=0;bufI<4;bufI++,charCount+=2)
-        {
-          r1=ba->at(charCount);
-          r2=ba->at(charCount+1);
-          if(r1==0xFF)
-            {
-              r1=r2=0;
-            }
-          if(r1==0xFE)
-            {
-              r1=0;
-            }
-          if(r1==0xFD)
-            {
-              r1=r2;
-              r2=0;
-            }
-          switch(bufI)
-            {
-            case 0: res1=r1*256+r2; break;
-            case 1: res2=r1*256+r2; break;
-            case 2: res3=r1*256+r2; break;
-            case 3: res4=r1*256+r2; break;
-            }
-        }
-
-      bufI= res1 * key4;
-      bufI2= res2 * key3;
-      num1= bufI - bufI2;
-      num1= num1 / divzr;
-      bufI= res2 * key1;
-      bufI2= res1 * key2;
-      num2= bufI - bufI2;
-      num2 = num2 / divzr;
-      bufI= res3 * key4;
-      bufI2= res4 * key3;
-      num3= bufI - bufI2;
-      num3= num3 / divzr;
-      bufI= res4 * key1;
-      bufI2= res3 * key2;
-      num4= bufI - bufI2;
-      num4= num4 / divzr;
-      tempStr[2]=QChar(num1);
-      tempStr[3]=QChar(num2);
-      result.append(QChar(tempStr.toInt(&ok,16)));
-      tempStr[2]=QChar(num3);
-      tempStr[3]=QChar(num4);
-      result.append(QChar(tempStr.toInt(&ok,16)));
-    }
-  while(charCount<baSize);
-  reverseString(result);
-  getParam(result);
-  return TRUE;
-}
-
-
-void hybridCrypt::reverseString(QString & s)
-{
-  int i,j;
-  QString t;
-  for (i=0,j=s.length()-1;i<s.length();i++,j--)
-    {
-      t[j]=s[i];
-    }
-  s=t;
-}
-
-bool hybridCrypt::getParam(QString result)
-{
-  int a,b,c,d,e;
-  a=result.indexOf(QChar(63));
-  b=result.indexOf(QChar(34),a+1);
-  c=result.indexOf(QChar(60),b+1);
-  d=result.indexOf(QChar(62),c+1);
-  e=result.indexOf(QChar(58),d+1);
-  hcFtpRemoteHost=result.mid(a+1,b-a-1);
-  hcFtpLogin=result.mid(b+1,c-b-1);
-  hcFtpPassword=result.mid(c+1,d-c-1);
-  hcFtpRemoteDirectory=result.mid(d+1,e-d-1);
-  if(hcFtpRemoteDirectory.isEmpty())
-    {
-      hcFtpRemoteDirectory="HybridFiles";
-    }
-  return TRUE;
-}
-
-
-
-
-
diff --git a/qsstv/drmrx/sourcedecoder.cpp b/qsstv/drmrx/sourcedecoder.cpp
index 166eb60..6c9ab1f 100644
--- a/qsstv/drmrx/sourcedecoder.cpp
+++ b/qsstv/drmrx/sourcedecoder.cpp
@@ -1,11 +1,11 @@
 #include "sourcedecoder.h"
 #include "drm.h"
-#include "qsstvglobal.h"
+#include "appglobal.h"
 #include "drmproto.h"
 #include <math.h>
 #include <float.h>
 #include "configparams.h"
-#include "dispatcher.h"
+#include "dispatch/dispatcher.h"
 #include <QApplication>
 #include <QFileInfo>
 #include "utils/reedsolomoncoder.h"
@@ -13,24 +13,41 @@
 #include "drmrx/demodulator.h"
 #include "utils/ftp.h"
 #include "configparams.h"
-#include "utils/qjp2io.h"
-#include "utils/hybridcrypt.h"
+
 #include "logbook/logbook.h"
 #include "drmrx/drmstatusframe.h"
+#include <QThread>
 
 sourceDecoder::sourceDecoder(QObject *parent) : QObject(parent)
 {
+//  QThread *thr;
+  transportBlockPtrList.clear();
+ notifyIntf=NULL;
+//  thr=QThread::currentThread();
+//  qDebug() << "thread" << thr->currentThreadId() <<thr->objectName();
 
 }
 
 void sourceDecoder::init()
 {
+//  QThread *thr=QThread::currentThread();
+//  qDebug() << "source dec init" << thr->currentThreadId() <<thr->objectName();
+  if (notifyIntf==NULL)
+  {
+    notifyIntf = new ftpInterface("RX Notification FTP");
+    connect(notifyIntf, SIGNAL(notification(QString)), this, SLOT(rxNotification(QString)));
+  }
+  else
+  {
+    notifyIntf->dumpState();
+  }
+
   lastTransportBlockPtr=NULL;
-  transportBlockPtrList.clear();
   bodyTotalSegments=0;
   checkIt=false;
   erasureList.clear();
   lastContinuityIndex=-1;
+  alreadyDisplayed=false;
 }
 
 
@@ -52,40 +69,40 @@ bool sourceDecoder::decode()
 
   if (channel_decoded_data_buffer_data_valid != 1)  return false;
   if (audio_data_flag == 0)
-    {
-      addToLog("audio decoding not implemented in qsstv !\n",LOGDRMSRC); return false;
-    }
+  {
+    addToLog("audio decoding not implemented in qsstv !\n",LOGDRMSRC); return false;
+  }
   addToLog("Datapacket received",LOGPERFORM);
   N_partB = (int) (length_decoded_data/ 8);
   addToLog(QString("N-partB lenght=%1").arg(N_partB),LOGDRMSRC);
   if(N_partB>PACKETBUFFERLEN)
-    {
-      addToLog(QString("packet buffer length exceeded: lenght=%1").arg(N_partB),LOGDRMMOT);
-    }
+  {
+    addToLog(QString("packet buffer length exceeded: lenght=%1").arg(N_partB),LOGDRMMOT);
+  }
   bits2bytes (channel_decoded_data_buffer, N_partB * 8, packetBuffer);
   crc16_bytewise(&checksum, packetBuffer,N_partB);
   if(fabs (checksum) <= DBL_EPSILON)
-    {
-      if(!setupDataBlock(packetBuffer,true,N_partB))
-        {
-          msc_valid=INVALID;
-          return false;
-        }
-    }
-  else
+  {
+    if(!setupDataBlock(packetBuffer,true,N_partB))
     {
       msc_valid=INVALID;
       return false;
     }
+  }
+  else
+  {
+    msc_valid=INVALID;
+    return false;
+  }
   // at this point we have a dataPacket we now check header / data and buils a transport stream
   switch(currentDataPacket.dataGroupType)
-    {
-    case MOTDATA:  addToLog("Datasegment",LOGDRMSRC);   addDataSegment(); break;
-    case MOTHEAD:  addToLog("Headersegment",LOGDRMSRC); addHeaderSegment(); break;
-    default:
+  {
+  case MOTDATA:  addToLog("Datasegment",LOGDRMSRC);   addDataSegment(); break;
+  case MOTHEAD:  addToLog("Headersegment",LOGDRMSRC); addHeaderSegment(); break;
+  default:
     return false;
     break;
-    }
+  }
   return true;
 }
 
@@ -106,39 +123,39 @@ bool sourceDecoder::setupDataBlock(unsigned char *buffer,bool crcIsOK,int len)
   currentDataBlock.continuityIndex = (header & 0x7);
   currentDataBlock.log();
   if ((currentDataBlock.PPI != 0) && (crcIsOK))
-    {
-      availableBytes=buffer[1];
-      bufPtr=(const char *)&buffer[2];
-    }
+  {
+    availableBytes=buffer[1];
+    bufPtr=(const char *)&buffer[2];
+  }
   else
-    {
-      availableBytes=len-3;
-      bufPtr=(const char *)&buffer[1];
-    }
+  {
+    availableBytes=len-3;
+    bufPtr=(const char *)&buffer[1];
+  }
   if(currentDataBlock.firstFlag)
+  {
+    holdingBuffer.clear();
+    lastContinuityIndex=currentDataBlock.continuityIndex;
+  }
+  else
+  {
+    if(lastContinuityIndex<0)
     {
-      holdingBuffer.clear();
-      lastContinuityIndex=currentDataBlock.continuityIndex;
+      return false;
     }
-  else
+    lastContinuityIndex=(lastContinuityIndex+1)%8;
+    if(currentDataBlock.continuityIndex!=lastContinuityIndex)
     {
-      if(lastContinuityIndex<0)
-        {
-          return false;
-        }
-      lastContinuityIndex=(lastContinuityIndex+1)%8;
-      if(currentDataBlock.continuityIndex!=lastContinuityIndex)
-        {
-          lastContinuityIndex=-1;
-          return false;
-        }
-
+      lastContinuityIndex=-1;
+      return false;
     }
+
+  }
   holdingBuffer.append(bufPtr,availableBytes);
   if(currentDataBlock.lastFlag)
-    {
-      return setupDataPacket(holdingBuffer);
-    }
+  {
+    return setupDataPacket(holdingBuffer);
+  }
   return false;
 }
 
@@ -211,44 +228,44 @@ bool sourceDecoder::setupDataPacket(QByteArray ba)
   if(header&0x20) currentDataPacket.sessionFlag=true;
 
   if(header&0x40)
+  {
+    currentDataPacket.crcFlag=true;
+    crc16_bytewise (&checksum,(unsigned char *)currentDataPacket.ba.data(),currentDataPacket.ba.count());
+    if (fabs (checksum) <= DBL_EPSILON)
     {
-      currentDataPacket.crcFlag=true;
-      crc16_bytewise (&checksum,(unsigned char *)currentDataPacket.ba.data(),currentDataPacket.ba.count());
-      if (fabs (checksum) <= DBL_EPSILON)
-        {
-          currentDataPacket.crcOK=true;
-        }
-      else
-        {
-          currentDataPacket.crcOK=false;
-          msc_valid=INVALID;
-          return false;
-        }
-      currentDataPacket.chop(2); // drop crc
+      currentDataPacket.crcOK=true;
     }
+    else
+    {
+      currentDataPacket.crcOK=false;
+      msc_valid=INVALID;
+      return false;
+    }
+    currentDataPacket.chop(2); // drop crc
+  }
   currentDataPacket.advance(2); //skip header and continuity bits
   if(currentDataPacket.extFlag) currentDataPacket.advance(2); // just skip the extension bytes
 
   if(currentDataPacket.sessionFlag)
+  {
+    currentDataPacket.segmentNumber = (((unsigned char)(currentDataPacket.ba.at(0)) & 0x7F))*256+ ((unsigned char)currentDataPacket.ba.at(1))  ;
+    if(currentDataPacket.ba.at(0)&0x80)
     {
-      currentDataPacket.segmentNumber = (((unsigned char)(currentDataPacket.ba.at(0)) & 0x7F))*256+ ((unsigned char)currentDataPacket.ba.at(1))  ;
-      if(currentDataPacket.ba.at(0)&0x80)
-        {
-          currentDataPacket.lastSegment=true;
-        }
-      currentSegmentNumber=currentDataPacket.segmentNumber;
-      currentDataPacket.advance(2);
+      currentDataPacket.lastSegment=true;
     }
+    currentSegmentNumber=currentDataPacket.segmentNumber;
+    currentDataPacket.advance(2);
+  }
 
   if (currentDataPacket.userFlag)
-    {
-      currentDataPacket.userAccessField = (unsigned char)(currentDataPacket.ba.at(0));
-      currentDataPacket.advance(1);
-      lengthIndicator = (currentDataPacket.userAccessField& 0xF);
-
-      if((currentDataPacket.userAccessField & 0x10) && (lengthIndicator>=2)) currentDataPacket.transportID = (((unsigned char)(currentDataPacket.ba.at(0))))*256+ ((unsigned char)currentDataPacket.ba.at(1))  ;
-      currentDataPacket.advance(lengthIndicator);
-    }
+  {
+    currentDataPacket.userAccessField = (unsigned char)(currentDataPacket.ba.at(0));
+    currentDataPacket.advance(1);
+    lengthIndicator = (currentDataPacket.userAccessField& 0xF);
+
+    if((currentDataPacket.userAccessField & 0x10) && (lengthIndicator>=2)) currentDataPacket.transportID = (((unsigned char)(currentDataPacket.ba.at(0))))*256+ ((unsigned char)currentDataPacket.ba.at(1))  ;
+    currentDataPacket.advance(lengthIndicator);
+  }
   currentDataPacket.segmentSize=(((unsigned char)(currentDataPacket.ba.at(0)) & 0x1F))*256+ ((unsigned char)currentDataPacket.ba.at(1));
   currentDataPacket.advance(2);
   currentDataPacket.lenght=currentDataPacket.ba.count();
@@ -268,16 +285,30 @@ void dataPacket::log()
 
 bool sourceDecoder::addHeaderSegment()
 {
+  loadRXImageEvent *stce;
+  displayMBoxEvent *stmb;
   transportBlock *tbPtr;
   addToLog(QString("Header segsize: %1").arg(currentDataPacket.segmentSize),LOGDRMSRC);
   tbPtr=getTransporPtr(currentDataPacket.transportID,true);
   if(!tbPtr->alreadyReceived) msc_valid=VALID;
   else
+  {
+    msc_valid=ALREADYRECEIVED;
+    if(!alreadyDisplayed)
     {
-      msc_valid=ALREADYRECEIVED;
-      return true;
+      alreadyDisplayed=true;
+      // redisplay
+      stce= new loadRXImageEvent(QString("%1").arg(tbPtr->newFileName));
+      QApplication::postEvent( dispatcherPtr, stce );  // Qt will delete it when done
+      stmb= new displayMBoxEvent("DRM Receive",QString("File %1 already received").arg(tbPtr->newFileName));
+      QApplication::postEvent( dispatcherPtr, stmb );
     }
 
+
+
+    return true;
+  }
+
   tbPtr->headerReceived=true;
   unsigned char *dataPtr=(unsigned char *)currentDataPacket.ba.data();
   unsigned char PLI;
@@ -302,61 +333,64 @@ bool sourceDecoder::addHeaderSegment()
   // the first byte of every parameter block contains a 2-bits PLI (B7 and B6) indicating the type of parameter block.
 
   while(currentDataPacket.ba.count())  // todo
+  {
+    PLI=dataPtr[0]>>6;
+    paramID=dataPtr[0]&0x3F;
+    switch (PLI)
     {
-      PLI=dataPtr[0]>>6;
-      paramID=dataPtr[0]&0x3F;
-      switch (PLI)
-        {
-        case 0:
-          currentDataPacket.advance(1);
-        break;
-        case 1:
-          loadParams(tbPtr,paramID,1);
-          currentDataPacket.advance(2);
-        break;
-        case 2:
-          loadParams(tbPtr,paramID,4);
-          currentDataPacket.advance(5);
-        break;
-        case 3:
-          extBit=dataPtr[0]&0x80;
-          if(extBit)
-            {
-              dataFieldLength=256*(dataPtr[0]&0x7F)+dataPtr[1];
-              currentDataPacket.advance(2);
-            }
-          else
-            {
-              dataFieldLength=dataPtr[0]&0x7F;
-              currentDataPacket.advance(1);
-            }
-          loadParams(tbPtr,paramID,dataFieldLength);
-          currentDataPacket.advance(dataFieldLength);
-        break;
-        }
-    }
+    case 0:
+      currentDataPacket.advance(1);
+      break;
+    case 1:
+      loadParams(tbPtr,paramID,1);
+      currentDataPacket.advance(2);
+      break;
+    case 2:
+      loadParams(tbPtr,paramID,4);
+      currentDataPacket.advance(5);
+      break;
+    case 3:
+      extBit=dataPtr[0]&0x80;
+      if(extBit)
+      {
+        dataFieldLength=256*(dataPtr[0]&0x7F)+dataPtr[1];
+        currentDataPacket.advance(2);
+      }
+      else
+      {
+        dataFieldLength=dataPtr[0]&0x7F;
+        currentDataPacket.advance(1);
+      }
+      loadParams(tbPtr,paramID,dataFieldLength);
+      currentDataPacket.advance(dataFieldLength);
+      break;
+    }
+  }
   return true;
 
 }
 
 void sourceDecoder::loadParams(transportBlock *tbPtr,unsigned char paramID,int len)
 {
+  //  QByteArray testBA;
+  //  char *data;
+  //  unsigned int ct;
   rxDRMStatusEvent *stce;
   QString tmp,t;
   switch(paramID)
-    {
-    case 5: // expiration
+  {
+  case 5: // expiration
     break;
-    case 6:
+  case 6:
     break;
-    case 12:
-      tbPtr->fileName=QString(currentDataPacket.ba.data()+1).left(len-1);
-      stce= new rxDRMStatusEvent(QString("%1").arg(tbPtr->fileName));
-      QApplication::postEvent( dispatcherPtr, stce );  // Qt will delete it when done
+  case 12:
+    tbPtr->fileName=QString::fromLatin1(currentDataPacket.ba.data()+1).left(len-1);
+    stce= new rxDRMStatusEvent(QString("%1").arg(tbPtr->fileName));
+    QApplication::postEvent( dispatcherPtr, stce );  // Qt will delete it when done
     break;
-    default:
+  default:
     break;
-    }
+  }
 }
 
 
@@ -369,47 +403,42 @@ void sourceDecoder::addDataSegment()
   if(callsignValid) tbPtr->callsign=drmCallsign;
   addToLog(QString("Data segsize: %1 segment# %2").arg(currentDataPacket.segmentSize).arg(currentDataPacket.segmentNumber),LOGDRMSRC);
 
-  bodyTotalSegments=tbPtr->totalSegments;
+
   if(!tbPtr->alreadyReceived) msc_valid=VALID;
   else
-    {
-      msc_valid=ALREADYRECEIVED;
-      //      return;
-    }
+  {
+    msc_valid=ALREADYRECEIVED;
+    //      return;
+  }
   if(currentDataPacket.lastSegment)
-    {
-      tbPtr->totalSegments=currentDataPacket.segmentNumber+1;
-      tbPtr->lastSegmentReceived=true;
-    }
+  {
+    tbPtr->totalSegments=currentDataPacket.segmentNumber+1;
+    tbPtr->lastSegmentReceived=true;
+  }
   else
-    {
-      tbPtr->defaultSegmentSize=currentDataPacket.segmentSize;
-    }
-  if(tbPtr->defaultSegmentSize==0)
-    {
-      //      qDebug() << "def seg size not set";
-    }
+  {
+    tbPtr->defaultSegmentSize=currentDataPacket.segmentSize;
+  }
   for(i=tbPtr->dataSegmentPtrList.count();i<=currentDataPacket.segmentNumber;i++)
-    {
-      tbPtr->dataSegmentPtrList.append(new dataSegment(tbPtr->defaultSegmentSize));
-    }
+  {
+    tbPtr->dataSegmentPtrList.append(new dataSegment(tbPtr->defaultSegmentSize));
+  }
 
   if(!tbPtr->dataSegmentPtrList.at(currentDataPacket.segmentNumber)->hasData())
-    {
-      checkIt=true;
-    }
+  {
+    checkIt=true;
+  }
   else
-    {
-      msc_valid=ALREADYRECEIVED;
-    }
+  {
+    msc_valid=ALREADYRECEIVED;
+  }
   if(tbPtr->alreadyReceived)
-    {
-      msc_valid=ALREADYRECEIVED;
-      checkIt=false;
-    }
-
-
+  {
+    msc_valid=ALREADYRECEIVED;
+    checkIt=false;
+  }
   if(tbPtr->totalSegments<currentDataPacket.segmentNumber+1) tbPtr->totalSegments=currentDataPacket.segmentNumber+1;
+  bodyTotalSegments=tbPtr->totalSegments;
   rxSegments=tbPtr->segmentsReceived;
   //  bytesReceived=rxSegments*tbPtr->defaultSegmentSize;
 
@@ -430,29 +459,28 @@ void sourceDecoder::writeData(transportBlock *tbPtr)
   erasureList.append(tbPtr->totalSegments);
   erasureList.append(tbPtr->defaultSegmentSize);
   for(i=0;i<tbPtr->dataSegmentPtrList.count();i++)
+  {
+    if(!tbPtr->dataSegmentPtrList.at(i)->hasData())
     {
-      if(!tbPtr->dataSegmentPtrList.at(i)->hasData())
-        {
-          erasureList.append(i);
-          ba.append(QByteArray(tbPtr->defaultSegmentSize,0x00));
-        }
-      else
-        {
-          ba.append(tbPtr->dataSegmentPtrList.at(i)->data);
-        }
-      length+=tbPtr->dataSegmentPtrList.at(i)->data.size();
-      //      qDebug()<< "block" << i<< "len" << tbPtr->dataSegmentPtrList.at(i)->data.size() ;
+      erasureList.append(i);
+      ba.append(QByteArray(tbPtr->defaultSegmentSize,0x00));
     }
+    else
+    {
+      ba.append(tbPtr->dataSegmentPtrList.at(i)->data);
+    }
+    length+=tbPtr->dataSegmentPtrList.at(i)->data.size();
+  }
   tbPtr->segmentsReceived=0;
   drmBlockList.clear();
   for(i=0;i<tbPtr->dataSegmentPtrList.count();i++)
+  {
+    if(tbPtr->dataSegmentPtrList.at(i)->hasData())
     {
-      if(tbPtr->dataSegmentPtrList.at(i)->hasData())
-        {
-          drmBlockList.append(i);
-          tbPtr->segmentsReceived++;
-        }
+      drmBlockList.append(i);
+      tbPtr->segmentsReceived++;
     }
+  }
   if(tbPtr->isAlmostComplete()<63) return ;
 
   if(!tbPtr->lastSegmentReceived) return;
@@ -465,125 +493,193 @@ void sourceDecoder::saveImage(transportBlock *tbPtr)
   int i;
   eftpError ftpResult;
   QByteArray hybridBa;
-  hybridCrypt hc;
+
   QImage test;
   displayTextEvent *stce;
   displayMBoxEvent *stmb=0;
+  rxDRMNotifyEvent *rxne;
   QString t;
-  ftpInterface ftpIntf("Save Image FTP");
+
   bool done=false;
   bool textMode=false;
-  QString downloadF;
+  QString downloadF, RxOkF;
   bool   saveOK=false;
-
-  if(tbPtr->alreadyReceived) return ;
+  alreadyDisplayed=true;
+  if(tbPtr->alreadyReceived)
+  {
+    return ;
+  }
   if(tbPtr->fileName.isEmpty()) return ;
-  lastAvgSNR=avgSNR;
+  if(tbPtr->retrieveTries==0) lastAvgSNR=avgSNR;
+
+  rxne = new rxDRMNotifyEvent("");
+  QApplication::postEvent( dispatcherPtr, rxne );  // Qt will delete it when done
+
   isHybrid=false;
-  if(tbPtr->fileName.left(3)=="de_")
-    {
-      isHybrid=true;
-      if(enableHybridRx)
+  if((tbPtr->fileName.left(3)==".de") || (tbPtr->fileName.left(3)=="de_"))
+  {
+    isHybrid=true;
+    ftpInterface ftpIntf("Save Image FTP");
+    if((enableHybridRx) && (soundRoutingInput!=soundBase::SNDINFROMFILE))
+    {
+      addToLog(QString("Hybrid filename %1, attempt %2").arg(tbPtr->fileName).arg(tbPtr->retrieveTries+1),LOGALL);
+      downloadF=rxDRMImagesPath+"/"+tbPtr->fileName;
+      for(i=0;i<tbPtr->dataSegmentPtrList.count();i++)
+      {
+        hybridBa+=tbPtr->dataSegmentPtrList.at(i)->data;
+      }
+      if(hc.deCrypt(&hybridBa))
+      {
+        if ((tbPtr->retrieveTries==0) && enableHybridNotify)
         {
-          downloadF=rxImagesPath+"/"+tbPtr->fileName;
-          for(i=0;i<tbPtr->dataSegmentPtrList.count();i++)
-            {
-              hybridBa+=tbPtr->dataSegmentPtrList.at(i)->data;
-            }
-          if(hc.deCrypt(&hybridBa))
-            {
-
-
-              ftpIntf.setupConnection(hc.host(),hc.port(),hc.user(),hc.passwd(),hc.dir()+"/"+hybridFtpHybridFilesDirectory);
-              ftpResult=ftpIntf.downloadFile(tbPtr->fileName,downloadF);
-              switch(ftpResult)
-                {
-                case FTPOK:
-                break;
-                case FTPERROR:
-                  stmb= new displayMBoxEvent("FTP Error",QString("Host: %1: %2").arg(ftpRemoteHost).arg(ftpIntf.getLastError()));
-                break;
-                case FTPNAMEERROR:
-                  stmb= new displayMBoxEvent("FTP Error",QString("Host: %1, Error in filename").arg(ftpRemoteHost));
-                break;
-                case FTPCANCELED:
-                  stmb= new displayMBoxEvent("FTP Error",QString("Connection to %1 Canceled").arg(ftpRemoteHost));
-                break;
-                case FTPTIMEOUT:
-                  stmb= new displayMBoxEvent("FTP Error",QString("Connection to %1 timed out").arg(ftpRemoteHost));
-                break;
-                }
-              if(ftpResult!=FTPOK)
-                {
-                  QApplication::postEvent( dispatcherPtr, stmb );  // Qt will delete it when done
-                  tbPtr->setAlreadyReceived(true);
-                  return;
-                }
-
-            }
-          else
-            {
-              stmb= new displayMBoxEvent("Hybrid Error","No file downloaded");
-              QApplication::postEvent( dispatcherPtr, stmb );  // Qt will delete it when done
-              return;
-            }
+          RxOkF = "Dummy"+tbPtr->fileName+"+++."+myCallsign+QString("  -%1dB SNR").arg(lastAvgSNR,0,'f',0);
+          notifyIntf->mremove("*+++."+myCallsign+"*");
+          notifyIntf->uploadData(QByteArray("Dummy\r\n"), RxOkF);
+          rxNotifyCheck(tbPtr->fileName,&hc);
         }
-      else
+        tbPtr->retrieveTries++;
+        ftpIntf.setupConnection(hc.host(),hc.port(),hc.user(),hc.passwd(),hc.dir()+"/"+hybridFtpHybridFilesDirectory);
+        ftpResult=ftpIntf.downloadFile(tbPtr->fileName.toLatin1(),downloadF);
+        switch(ftpResult)
         {
-          downloadF.clear();
+        case FTPOK:
+          break;
+        case FTPERROR:
+          stmb= new displayMBoxEvent("FTP Error",QString("Host: %1: %2").arg(ftpRemoteHost).arg(ftpIntf.getLastError()));
+          errorOut() << "ftp error" << ftpRemoteHost << ftpIntf.getLastError();
+          break;
+        case FTPNAMEERROR:
+          stmb= new displayMBoxEvent("FTP Error",QString("Host: %1, Error in filename").arg(ftpRemoteHost));
+          errorOut() << "ftp filename error" << ftpRemoteHost << ftpIntf.getLastError();
+          break;
+        case FTPCANCELED:
+          stmb= new displayMBoxEvent("FTP Error",QString("Connection to %1 Canceled").arg(ftpRemoteHost));
+          errorOut() << "ftp connection error" << ftpRemoteHost << ftpIntf.getLastError();
+          break;
+        case FTPTIMEOUT:
+          stmb= new displayMBoxEvent("FTP Error",QString("Connection to %1 timed out").arg(ftpRemoteHost));
+          errorOut() << "ftp connection timeout error" << ftpRemoteHost << ftpIntf.getLastError();
+          break;
+        }
+        if(ftpResult!=FTPOK)
+        {
+          if ((ftpResult!=FTPTIMEOUT) || (tbPtr->retrieveTries>1)) {
+            QApplication::postEvent( dispatcherPtr, stmb );  // Qt will delete it when done
+            tbPtr->setAlreadyReceived(true);
+          }
+          return;
         }
 
-      tbPtr->newFileName=downloadF;
-
+      }
+      else
+      {
+        stmb= new displayMBoxEvent("Hybrid Error","No file downloaded");
+        QApplication::postEvent( dispatcherPtr, stmb );  // Qt will delete it when done
+        return;
+      }
+    }
+    else
+    {
+      downloadF.clear();
     }
 
+    tbPtr->newFileName=downloadF;
+
+  }
+
   if(tbPtr->newFileName.isEmpty()) return ;
   //  test=readJP2Image(tbPtr->newFileName);
   if(!test.load(tbPtr->newFileName))
-    {
-      test=readJP2Image(tbPtr->newFileName);
-      if(test.isNull())
-        {
-          // maybe text
-          QFileInfo finfo(tbPtr->newFileName);
-          if((finfo.suffix()=="txt") || (finfo.suffix()=="chat") )
-            {
-              QFile fi(tbPtr->newFileName);
-              if(!fi.open(QIODevice::ReadOnly)) return;
-              t=fi.readAll();
-              stce= new displayTextEvent(t);
-              QApplication::postEvent( dispatcherPtr, stce );  // Qt will delete it when done
-              textMode=true;
-            }
-        }
+  {
 
-      saveOK=true;
-    }
-  else
+    // maybe text
+    QFileInfo finfo(tbPtr->newFileName);
+    if((finfo.suffix()=="txt") || (finfo.suffix()=="chat") )
     {
-      saveOK=true;
+      QFile fi(tbPtr->newFileName);
+      if(!fi.open(QIODevice::ReadOnly)) return;
+      t=fi.readAll();
+      stce= new displayTextEvent(t);
+      QApplication::postEvent( dispatcherPtr, stce );  // Qt will delete it when done
+      textMode=true;
     }
+    saveOK=true;
+  }
+  else
+  {
+    saveOK=true;
+  }
   if(saveOK)
-    {
-      QFileInfo tfi(tbPtr->newFileName);
-      QString modestr(tfi.fileName());
-      modestr+=" ";
-      if(isHybrid) modestr+="Hybrid ";
-      modestr+=compactModeToString(tbPtr->modeCode);
-      logBookPtr->logQSO(tbPtr->callsign,modestr);
-    }
+  {
+    QFileInfo tfi(tbPtr->newFileName);
+
+    QString modestr(tfi.fileName());
+    modestr+=QString(" %1dB ").arg(lastAvgSNR,0,'f',0);
+    if(isHybrid) modestr+="Hybrid ";
+    modestr+=compactModeToString(tbPtr->modeCode);
+    logBookPtr->logQSO(tbPtr->callsign,"DSSTV",modestr);
+
+  }
   tbPtr->setAlreadyReceived(true);
   if(!textMode)
+  {
+    saveDRMImageEvent *ce = new saveDRMImageEvent(tbPtr->newFileName);
+    ce->waitFor(&done);
+    QApplication::postEvent(dispatcherPtr, ce);
+    while(!done)
     {
-      saveDRMImageEvent *ce = new saveDRMImageEvent(tbPtr->newFileName);
-      ce->waitFor(&done);
-      QApplication::postEvent(dispatcherPtr, ce);
-      while(!done)
-        {
-          usleep(10);
-        }
-      checkIt=false;
+      usleep(10);
     }
+    checkIt=false;
+  }
+}
+
+
+bool sourceDecoder::rxNotifyCheck(QString fn, hybridCrypt *c)
+{
+  rxDRMNotifyEvent *rxne;
+  if (!enableHybridNotify) return false;
+
+  if (enableHybridNotifySpecialServer)
+  {
+    addToLog(QString("using special server host:%1, port:%2, user:%3, pwd:%4").arg(c->host()).arg(c->port()).arg(c->user()).arg(c->passwd()),LOGNOTIFY);
+
+    notifyIntf->setupConnection(hybridNotifyRemoteHost, hybridNotifyPort,
+                                hybridNotifyLogin, hybridNotifyPassword,
+                                hybridNotifyRemoteDir+"/"+hybridNotifyDir);
+  }
+  else if (c)
+  {
+    // notification to image server
+    addToLog(QString("notification to image server host:%1, port:%2, user:%3, pwd:%4").arg(c->host()).arg(c->port()).arg(c->user()).arg(c->passwd()),LOGNOTIFY);
+    notifyIntf->setupConnection(c->host(),c->port(),c->user(),c->passwd(),c->dir()+"/RxOkNotifications1");
+  }
+  else
+  {
+    // notification to vk4aes.com (EasyPal compatible)
+    addToLog("notification to image server",LOGNOTIFY);
+    notifyIntf->setupConnection("vk4aes.com",21,"vk4aes","10mar1936","/RxOkNotifications1");
+
+    // or to default server (from hc object)
+    //notifyIntf->setupConnection(hc->host(),hc->port(),hc->user(),hc->passwd(),hc->dir()+"/RxOkNotifications1");
+  }
+
+  rxne = new rxDRMNotifyEvent("");
+  QApplication::postEvent( dispatcherPtr, rxne );
+//   QThread *thr;
+//   thr=QThread::currentThread();
+//  qDebug() << "thread not" << thr->currentThreadId() <<thr->objectName();
+  notifyIntf->startNotifyCheck(fn, 5, 45/5, false);
+  return true;
+}
+
+void sourceDecoder::rxNotification(QString info)
+{
+  if (info != "")
+  {
+    rxDRMNotifyAppendEvent *rxne = new rxDRMNotifyAppendEvent(info);
+    QApplication::postEvent( dispatcherPtr, rxne );  // Qt will delete it when done
+  }
 }
 
 bool sourceDecoder::checkSaveImage(QByteArray ba,transportBlock *tbPtr)
@@ -593,7 +689,7 @@ bool sourceDecoder::checkSaveImage(QByteArray ba,transportBlock *tbPtr)
   reedSolomonCoder rsd;
   QString fileName;
   QString extension;
-  fileName=rxImagesPath+"/"+tbPtr->fileName;
+  fileName=rxDRMImagesPath+"/"+tbPtr->fileName;
   tbPtr->newFileName=fileName;
   QByteArray baFile;
   QByteArray *baFilePtr;
@@ -602,38 +698,38 @@ bool sourceDecoder::checkSaveImage(QByteArray ba,transportBlock *tbPtr)
   QFileInfo qfinf(fileName);
   extension=qfinf.suffix().toLower();
   if((extension=="rs1") || (extension=="rs2") ||(extension=="rs3")||(extension=="rs4"))
-    {
-      // try to decode
-      if(tbPtr->alreadyReceived) return false;
-      if(!rsd.decode(ba,fileName,tbPtr->newFileName,baFile,extension,erasureList)) return false;
-      baFilePtr=&baFile;
-    }
+  {
+    // try to decode
+    if(tbPtr->alreadyReceived) return false;
+    if(!rsd.decode(ba,fileName,tbPtr->newFileName,baFile,extension,erasureList)) return false;
+    baFilePtr=&baFile;
+  }
   else
-    {
-      if(!tbPtr->isComplete()) return false;
-      tbPtr->newFileName=fileName;
-      if((tbPtr->fileName=="bsr.bin")&&(!tbPtr->alreadyReceived))
-        {
-          tbPtr->setAlreadyReceived(true);
-          pe = new prepareFixEvent(ba);
-          QApplication::postEvent(dispatcherPtr, pe);
-          return false;
-        }
-      baFilePtr=&ba;
+  {
+    if(!tbPtr->isComplete()) return false;
+    tbPtr->newFileName=fileName;
+    if((tbPtr->fileName=="bsr.bin")&&(!tbPtr->alreadyReceived))
+    {
+      tbPtr->setAlreadyReceived(true);
+      pe = new prepareFixEvent(ba);
+      QApplication::postEvent(dispatcherPtr, pe);
+      return false;
     }
+    baFilePtr=&ba;
+  }
   if(!tbPtr->alreadyReceived)
+  {
+    outFile.setFileName(tbPtr->newFileName);
+    if(outFile.open(QIODevice::WriteOnly)<=0)
     {
-      outFile.setFileName(tbPtr->newFileName);
-      if(outFile.open(QIODevice::WriteOnly)<=0)
-        {
-          outFile.close();
-          return false;
-        }
-      outFile.write(*baFilePtr);
       outFile.close();
-      erasureList.clear();
-      saveImage(tbPtr);
+      return false;
     }
+    outFile.write(*baFilePtr);
+    outFile.close();
+    erasureList.clear();
+    saveImage(tbPtr);
+  }
   return false;
 }
 
@@ -644,12 +740,12 @@ QList <bsrBlock> *sourceDecoder::getBSR()
   bsrList.clear();
 
   for(i=0;i<transportBlockPtrList.count();i++)
-    {
-      tbPtr=transportBlockPtrList.at(i);
-      if(tbPtr->alreadyReceived) continue;
-      if(tbPtr->fileName=="bsr.bin") continue;
-      bsrList.append(bsrBlock(tbPtr));
-    }
+  {
+    tbPtr=transportBlockPtrList.at(i);
+    if(tbPtr->alreadyReceived) continue;
+    if(tbPtr->fileName=="bsr.bin") continue;
+    bsrList.append(bsrBlock(tbPtr));
+  }
   return &bsrList;
 }
 
@@ -663,19 +759,12 @@ bool sourceDecoder::storeBSR(transportBlock *tb, bool compat)
   erasureList.append(tb->totalSegments);
   erasureList.append(tb->defaultSegmentSize);
   for(i=0;i<tb->dataSegmentPtrList.count();i++)
+  {
+    if(!tb->dataSegmentPtrList.at(i)->hasData())
     {
-      if(!tb->dataSegmentPtrList.at(i)->hasData())
-        {
-          erasureList.append(i);
-          //         ba.append(QByteArray(tb->defaultSegmentSize,0x00));
-        }
-      else
-        {
-          //          ba.append(tb->dataSegmentPtrList.at(i)->data);
-        }
-      //      length+=tb->dataSegmentPtrList.at(i)->data.size();
-      //      qDebug()<< "block" << i<< "len" << tbPtr->dataSegmentPtrList.at(i)->data.size() ;
+      erasureList.append(i);
     }
+  }
   tb->baBSR.clear();
   if(erasureList.count()<3) return false; //erasurelist has already totalSegments and defaultSegmentSize
   tb->baBSR.append(QString::number(tb->transportID).toLatin1().data());
@@ -689,41 +778,41 @@ bool sourceDecoder::storeBSR(transportBlock *tb, bool compat)
   prevErasure=erasureList.at(2);
   needsFiller=false;
   for(i=3;i<erasureList.count();i++) //skip
+  {
+    if(((prevErasure+1)==erasureList.at(i))&&(compat))
     {
-      if(((prevErasure+1)==erasureList.at(i))&&(compat))
-        {
-          needsFiller=true;
-        }
-      else
-        {
-          if(needsFiller)
-            {
-              tb->baBSR.append(QString::number(-1).toLatin1().data());
-              tb->baBSR.append("\n");
-              needsFiller=false;
-            }
-          tb->baBSR.append(QString::number(erasureList.at(i)).toLatin1().data());
-          tb->baBSR.append("\n");
-        }
-      prevErasure=erasureList.at(i);
+      needsFiller=true;
     }
-  if(needsFiller)
+    else
     {
-      tb->baBSR.append(QString::number(-1).toLatin1().data());
-      tb->baBSR.append("\n");
-      needsFiller=false;
-      tb->baBSR.append(QString::number(erasureList.at(erasureList.count()-1)).toLatin1().data());
+      if(needsFiller)
+      {
+        tb->baBSR.append(QString::number(-1).toLatin1().data());
+        tb->baBSR.append("\n");
+        needsFiller=false;
+      }
+      tb->baBSR.append(QString::number(erasureList.at(i)).toLatin1().data());
       tb->baBSR.append("\n");
     }
+    prevErasure=erasureList.at(i);
+  }
+  if(needsFiller)
+  {
+    tb->baBSR.append(QString::number(-1).toLatin1().data());
+    tb->baBSR.append("\n");
+    needsFiller=false;
+    tb->baBSR.append(QString::number(erasureList.at(erasureList.count()-1)).toLatin1().data());
+    tb->baBSR.append("\n");
+  }
   tb->baBSR.append("-99\n");
   if(!compat)
-    {
-      QString temp;
-      tb->baBSR.append(tb->fileName+"\n");
-      temp=QString::number(tb->modeCode);
-      while(temp.length()<5) temp.prepend("0");
-      tb->baBSR.append(temp);
-    }
+  {
+    QString temp;
+    tb->baBSR.append(tb->fileName+"\n");
+    temp=QString::number(tb->modeCode);
+    while(temp.length()<5) temp.prepend("0");
+    tb->baBSR.append(temp);
+  }
   return true;
 }
 
@@ -734,52 +823,53 @@ transportBlock *sourceDecoder::getTransporPtr(unsigned short tId,bool create)
   rxDRMStatusEvent *stce;
   bool found=false;
   for(i=0;i<transportBlockPtrList.count();i++)
+  {
+    if(transportBlockPtrList.at(i)->transportID==tId)
     {
-      if(transportBlockPtrList.at(i)->transportID==tId)
-        {
-          found=true;
-          break;
-        }
+      found=true;
+      break;
     }
+  }
   if(found) lastTransportBlockPtr=transportBlockPtrList.at(i);
   else if (create)
-    {
-      callsignValid=false;
-      stce= new rxDRMStatusEvent("");
-      QApplication::postEvent( dispatcherPtr, stce );  // Qt will delete it when done
-      if(transportBlockPtrList.count()>=MAXTRANSPORTLISTS)
-        {
-          //delete the oldest
-          transportBlockPtrList.removeFirst();
-        }
-      for(i=0;i<transportBlockPtrList.count();)
-        {
-          if(transportBlockPtrList.at(i)->fileName=="bsr.bin")
-            {
-              transportBlockPtrList.takeAt(i);
-              //              qDebug()<< "deleting bsr.bin";
-            }
-          else i++;
-        }
-      transportBlockPtrList.append(new transportBlock(tId));
-      lastTransportBlockPtr=transportBlockPtrList.last();
-      lastTransportBlockPtr->robMode=robustness_mode;
-      lastTransportBlockPtr->interLeaver=interleaver_depth_new;
-      lastTransportBlockPtr->mscMode=msc_mode_new; // qam
-      lastTransportBlockPtr->mpx=multiplex_description.PL_PartB;
-      lastTransportBlockPtr->spectrum=spectrum_occupancy_new;
-      // remap msc_new to modeCode
-      int mCode=1;    //default QAM16
-      if(msc_mode_new==3) mCode=0;
-      if(msc_mode_new==0) mCode=2;
-      int protection=0;
-      if(multiplex_description.PL_PartB==1) protection=1;
-      lastTransportBlockPtr->modeCode=robustness_mode*10000+spectrum_occupancy_new*1000+protection*100+mCode*10+interleaver_depth_new;
-    }
+  {
+    callsignValid=false;
+    bodyTotalSegments=0;
+    drmBlockList.clear();
+    stce= new rxDRMStatusEvent("");
+    QApplication::postEvent( dispatcherPtr, stce );  // Qt will delete it when done
+    if(transportBlockPtrList.count()>=MAXTRANSPORTLISTS)
+    {
+      //delete the oldest
+      transportBlockPtrList.removeFirst();
+    }
+    for(i=0;i<transportBlockPtrList.count();)
+    {
+      if(transportBlockPtrList.at(i)->fileName=="bsr.bin")
+      {
+        transportBlockPtrList.takeAt(i);
+      }
+      else i++;
+    }
+    transportBlockPtrList.append(new transportBlock(tId));
+    lastTransportBlockPtr=transportBlockPtrList.last();
+    lastTransportBlockPtr->robMode=robustness_mode;
+    lastTransportBlockPtr->interLeaver=interleaver_depth_new;
+    lastTransportBlockPtr->mscMode=msc_mode_new; // qam
+    lastTransportBlockPtr->mpx=multiplex_description.PL_PartB;
+    lastTransportBlockPtr->spectrum=spectrum_occupancy_new;
+    // remap msc_new to modeCode
+    int mCode=1;    //default QAM16
+    if(msc_mode_new==3) mCode=0;
+    if(msc_mode_new==0) mCode=2;
+    int protection=0;
+    if(multiplex_description.PL_PartB==1) protection=1;
+    lastTransportBlockPtr->modeCode=robustness_mode*10000+spectrum_occupancy_new*1000+protection*100+mCode*10+interleaver_depth_new;
+  }
   else
-    {
-      return NULL;
-    }
+  {
+    return NULL;
+  }
   return lastTransportBlockPtr;
 }
 
@@ -787,13 +877,13 @@ void sourceDecoder::removeTransporPtr(transportBlock * ptr)
 {
   int i;
   for(i=0;i<transportBlockPtrList.count();i++)
+  {
+    if(transportBlockPtrList.at(i)==ptr)
     {
-      if(transportBlockPtrList.at(i)==ptr)
-        {
-          transportBlockPtrList.takeAt(i);
-          break;
-        }
+      transportBlockPtrList.takeAt(i);
+      break;
     }
+  }
 }
 
 
diff --git a/qsstv/drmrx/sourcedecoder.h b/qsstv/drmrx/sourcedecoder.h
index 8ff4f48..a6acdeb 100644
--- a/qsstv/drmrx/sourcedecoder.h
+++ b/qsstv/drmrx/sourcedecoder.h
@@ -11,7 +11,9 @@
 #include <QDateTime>
 #include <QByteArray>
 #include <QVector>
-#include "qsstvdefs.h"
+#include "appdefs.h"
+#include "hybridcrypt.h"
+#include "ftp.h"
 
 enum edataGroupType {GENDATA,CAMESS,GENCA,MOTHEAD,MOTDATA,MOTDATACA};
 
@@ -109,6 +111,7 @@ struct transportBlock
     bodySize=0;
     headerSize=0;
     alreadyReceived=false;
+    retrieveTries=0;
     //    blockList.clear();
     lastSegmentReceived=false;
     defaultSegmentSize=0;
@@ -150,6 +153,7 @@ struct transportBlock
   QString newFileName;
   bool headerReceived;
   bool alreadyReceived;
+  int  retrieveTries;
   unsigned short segmentsReceived;
   bool lastSegmentReceived;
   int totalSegments;
@@ -189,6 +193,9 @@ public:
   bool checkSaveImage(QByteArray ba, transportBlock *tbPtr);
   void saveImage(transportBlock *tbPtr);
   bool storeBSR(transportBlock *tb,bool compat);
+  bool rxNotifyCheck(QString fn, hybridCrypt *hc);
+private slots:
+  void rxNotification(QString info);
 private:
   bool setupDataBlock(unsigned char *buffer,bool crcIsOK,int len);
   bool setupDataPacket(QByteArray ba);
@@ -209,5 +216,8 @@ private:
   bool checkIt;
   QList <bsrBlock> bsrList;
   bool isHybrid;
+  hybridCrypt hc;
+  bool alreadyDisplayed;
+  ftpInterface *notifyIntf;
 };
 #endif // SOURCEDECODER_H
diff --git a/qsstv/drmtx/bsrform.cpp b/qsstv/drmtx/bsrform.cpp
index a9dccf9..232e548 100644
--- a/qsstv/drmtx/bsrform.cpp
+++ b/qsstv/drmtx/bsrform.cpp
@@ -1,7 +1,7 @@
 #include "bsrform.h"
 #include "ui_bsrform.h"
 #include "drmrx/drmstatusframe.h"
-#include "qsstvglobal.h"
+#include "drm.h"
 
 bsrForm::bsrForm(QWidget *parent) :
   QDialog(parent),
@@ -23,7 +23,7 @@ bsrForm::~bsrForm()
 void bsrForm::init()
 {
   int i;
-  bsrPtr=srcDecoder.getBSR();
+  bsrPtr=srcDecoder->getBSR();
   if(bsrPtr->count()==0)
     {
       ui->infoTextEdit->clear();
@@ -46,22 +46,19 @@ QByteArray *bsrForm::getBA(bool compat)
 {
   int i;
   i=bsrPtr->count()-1-ui->bsrComboBox->currentIndex();
-  if(bsrPtr->count()>0)
+  if(srcDecoder->storeBSR(bsrPtr->at(i).tbPtr,compat))
     {
-      if(srcDecoder.storeBSR(bsrPtr->at(i).tbPtr,compat))
-        {
-          drmParams.robMode=bsrPtr->at(i).tbPtr->robMode;
-          drmParams.interleaver=bsrPtr->at(i).tbPtr->interLeaver;
-          drmParams.qam=bsrPtr->at(i).tbPtr->mscMode;
-          drmParams.protection=bsrPtr->at(i).tbPtr->mpx;
-          drmParams.bandwith=bsrPtr->at(i).tbPtr->spectrum;
-          return(&bsrPtr->at(i).tbPtr->baBSR);
-        }
+      drmParams.robMode=bsrPtr->at(i).tbPtr->robMode;
+      drmParams.interleaver=bsrPtr->at(i).tbPtr->interLeaver;
+      drmParams.qam=bsrPtr->at(i).tbPtr->mscMode;
+      drmParams.protection=bsrPtr->at(i).tbPtr->mpx;
+      drmParams.bandwith=bsrPtr->at(i).tbPtr->spectrum;
+      return(&bsrPtr->at(i).tbPtr->baBSR);
     }
   return NULL;
 }
 
-void bsrForm::slotBSRSelection(int idx)
+ void bsrForm::slotBSRSelection(int idx)
 {
   int i;
   transportBlock *tbPtr;
diff --git a/qsstv/drmtx/common/DRMSignalIO.cpp b/qsstv/drmtx/common/DRMSignalIO.cpp
index db892f6..04b7309 100644
--- a/qsstv/drmtx/common/DRMSignalIO.cpp
+++ b/qsstv/drmtx/common/DRMSignalIO.cpp
@@ -30,7 +30,7 @@
 
 #include "DRMSignalIO.h"
 #include <iostream>
-#include "qsstvglobal.h"
+#include "appglobal.h"
 
 #define pi  4.0*atan(1.0) 
 
diff --git a/qsstv/drmtx/common/DrmTransmitter.cpp b/qsstv/drmtx/common/DrmTransmitter.cpp
index 592986a..d4f8e59 100644
--- a/qsstv/drmtx/common/DrmTransmitter.cpp
+++ b/qsstv/drmtx/common/DrmTransmitter.cpp
@@ -30,8 +30,9 @@
 
 #include "DrmTransmitter.h"
 #include "csoundout.h"
-#include <qsstvglobal.h>
-#include "utils/supportfunctions.h"
+#include "appglobal.h"
+#include "drm.h"
+#include "supportfunctions.h"
 
 /* Implementation *************************************************************/
 void CDRMTransmitter::Start()
diff --git a/qsstv/drmtx/common/GlobalDefinitions.h b/qsstv/drmtx/common/GlobalDefinitions.h
index 53d084a..1ee01ef 100644
--- a/qsstv/drmtx/common/GlobalDefinitions.h
+++ b/qsstv/drmtx/common/GlobalDefinitions.h
@@ -30,8 +30,8 @@
 
 #if !defined(DEF_H__3B0BA660_CA63_4344_BB2B_23E7A0D31912__INCLUDED_)
 #define DEF_H__3B0BA660_CA63_4344_BB2B_23E7A0D31912__INCLUDED_
-#include "qsstvglobal.h"
-#include "qsstvdefs.h"
+#include "appglobal.h"
+#include "appdefs.h"
 
 #include <string>
 #include <stdio.h>
diff --git a/qsstv/drmtx/common/Parameter.h b/qsstv/drmtx/common/Parameter.h
index f69b123..5ba0bae 100644
--- a/qsstv/drmtx/common/Parameter.h
+++ b/qsstv/drmtx/common/Parameter.h
@@ -164,37 +164,37 @@ enum ERecState {RS_TRACKING, RS_ACQUISITION};
 		_BOOLEAN operator!=(const CAudioParam AudioParam)
 		{
 			if (iStreamID != AudioParam.iStreamID)
-				return true;
+        return true;
 			if (eAudioCoding != AudioParam.eAudioCoding)
-				return true;
+        return true;
 			if (eSBRFlag != AudioParam.eSBRFlag)
-				return true;
+        return true;
 			if (eAudioSamplRate != AudioParam.eAudioSamplRate)
-				return true;
+        return true;
 			if (bTextflag != AudioParam.bTextflag)
-				return true;
+        return true;
 			if (bEnhanceFlag != AudioParam.bEnhanceFlag)
-				return true;
+        return true;
 
 			switch (AudioParam.eAudioCoding)
 			{
 			case AC_AAC:
 				if (eAudioMode != AudioParam.eAudioMode)
-					return true;
+          return true;
 				break;
 
 			case AC_CELP:
 				if (bCELPCRC != AudioParam.bCELPCRC)
-					return true;
+          return true;
 				if (iCELPIndex != AudioParam.iCELPIndex)
-					return true;
+          return true;
 				break;
 
 			case AC_HVXC:
 				if (eHVXCRate != AudioParam.eHVXCRate)
-					return true;
+          return true;
 				if (bHVXCCRC != AudioParam.bHVXCCRC)
-					return true;
+          return true;
 				break;
 			}
 			return false;
@@ -263,22 +263,22 @@ enum ERecState {RS_TRACKING, RS_ACQUISITION};
 		_BOOLEAN operator!=(const CDataParam DataParam)
 		{
 			if (iStreamID != DataParam.iStreamID)
-				return true;
+        return true;
 			if (ePacketModInd != DataParam.ePacketModInd)
-				return true;
+        return true;
 			if (DataParam.ePacketModInd == PM_PACKET_MODE)
 			{
 				if (eDataUnitInd != DataParam.eDataUnitInd)
-					return true;
+          return true;
 				if (iPacketID != DataParam.iPacketID)
-					return true;
+          return true;
 				if (iPacketLen != DataParam.iPacketLen)
-					return true;
+          return true;
 				if (eAppDomain != DataParam.eAppDomain)
-					return true;
+          return true;
 				if (DataParam.eAppDomain == AD_DAB_SPEC_APP)
 					if (iUserAppIdent != DataParam.iUserAppIdent)
-						return true;
+            return true;
 			}
 			return false;
 		}
@@ -428,7 +428,7 @@ enum ERecState {RS_TRACKING, RS_ACQUISITION};
 			if (iDuration != nAFS.iDuration)
 				return false;
 
-			return true;
+      return true;
 		}
 
 		_BOOLEAN IsActive(const time_t ltime);
@@ -487,7 +487,7 @@ enum ERecState {RS_TRACKING, RS_ACQUISITION};
 				if (veciCIRAFZones[i] != nAFR.veciCIRAFZones[i])
 					return false;
 
-			return true;
+      return true;
 		}
 
 		vector<int> veciCIRAFZones;
@@ -542,7 +542,7 @@ enum ERecState {RS_TRACKING, RS_ACQUISITION};
 			if (iSystemID != sd.iSystemID)
 				return false;
 
-			return true;
+      return true;
 		}
 		bool operator!=(const CServiceDefinition& sd) const { return !(*this==sd); }
 
@@ -594,7 +594,7 @@ enum ERecState {RS_TRACKING, RS_ACQUISITION};
 			if (bIsSyncMultplx != md.bIsSyncMultplx)
 				return false;
 
-			return true;
+      return true;
 		}
 
 		vector<int> veciServRestrict;
@@ -604,7 +604,7 @@ enum ERecState {RS_TRACKING, RS_ACQUISITION};
 	class COtherService: public CServiceDefinition
 	{
 	public:
-		COtherService(): CServiceDefinition(), bSameService(true),
+    COtherService(): CServiceDefinition(), bSameService(true),
 			iShortID(0), iServiceID(SERV_ID_NOT_USED)
 		{
 		}
@@ -640,7 +640,7 @@ enum ERecState {RS_TRACKING, RS_ACQUISITION};
 			if (iServiceID != nAF.iServiceID)
 				return false;
 
-			return true;
+      return true;
 		}
 
 		string ServiceID() const;
@@ -858,7 +858,7 @@ enum ERecState {RS_TRACKING, RS_ACQUISITION};
 		// Constructor
 		CFrontEndParameters():
 			eSMeterCorrectionType(S_METER_CORRECTION_TYPE_CAL_FACTOR_ONLY), rSMeterBandwidth(10000.0),
-				rDefaultMeasurementBandwidth(10000.0), bAutoMeasurementBandwidth(true), rCalFactorAM(0.0),
+        rDefaultMeasurementBandwidth(10000.0), bAutoMeasurementBandwidth(true), rCalFactorAM(0.0),
 				rCalFactorDRM(0.0), rIFCentreFreq(12000.0)
 			{}
 		CFrontEndParameters(const CFrontEndParameters& p):
@@ -884,7 +884,7 @@ enum ERecState {RS_TRACKING, RS_ACQUISITION};
 		_REAL rSMeterBandwidth; // The bandwidth the S-meter uses to do the measurement
 
 		_REAL rDefaultMeasurementBandwidth; // Bandwidth to do measurement if not synchronised
-		_BOOLEAN bAutoMeasurementBandwidth; // true: use the current FAC bandwidth if locked, false: use default bandwidth always
+    _BOOLEAN bAutoMeasurementBandwidth; // true: use the current FAC bandwidth if locked, false: use default bandwidth always
 		_REAL rCalFactorAM;
 		_REAL rCalFactorDRM;
 		_REAL rIFCentreFreq;
diff --git a/qsstv/drmtx/common/SDC/SDCTransmit.cpp b/qsstv/drmtx/common/SDC/SDCTransmit.cpp
index 0f53da4..d7b47df 100644
--- a/qsstv/drmtx/common/SDC/SDCTransmit.cpp
+++ b/qsstv/drmtx/common/SDC/SDCTransmit.cpp
@@ -454,16 +454,10 @@ void CSDCTransmit::DataEntityType9(CVector<_BINARY>& vecbiData, int ServiceID,
 		vecbiData.Enqueue((uint32_t) 0, 1);
 
 		/* CELP_CRC */
-		switch (Parameter.Service[ServiceID].AudioParam.bCELPCRC)
-		{
-		case false:
-			vecbiData.Enqueue(0 /* 0 */, 1);
-			break;
+    if (!Parameter.Service[ServiceID].AudioParam.bCELPCRC) vecbiData.Enqueue(0 /* 0 */, 1);
+    else vecbiData.Enqueue(1 /* 1 */, 1);
+
 
-		case true:
-			vecbiData.Enqueue(1 /* 1 */, 1);
-			break;
-		}
 		break;
 
 	case CAudioParam::AC_HVXC:
@@ -480,16 +474,9 @@ void CSDCTransmit::DataEntityType9(CVector<_BINARY>& vecbiData, int ServiceID,
 		}
 
 		/* HVXC CRC */
-		switch (Parameter.Service[ServiceID].AudioParam.bHVXCCRC)
-		{
-		case false:
-			vecbiData.Enqueue(0 /* 0 */, 1);
-			break;
+    if (!Parameter.Service[ServiceID].AudioParam.bHVXCCRC) vecbiData.Enqueue(0 /* 0 */, 1);
+    else vecbiData.Enqueue(1 /* 1 */, 1);
 
-		case true:
-			vecbiData.Enqueue(1 /* 1 */, 1);
-			break;
-		}
 		break;
 	}
 
@@ -514,28 +501,13 @@ void CSDCTransmit::DataEntityType9(CVector<_BINARY>& vecbiData, int ServiceID,
 	}
 
 	/* Text flag */
-	switch (Parameter.Service[ServiceID].AudioParam.bTextflag)
-	{
-	case false:
-		vecbiData.Enqueue(0 /* 0 */, 1);
-		break;
-
-	case true:
-		vecbiData.Enqueue(1 /* 1 */, 1);
-		break;
-	}
+  if (!Parameter.Service[ServiceID].AudioParam.bTextflag) vecbiData.Enqueue(0 /* 0 */, 1);
+  else vecbiData.Enqueue(1 /* 1 */, 1);
 
 	/* Enhancement flag */
-	switch (Parameter.Service[ServiceID].AudioParam.bEnhanceFlag)
-	{
-	case false:
-		vecbiData.Enqueue(0 /* 0 */, 1);
-		break;
+  if (!Parameter.Service[ServiceID].AudioParam.bEnhanceFlag) vecbiData.Enqueue(0 /* 0 */, 1);
+  else 	vecbiData.Enqueue(1 /* 1 */, 1);
 
-	case true:
-		vecbiData.Enqueue(1 /* 1 */, 1);
-		break;
-	}
 
 	/* Coder field */
 	if (Parameter.Service[ServiceID].AudioParam.
diff --git a/qsstv/drmtx/common/csoundout.cpp b/qsstv/drmtx/common/csoundout.cpp
index bdc8e68..c77b966 100644
--- a/qsstv/drmtx/common/csoundout.cpp
+++ b/qsstv/drmtx/common/csoundout.cpp
@@ -1,5 +1,5 @@
 #include "csoundout.h"
-#include "qsstvglobal.h"
+#include "appglobal.h"
 #include "dsp/synthes.h"
 #include "utils/vector.h"
 
diff --git a/qsstv/drmtx/common/datadecoding/DABMOT.cpp b/qsstv/drmtx/common/datadecoding/DABMOT.cpp
index a0ed9c8..851f6c8 100644
--- a/qsstv/drmtx/common/datadecoding/DABMOT.cpp
+++ b/qsstv/drmtx/common/datadecoding/DABMOT.cpp
@@ -40,6 +40,7 @@
 #include <cstring>
 #include <iostream>
 #include "drmtx/drmtransmitter.h"
+#include <QDebug>
 
 #if HAVE_LIBZ
 #include <zlib.h>
@@ -49,7 +50,7 @@
 #endif
 #endif
 
-#define RUNINLEN 15
+#define RUNINLEN 24
 #define RUNOUTLEN 10
 
 static int bsrTransportId=2;
@@ -565,7 +566,7 @@ void CMOTDABEnc::prepareSegmentList(unsigned int repetition) // ON4QZ
   segmentList.clear();
   for(j=0;j<repetition;j++)
     {
-      // Fill in segmentHeeder for RUNIN
+      // Fill in segmentHeader for RUNIN
       for(counter=0;counter<RUNINLEN;)
         {
           for(k=0;k<numHeaderSegments;k++)
diff --git a/qsstv/drmtx/common/datadecoding/DABMOT.h b/qsstv/drmtx/common/datadecoding/DABMOT.h
index c45e632..0ba3025 100644
--- a/qsstv/drmtx/common/datadecoding/DABMOT.h
+++ b/qsstv/drmtx/common/datadecoding/DABMOT.h
@@ -39,7 +39,7 @@
 #include <map>
 #include <queue>
 #include <iostream>
-#include "qsstvglobal.h"
+#include "drm.h"
 
 
 /* Definitions ****************************************************************/
diff --git a/qsstv/drmtx/common/datadecoding/MOTSlideShow.cpp b/qsstv/drmtx/common/datadecoding/MOTSlideShow.cpp
index 59189b8..d77d492 100644
--- a/qsstv/drmtx/common/datadecoding/MOTSlideShow.cpp
+++ b/qsstv/drmtx/common/datadecoding/MOTSlideShow.cpp
@@ -31,7 +31,8 @@
 #include "MOTSlideShow.h"
 #include <stdio.h>
 #include <stdlib.h>
-#include "drmtx/drmtransmitter.h"
+#include "drm.h"
+#include "drmtransmitter.h"
 //#include"utils/supportfunctions.h"
 
 
@@ -126,6 +127,6 @@ void CMOTSlideShowEncoder::AddArray (QByteArray *ba,const QString name,const QSt
     int iOldNumObj = vecPicFileNames.Size ();
     vecPicFileNames.Enlarge (1);
     vecPicFileNames[iOldNumObj].arrayPtr = ba;
-    vecPicFileNames[iOldNumObj].name=name;
+    vecPicFileNames[iOldNumObj].name=name.toLatin1();
     vecPicFileNames[iOldNumObj].format=format;
 }
diff --git a/qsstv/drmtx/common/ofdmcellmapping/OFDMCellMapping.cpp b/qsstv/drmtx/common/ofdmcellmapping/OFDMCellMapping.cpp
index 6a020da..02bfa44 100644
--- a/qsstv/drmtx/common/ofdmcellmapping/OFDMCellMapping.cpp
+++ b/qsstv/drmtx/common/ofdmcellmapping/OFDMCellMapping.cpp
@@ -32,6 +32,20 @@
 /******************************************************************************\
 * OFDM cells mapping														   *
 \******************************************************************************/
+
+/* Dummy cells for the MSC ****************************************************/
+/* Already normalized */
+const _COMPLEX cDummyCells64QAM[2] = {
+  _COMPLEX(0.1543033499f,  0.1543033499f),
+  _COMPLEX(0.1543033499f, -0.1543033499f)
+};
+
+const _COMPLEX cDummyCells16QAM[2] = {
+  _COMPLEX(0.3162277660f,  0.3162277660f),
+  _COMPLEX(0.3162277660f, -0.3162277660f)
+};
+
+
 void COFDMCellMapping::ProcessDataInternal(CParameter& TransmParam)
 {
 	
diff --git a/qsstv/drmtx/common/soundinterface.h b/qsstv/drmtx/common/soundinterface.h
index 43e3709..0ca34ca 100644
--- a/qsstv/drmtx/common/soundinterface.h
+++ b/qsstv/drmtx/common/soundinterface.h
@@ -28,7 +28,7 @@
 
 #ifndef _SOUNDINTERFACE_H
 #define _SOUNDINTERFACE_H
-#include "qsstvglobal.h"
+#include "appglobal.h"
 #include "utils/vector.h"
 
 //class CSoundInInterface : public CSelectionInterface
diff --git a/qsstv/drmtx/common/tables/TableCarMap.h b/qsstv/drmtx/common/tables/TableCarMap.h
index 53c0197..23a2639 100644
--- a/qsstv/drmtx/common/tables/TableCarMap.h
+++ b/qsstv/drmtx/common/tables/TableCarMap.h
@@ -222,17 +222,6 @@ const int iScatPilGainRobModB[2][NUM_BOOSTED_SCAT_PILOTS] = {
 };
 
 
-/* Dummy cells for the MSC ****************************************************/
-/* Already normalized */
-const _COMPLEX cDummyCells64QAM[2] = {
-  _COMPLEX(0.1543033499f,  0.1543033499f),
-  _COMPLEX(0.1543033499f, -0.1543033499f)
-};
-
-const _COMPLEX cDummyCells16QAM[2] = {
-  _COMPLEX(0.3162277660f,  0.3162277660f),
-  _COMPLEX(0.3162277660f, -0.3162277660f)
-};
 
 const int iScatPilGainRobModE[2][NUM_BOOSTED_SCAT_PILOTS] = {
 	{1,29, 0, 0},
diff --git a/qsstv/drmtx/common/util/Buffer.h b/qsstv/drmtx/common/util/Buffer.h
index 20b4787..58f3652 100644
--- a/qsstv/drmtx/common/util/Buffer.h
+++ b/qsstv/drmtx/common/util/Buffer.h
@@ -29,9 +29,9 @@
 
 #if !defined(PUFFER_H__3B0BA660_CA63_4344_BB2B_23E7A0D31912__INCLUDED_)
 #define PUFFER_H__3B0BA660_CA63_4344_BB2B_23E7A0D31912__INCLUDED_
-#include <qsstvglobal.h>
+#include "appglobal.h"
 #include "../GlobalDefinitions.h"
-#include "utils/vector.h"
+#include "vector.h"
 
 
 /* Classes ********************************************************************/
@@ -201,7 +201,7 @@ template<class TData> void CCyclicBuffer<TData>::Clear()
 	iPut = 0;
 	iGet = 0;
 	iBufferState = BS_EMPTY;
-	this->bRequestFlag = false;
+  this->bRequestFlag = false;
 }
 
 template<class TData> CVectorEx<TData>* CCyclicBuffer<TData>::Get(const int iRequestedSize)
diff --git a/qsstv/drmtx/drmparams.cpp b/qsstv/drmtx/drmparams.cpp
new file mode 100644
index 0000000..8accf0f
--- /dev/null
+++ b/qsstv/drmtx/drmparams.cpp
@@ -0,0 +1,35 @@
+#include "drmparams.h"
+#include "configparams.h"
+
+int numTxFrames;
+drmTxParams drmParams;
+QList<short unsigned int> fixBlockList;
+
+drmTxParams modeToParams(unsigned int mode)
+{
+  drmTxParams prm;
+  prm.robMode=mode/10000;
+  mode-=(mode/10000)*10000;
+  prm.bandwith=mode/1000;
+  mode-=(mode/1000)*1000;
+  prm.protection=mode/100;
+  mode-=(mode/100)*100;
+  prm.qam=mode/10;
+  prm.interleaver=0;
+  prm.callsign=myCallsign;
+  return prm;
+}
+
+unsigned int paramsToMode(drmTxParams prm)
+{
+  uint mode=1;
+  mode+=prm.robMode*10000;
+  mode+=prm.bandwith*1000;
+  mode+=prm.protection*100;
+  mode+=prm.qam*10;
+  mode+=prm.interleaver;
+  return mode;
+}
+
+
+
diff --git a/qsstv/drmtx/drmparams.h b/qsstv/drmtx/drmparams.h
new file mode 100644
index 0000000..0eab018
--- /dev/null
+++ b/qsstv/drmtx/drmparams.h
@@ -0,0 +1,24 @@
+#ifndef DRMPARAMS_H
+#define DRMPARAMS_H
+
+#include <QString>
+#include <QList>
+
+struct drmTxParams
+{
+  int robMode;
+  int qam;
+  int bandwith;
+  int interleaver;
+  int protection;
+  QString callsign;
+  int reedSolomon;
+};
+
+drmTxParams modeToParams(unsigned int mode);
+unsigned int paramsToMode(drmTxParams prm);
+extern int numTxFrames;
+extern   drmTxParams drmParams;
+extern QList<short unsigned int> fixBlockList;
+
+#endif // DRMPARAMS_H
diff --git a/qsstv/drmtx/drmtransmitter.cpp b/qsstv/drmtx/drmtransmitter.cpp
index 751e37b..02c4734 100644
--- a/qsstv/drmtx/drmtransmitter.cpp
+++ b/qsstv/drmtx/drmtransmitter.cpp
@@ -1,9 +1,10 @@
 #include "drmtransmitter.h"
 #include "configparams.h"
+#include "drm.h"
 
 
 // timing table;
-int numTxFrames;
+
 
 int partTable[BWs][MODES][PROTECTIONS][QAMS]=
 {
@@ -129,30 +130,7 @@ void drmTransmitter::start(bool startTx)
     }
 }
 
-drmTxParams modeToParams(uint mode)
-{
-  drmTxParams prm;
-  prm.robMode=mode/10000;
-  mode-=(mode/10000)*10000;
-  prm.bandwith=mode/1000;
-  mode-=(mode/1000)*1000;
-  prm.protection=mode/100;
-  mode-=(mode/100)*100;
-  prm.qam=mode/10;
-  prm.interleaver=0;
-  prm.callsign=myCallsign;
-  return prm;
-}
 
-uint paramsToMode(drmTxParams prm)
-{
-  uint mode=1;
-  mode+=prm.robMode*10000;
-  mode+=prm.bandwith*1000;
-  mode+=prm.protection*100;
-  mode+=prm.qam*10;
-  return mode;
-}
 
 
 
diff --git a/qsstv/drmtx/drmtransmitter.h b/qsstv/drmtx/drmtransmitter.h
index dff7236..c6c5b2a 100644
--- a/qsstv/drmtx/drmtransmitter.h
+++ b/qsstv/drmtx/drmtransmitter.h
@@ -3,17 +3,7 @@
 
 #include "common/GlobalDefinitions.h"
 #include "common/DrmTransmitter.h"
-
-struct drmTxParams
-{
-  int robMode;
-  int qam;
-  int bandwith;
-  int interleaver;
-  int protection;
-  QString callsign;
-  int reedSolomon;
-};
+#include "drmparams.h"
 
 
 class drmTransmitter
@@ -32,8 +22,5 @@ private:
   double duration;
 };
 
-drmTxParams modeToParams(uint mode);
-uint paramsToMode(drmTxParams prm);
-extern int numTxFrames;
 
 #endif // DRMTRANSMITTER_H
diff --git a/qsstv/drmtx/drmtx.cpp b/qsstv/drmtx/drmtx.cpp
new file mode 100644
index 0000000..3fa469a
--- /dev/null
+++ b/qsstv/drmtx/drmtx.cpp
@@ -0,0 +1,330 @@
+#include "drmtx.h"
+#include "appglobal.h"
+#include "soundbase.h"
+#include "dispatcher.h"
+#include "drmtransmitter.h"
+#include "drmparams.h"
+#include "reedsolomoncoder.h"
+#include "hybridcrypt.h"
+#include "configparams.h"
+#include "txwidget.h"
+#include "ftp.h"
+#include "hybridcrypt.h"
+
+#include <QFileInfo>
+
+
+
+
+drmTx::drmTx(QObject *parent) :
+  QObject(parent)
+{
+  txDRM=new drmTransmitter;
+  txList.clear();
+  notifyIntf=NULL;
+
+}
+
+drmTx::~drmTx()
+{
+  delete txDRM;
+}
+
+void drmTx::init()
+{
+  if(notifyIntf==NULL)
+  {
+      notifyIntf = new ftpInterface("HybridTXNotify");
+      connect(notifyIntf, SIGNAL(notification(QString)), this, SLOT(rxNotification(QString)));
+  }
+}
+
+void drmTx::start()
+{
+  txDRM->start(true);
+}
+
+
+
+bool drmTx::initDRMImage(bool binary,QString fileName)
+{
+  eRSType rsType;
+  reedSolomonCoder rsd;
+  QString fn;
+  QString ext;
+  QFileInfo finf;
+  QFile inf;
+  hybridCrypt hc;
+  setTxParams(drmParams);
+  // we need to save it as a jpg file
+  if(binary)
+    {
+      finf.setFile(fileName);
+    }
+  else
+    {
+      finf.setFile(txWidgetPtr->getImageViewerPtr()->getFilename());
+    }
+  if(useHybrid)
+    {
+      fn="de_"+myCallsign+"-1-"+finf.baseName();
+    }
+  else
+    {
+      fn=QDateTime::currentDateTime().toUTC().toString("yyyyMMddHHmmss");
+      fn+="-"+finf.baseName();
+    }
+  ext=finf.suffix();
+  fixBlockList.clear();
+  if(txList.count()>5) txList.removeFirst();
+  txList.append(txSession());
+  txList.last().filename=fn;
+  txList.last().extension=ext;
+  if(!useHybrid)
+    {
+      txList.last().drmParams=drmTxParameters;
+      if(binary)
+        {
+          inf.setFileName(fileName);
+          if(!inf.open(QIODevice::ReadOnly))
+            {
+              return false;
+            }
+          txList.last().ba=inf.readAll();
+
+        }
+      else
+        {
+          if(!txWidgetPtr->getImageViewerPtr()->copyToBuffer(&(txList.last().ba)))
+          {
+              return false;
+          }
+        }
+
+      rsType=(eRSType)txList.last().drmParams.reedSolomon;
+      baDRM=txList.last().ba;
+      if(rsType!=RSTNONE)
+        {
+          rsd.encode(baDRM,txList.last().extension,rsType);
+          txDRM->init(&baDRM,txList.last().filename,rsTypeStr[rsType],txList.last().drmParams);
+        }
+      else
+        {
+          txDRM->init(&baDRM,txList.last().filename,txList.last().extension,txList.last().drmParams);
+        }
+    }
+  else
+    {
+      txList.last().drmParams.bandwith=1; // bw 2.2
+      txList.last().drmParams.robMode=2;  // mode E
+      txList.last().drmParams.interleaver=0; // long
+      txList.last().drmParams.protection=0; // high
+      txList.last().drmParams.qam=0; // 4bit QAM
+      txList.last().drmParams.callsign=myCallsign;
+
+      // we have to fill in the body
+      txList.last().ba.clear();
+      hc.enCrypt(&txList.last().ba);
+      txDRM->init(&txList.last().ba,txList.last().filename,txList.last().extension,txList.last().drmParams);
+      if(!ftpDRMHybrid(txList.last().filename+"."+finf.suffix()))
+      {
+        return false;
+      }
+      ftpDRMHybridNotifyCheck(txList.last().filename+"."+finf.suffix());
+    }
+  // transportID is set
+  txList.last().transportID=txTransportID;
+  return true;
+}
+
+bool drmTx::ftpDRMHybrid(QString fn)
+{
+//  char *data;
+//  unsigned int ct;
+  eftpError ftpResult;
+  QByteArray testBA;
+  QByteArray ba;
+  QTemporaryFile ftmp;
+  ftpInterface ftpIntf("HybridTX");
+  hybridCrypt hc;
+  ftpIntf.setupConnection(hc.host(),hc.port(),hc.user(),hc.passwd(),hc.dir()+"/"+hybridFtpHybridFilesDirectory);
+  txWidgetPtr->getImageViewerPtr()->copyToBuffer(&ba);
+  if(!ftmp.open()) return false;
+  ftmp.write(ba);
+  ftmp.close();
+
+  ftpResult=ftpIntf.uploadFile(ftmp.fileName(),fn,true);
+  switch(ftpResult)
+    {
+    case FTPCANCELED:
+      ftpErrorStr="Connection Canceled";
+    break;
+    case FTPOK:
+      break;
+    case FTPERROR:
+      ftpErrorStr=ftpIntf.getLastError();
+      break;
+    case FTPNAMEERROR:
+      ftpErrorStr="Error in filename";
+      break;
+    case FTPTIMEOUT:
+      ftpErrorStr="FTP timed out";
+      break;
+    }
+  addToLog("sendDRMHybrid",LOGDRMTX);
+  return ftpResult==FTPOK;
+}
+
+
+bool drmTx::ftpDRMHybridNotifyCheck(QString fn)
+{
+  txDRMNotifyEvent *txne;
+  if (!enableHybridNotify) return false;
+  
+  if (enableHybridNotifySpecialServer) {
+     notifyIntf->setupConnection(hybridNotifyRemoteHost, hybridNotifyPort,
+              hybridNotifyLogin, hybridNotifyPassword,
+              hybridNotifyRemoteDir+"/"+hybridNotifyDir);
+     }
+  else {
+     // notification to vk4aes.com (EasyPal compatible)
+     notifyIntf->setupConnection("vk4aes.com",21,"vk4aes","10mar1936","/RxOkNotifications1");
+                    
+     // or notification to image server
+     //notifyIntf->setupConnection(hc.host(),hc.port(),hc.user(),hc.passwd(),hc.dir()+"/RxOkNotifications1");
+     }
+     
+  txne = new txDRMNotifyEvent("");
+  QApplication::postEvent( dispatcherPtr, txne );
+  
+  notifyIntf->startNotifyCheck(fn, 15, 60/15, true);
+  return true;
+}
+
+void drmTx::rxNotification(QString info)
+{
+  if (info != "") {
+     txDRMNotifyAppendEvent *txne = new txDRMNotifyAppendEvent(info);
+     QApplication::postEvent( dispatcherPtr, txne );
+  }
+}
+
+
+double  drmTx::calcTxTime(int overheadTime)
+{
+  double tim=0;
+  //  tim= soundIOPtr->getPlaybackStartupTime();
+  tim+=overheadTime;
+  tim+=txDRM->getDuration();
+  return tim;
+}
+
+int drmTx::processFIX(QByteArray bsrByteArray)
+{
+  int i,j;
+  bool inSeries;
+//  bool extended; // todo check use of extended
+  bool done;
+  int block;
+  int trID,lastBlock;
+
+  fixBlockList.clear();
+  QString str(bsrByteArray);
+  str.replace("\r","");
+  //  information is in the QByteArray ba
+  QStringList sl;
+  sl=str.split("\n",QString::SkipEmptyParts);
+
+  if(sl.at(1)!="H_OK")
+    {
+      return -1;
+    }
+  trID=sl.at(0).toUInt();
+  lastBlock=sl.at(3).toUInt();
+  fixBlockList.append(lastBlock++);
+  inSeries=false;
+  done=false;
+//  extended=false;
+  for(i=4;(!done)&&i<sl.count();i++)
+    {
+      block=sl.at(i).toInt();
+      if(block==-99)
+        {
+          done=true;
+          i++;
+          break;
+        }
+      if(block<0) inSeries=true;
+      else
+        {
+          if(inSeries)
+            {
+              inSeries=false;
+              for(j=lastBlock;j<block;j++) fixBlockList.append(j);
+            }
+          fixBlockList.append(block);
+          lastBlock=block+1;
+        }
+    }
+  // check if we have a filename beyond -99
+  if((i+1)<sl.count()) // we need an additional 2 entries (filename and mode)
+    {
+//      extended=true;
+      //      fileName=sl.at(i++); // not used at this moment
+    }
+  return trID;
+}
+
+
+void drmTx::initDRMBSR(QByteArray *ba)
+{
+  baDRM=*ba;
+  fixBlockList.clear();
+  txDRM->init(&baDRM,"bsr","bin",drmTxParameters);
+  addToLog(QString("bsr.bin send %1").arg(baDRM.size()),LOGPERFORM);
+}
+
+bool drmTx::initDRMFIX(txSession *sessionPtr)
+{
+  reedSolomonCoder rsd;
+  eRSType rsType;
+  rsType=(eRSType)sessionPtr->drmParams.reedSolomon;
+  baDRM=sessionPtr->ba;
+  if(rsType!=RSTNONE)
+    {
+      rsd.encode(baDRM,sessionPtr->extension,rsType);
+      txDRM->init(&baDRM,sessionPtr->filename,rsTypeStr[rsType],sessionPtr->drmParams);
+    }
+  else
+    {
+      txDRM->init(&baDRM,sessionPtr->filename,sessionPtr->extension,sessionPtr->drmParams);
+    }
+  return true;
+}
+
+
+void drmTx::sendBSR(QByteArray *p,drmTxParams dp)
+{
+  setTxParams(dp);
+  initDRMBSR(p);
+  dispatcherPtr->startTX(txFunctions::TXSENDDRMBSR);
+  addToLog("sendDRMBSR",LOGDRMTX);
+}
+
+txSession *drmTx::getSessionPtr(uint transportID)
+{
+  int i;
+  for(i=0;i<txList.count();i++)
+    {
+      if(txList.at(i).transportID==transportID)
+        {
+          return &txList[i];
+        }
+    }
+  return NULL;
+}
+
+void drmTx::applyTemplate(QString templateFilename, bool useTemplate, imageViewer *ivPtr)
+{
+  ivPtr->setParam(templateFilename,useTemplate);
+}
diff --git a/qsstv/drmtx/drmtx.h b/qsstv/drmtx/drmtx.h
new file mode 100644
index 0000000..c535c42
--- /dev/null
+++ b/qsstv/drmtx/drmtx.h
@@ -0,0 +1,68 @@
+#ifndef DRMTX_H
+#define DRMTX_H
+
+
+#include <QObject>
+
+#include "drmtransmitter.h"
+#include "reedsolomoncoder.h"
+#include "ftp.h"
+
+class imageViewer;
+
+struct txSession
+{
+  drmTxParams drmParams;
+  QByteArray ba;  // contains the image data in jpg, jp2 .... format
+  uint transportID;
+  QString filename;
+  QString extension;
+};
+
+
+
+class drmTransmitter;
+
+class drmTx : public QObject
+{
+  Q_OBJECT
+public:
+  explicit drmTx(QObject *parent = 0);
+  ~drmTx();
+  void init();
+  void start();
+  bool initDRMImage(bool binary, QString fileName);
+  bool ftpDRMHybridNotifyCheck(QString fn);
+  
+  void sendBSR(QByteArray *p,drmTxParams dp);
+  int processFIX(QByteArray bsrByteArray);
+  void initDRMBSR(QByteArray *ba);
+  bool initDRMFIX(txSession *sessionPtr);
+//  bool initDRMFIX(QString fileName,QString extension,eRSType rsType,int mode);
+  txSession *getSessionPtr(uint transportID);
+  void applyTemplate(QString templateFilename, bool useTemplate, imageViewer *ivPtr);
+
+
+  void setTxParams(drmTxParams params)
+  {
+    drmTxParameters=params;
+  }
+ double calcTxTime(int overheadTime);
+
+signals:
+
+private slots:
+  void rxNotification(QString info);
+
+private:
+    void runRx();
+    bool ftpDRMHybrid(QString fn);
+    drmTransmitter *txDRM;
+    QList <txSession> txList;
+    drmTxParams drmTxParameters;
+    QByteArray baDRM;
+    QString ftpErrorStr;
+    ftpInterface *notifyIntf;
+};
+
+#endif // DRMTX_H
diff --git a/qsstv/dsp/downsamplefilter.cpp b/qsstv/dsp/downsamplefilter.cpp
index d953aa9..863159e 100644
--- a/qsstv/dsp/downsamplefilter.cpp
+++ b/qsstv/dsp/downsamplefilter.cpp
@@ -19,49 +19,70 @@
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 #include "downsamplefilter.h"
-#include "configparams.h"
-#include "utils/supportfunctions.h"
+#include "appglobal.h"
+#include "arraydumper.h"
+#include "logging.h"
+
+#include <QDebug>
+
+
+
+#include <math.h>
+
+#define VOLINTEGRATOR 0.5
+
 
-#define VOLINTEGRATOR 0.0001
 
 downsampleFilter::downsampleFilter()
 {
-	filteredDataBuffer=0;
-	filterParams=0;
-	samplesI=0;
-	samplesQ=0;
-	filterLength=0;
-}
+  filteredDataBuffer=0;
+  volumeBuffer=0;
+  filterParams=0;
+  samplesI=0;
+  samplesQ=0;
+  volSamples=0;
+  filterLength=0;
 
-downsampleFilter::~downsampleFilter()
-{
-  if(filteredDataBuffer) delete [] filteredDataBuffer;
-  if(filterParams) delete [] filterParams;
 }
 
-downsampleFilter::downsampleFilter(unsigned int len, const FILTERPARAMTYPE *fparam, unsigned int filterLen, bool scaled)
+downsampleFilter::downsampleFilter(unsigned int len, bool scaled)
 {
   filteredDataBuffer=0;
-	filterParams=0;
-	samplesI=0;
-	samplesQ=0;
-	filterLength=0;
-  setFilterParams(fparam,filterLen,scaled);
+  volumeBuffer=0;
+  filterParams=0;
+  samplesI=0;
+  samplesQ=0;
+  volSamples=0;
+  filterLength=0;
+  setFilterParams(scaled);
   allocate(len);
   init();
 }
 
+downsampleFilter::~downsampleFilter()
+{
+  if(filteredDataBuffer) delete [] filteredDataBuffer;
+  if(filterParams) delete [] filterParams;
+  if(samplesI) delete [] samplesI;
+  if(samplesQ) delete [] samplesQ;
+  if(volSamples) delete [] volSamples;
+}
+
+
+
 void downsampleFilter::allocate(unsigned int len)
 {
-	length=len;
-	if(filteredDataBuffer) delete [] filteredDataBuffer;
-  filteredDataBuffer=new DSPFLOAT [len];
+  length=len;
+  if(filteredDataBuffer) delete [] filteredDataBuffer;
+  filteredDataBuffer=new FILTERPARAMTYPE [length];
+  volumeBuffer=new unsigned int [length/4+CONVDELAY];
 }
 
 
 void downsampleFilter::init()
 {
   unsigned int i;
+  first=true;
   for(i=0;i<filterLength;i++)
     {
       samplesI[i]=0;
@@ -71,35 +92,44 @@ void downsampleFilter::init()
     {
       filteredDataBuffer[i]=0;
     }
-  avgVolume=0;
+  for(i=0;i<CONVLENGTH;i++)
+    {
+      volSamples[i]=0;
+    }
+  for(i=0;i<length/4+CONVDELAY;i++)
+    {
+      volumeBuffer[i]=0;
+    }
+  avgVolumeDb=0;
+//  rxBytes=0;
+//  avgVolume=0;
 }
 
-void downsampleFilter::setFilterParams(const FILTERPARAMTYPE *fparam,unsigned filterLen,bool scaled)
+void downsampleFilter::setFilterParams(bool scaled)
 {
-	unsigned int i;
-  if(filterLen!=filterLength)
-    {
-      filterLength=filterLen;
-      if(filterParams) delete [] filterParams;
-      filterParams=new FILTERPARAMTYPE [filterLength];
-      if(samplesI) delete [] samplesI;
-      if(samplesQ) delete [] samplesQ;
-      samplesI=new DSPFLOAT[filterLength];
-      samplesQ=new DSPFLOAT[filterLength];
-    }
+  unsigned int i;
+
+  filterLength=DSAMPLEFILTERLEN;
+  if(filterParams) delete [] filterParams;
+  filterParams=new FILTERPARAMTYPE [filterLength];
+  if(samplesI) delete [] samplesI;
+  if(samplesQ) delete [] samplesQ;
+  samplesI=new FILTERPARAMTYPE[filterLength];
+  samplesQ=new FILTERPARAMTYPE[filterLength];
+  volSamples=new DSPFLOAT[CONVLENGTH];
   zeroes=filterLength-1;
   ssize=(zeroes)*sizeof(DSPFLOAT);
 
 
   DSPFLOAT gain=0;
-	for(i=0;i<filterLength;i++)
-		{
-      gain+=fparam[i];
-		}
   for(i=0;i<filterLength;i++)
     {
-      if(scaled) filterParams[i]=fparam[i]/gain;
-      else filterParams[i]=fparam[i];
+      gain+=downSampleFilterParam[i];
+    }
+  for(i=0;i<filterLength;i++)
+    {
+      if(scaled) filterParams[i]=downSampleFilterParam[i]/gain;
+      else filterParams[i]=downSampleFilterParam[i];
     }
   addToLog(QString("filtergain:=%1").arg(gain),LOGPERFORM);
 }
@@ -109,17 +139,20 @@ void downsampleFilter::setFilterParams(const FILTERPARAMTYPE *fparam,unsigned fi
 void downsampleFilter::downSample4(short int *data)
 {
   unsigned int i,k;
+  DSPFLOAT tmpVol;
   FILTERPARAMTYPE res;
   const FILTERPARAMTYPE *cf1;
-  DSPFLOAT *fp1;
+  FILTERPARAMTYPE *fp1;
   FILTERPARAMTYPE res0,res1,res2,res3;
-//  int zeroes=filterLength-1;
+//  arrayDump("din",data,RXSTRIPE,true,false);
+  memmove(volumeBuffer,volumeBuffer+length/4,CONVDELAY*sizeof(unsigned int));
+
   for (k=0;k<length;k+=4)
     {
       res0=res1=res2=res3=0;
       cf1 = filterParams;
       fp1 = samplesI;
-      memmove(samplesI+4, samplesI, (filterLength-4)*sizeof(DSPFLOAT));
+      memmove(samplesI+4, samplesI, (filterLength-4)*sizeof(FILTERPARAMTYPE));
       samplesI[3]=data[k];
       samplesI[2]= data[k+1];
       samplesI[1]= data[k+2];
@@ -132,15 +165,212 @@ void downsampleFilter::downSample4(short int *data)
           res3+=(*(fp1+3))*(*(cf1+3));
         }
       res=res0+res1+res2+res3;
-      filteredDataBuffer[k/4]=(DSPFLOAT)res;
-//        filteredDataBuffer[k/4]=samplesI[filterLength/2];
-      avgVolume=avgVolume*(1-VOLINTEGRATOR)+(10*log(res*res)-145)*VOLINTEGRATOR;
+      filteredDataBuffer[k/4]=res;
+      memmove(volSamples+1,volSamples,(CONVLENGTH-1)*sizeof(DSPFLOAT));
+      volSamples[0]=sqrt(res*res)*1.35;
+      tmpVol=0;
+      for(i=0;i<CONVLENGTH;i++)
+        {
+          tmpVol+=volSamples[i];
+        }
+      volumeBuffer[k/4+CONVDELAY]=(unsigned int)rint(tmpVol/CONVLENGTH);
 
     }
-
+  avgVolumeDb=20*log(volumeBuffer[length/8])-130;
 }
 
 
 
+// rFIR
+// localSamplingrate = 48000.000000
+// number of taps = 181
+// Band0 Lower=0.000000, Upper=2800.000000, Desired=2.000000, Weight=1.000000
+// Band1 Lower=3500.000000, Upper=24000.000000, Desired=0.000000, Weight=10.000000
+//Coefficients:
+const FILTERPARAMTYPE downSampleFilterParam[DSAMPLEFILTERLEN]=
+{
+  -0.000726805371518309,
+  0.00212924341308074,
+  0.00209607515518649,
+  0.00258616863859503,
+  0.00312451941666017,
+  0.00351845737963003,
+  0.00365705393269608,
+  0.00347249738871369,
+  0.00294091277303658,
+  0.0020876784816062,
+  0.000989968644394825,
+  -0.000229536963193281,
+  -0.00141602838562286,
+  -0.00240355817861836,
+  -0.00303972686902264,
+  -0.00321109351395581,
+  -0.00286490657890866,
+  -0.00202335724664101,
+  -0.000787353876891696,
+  0.000672176418542286,
+  0.00213509217135987,
+  0.00336342008182743,
+  0.00413819652648567,
+  0.00429713243771618,
+  0.00376510708747164,
+  0.00257360789092004,
+  0.000863764615466942,
+  -0.001127792766604,
+  -0.00309663047609688,
+  -0.00472159091592147,
+  -0.0056999360876337,
+  -0.00583031339786136,
+  -0.00501710522705826,
+  -0.00331719263251476,
+  -0.000939525687925027,
+  0.00178104445626093,
+  0.00442648054106535,
+  0.00655781811862848,
+  0.00778470951795523,
+  0.00783457506289861,
+  0.00660582869791214,
+  0.00419854005559208,
+  0.000913611071336271,
+  -0.00278058458658644,
+  -0.00631166219807734,
+  -0.00908863549508422,
+  -0.0105968380602393,
+  -0.0104880827011458,
+  -0.00865059863609764,
+  -0.00524633117469452,
+  -0.000706169042697737,
+  0.00431853795460012,
+  0.00904473602072652,
+  0.0126740048689635,
+  0.0145210513202929,
+  0.0141339163209834,
+  0.0113860335748772,
+  0.00652568850180913,
+  0.000164013828194059,
+  -0.00678721495092159,
+  -0.0132450608783663,
+  -0.0181056223037124,
+  -0.0204244364948377,
+  -0.0195817855693473,
+  -0.0154088583976291,
+  -0.00825851456253797,
+  0.00100265183405794,
+  0.0110798178134256,
+  0.0204127669048817,
+  0.0273919133377699,
+  0.0306039642231267,
+  0.0290707628785015,
+  0.0224466971136873,
+  0.0111424375360727,
+  -0.00364878906373264,
+  -0.0200329664559621,
+  -0.0356023553816112,
+  -0.0477088371694707,
+  -0.053792701556172,
+  -0.0517250893361419,
+  -0.0401198095407566,
+  -0.0185705541637443,
+  0.0122205143308298,
+  0.0504455099076038,
+  0.093330253141237,
+  0.13739759113622,
+  0.178828272483524,
+  0.213871703505128,
+  0.239265440205684,
+  0.252600612879519,
+  0.252600612879519,
+  0.239265440205684,
+  0.213871703505128,
+  0.178828272483524,
+  0.13739759113622,
+  0.093330253141237,
+  0.0504455099076038,
+  0.0122205143308298,
+  -0.0185705541637443,
+  -0.0401198095407566,
+  -0.0517250893361419,
+  -0.053792701556172,
+  -0.0477088371694707,
+  -0.0356023553816112,
+  -0.0200329664559621,
+  -0.00364878906373264,
+  0.0111424375360727,
+  0.0224466971136873,
+  0.0290707628785015,
+  0.0306039642231267,
+  0.0273919133377699,
+  0.0204127669048817,
+  0.0110798178134256,
+  0.00100265183405794,
+  -0.00825851456253797,
+  -0.0154088583976291,
+  -0.0195817855693473,
+  -0.0204244364948377,
+  -0.0181056223037124,
+  -0.0132450608783663,
+  -0.00678721495092159,
+  0.000164013828194059,
+  0.00652568850180913,
+  0.0113860335748772,
+  0.0141339163209834,
+  0.0145210513202929,
+  0.0126740048689635,
+  0.00904473602072652,
+  0.00431853795460012,
+  -0.000706169042697737,
+  -0.00524633117469452,
+  -0.00865059863609764,
+  -0.0104880827011458,
+  -0.0105968380602393,
+  -0.00908863549508422,
+  -0.00631166219807734,
+  -0.00278058458658644,
+  0.000913611071336271,
+  0.00419854005559208,
+  0.00660582869791214,
+  0.00783457506289861,
+  0.00778470951795523,
+  0.00655781811862848,
+  0.00442648054106535,
+  0.00178104445626093,
+  -0.000939525687925027,
+  -0.00331719263251476,
+  -0.00501710522705826,
+  -0.00583031339786136,
+  -0.0056999360876337,
+  -0.00472159091592147,
+  -0.00309663047609688,
+  -0.001127792766604,
+  0.000863764615466942,
+  0.00257360789092004,
+  0.00376510708747164,
+  0.00429713243771618,
+  0.00413819652648567,
+  0.00336342008182743,
+  0.00213509217135987,
+  0.000672176418542286,
+  -0.000787353876891696,
+  -0.00202335724664101,
+  -0.00286490657890866,
+  -0.00321109351395581,
+  -0.00303972686902264,
+  -0.00240355817861836,
+  -0.00141602838562286,
+  -0.000229536963193281,
+  0.000989968644394825,
+  0.0020876784816062,
+  0.00294091277303658,
+  0.00347249738871369,
+  0.00365705393269608,
+  0.00351845737963003,
+  0.00312451941666017,
+  0.00258616863859503,
+  0.00209607515518649,
+  0.00212924341308074,
+  -0.000726805371518309
+};
+
+
 
 
diff --git a/qsstv/dsp/downsamplefilter.h b/qsstv/dsp/downsamplefilter.h
index d4b4bc8..1d34a82 100644
--- a/qsstv/dsp/downsamplefilter.h
+++ b/qsstv/dsp/downsamplefilter.h
@@ -20,33 +20,44 @@
  ***************************************************************************/
 #ifndef DOWNSAMPLEFILTER_H
 #define DOWNSAMPLEFILTER_H
-#include "nco.h"
-#include "filterparam.h"
+#include "appdefs.h"
+
+
+#define DSAMPLEFILTERLEN 180
+#define CONVLENGTH 200
+#define CONVDELAY  10
+
+extern const FILTERPARAMTYPE downSampleFilterParam[DSAMPLEFILTERLEN];
 
 class downsampleFilter
 {
 public:
   downsampleFilter();
-  downsampleFilter(unsigned int len, const FILTERPARAMTYPE *fparam, unsigned int filterLen, bool scaled);
+  downsampleFilter(unsigned int len, bool scaled);
   ~downsampleFilter();
 	void allocate(unsigned int dataLength);
-  void setFilterParams(const FILTERPARAMTYPE *fparam,unsigned int filterLen,bool scaled);
+  void setFilterParams(bool scaled);
   void downSample4(short int *data);
 //  void downSample4(DSPFLOAT *data, DSPFLOAT *filteredData, unsigned int len);
-  DSPFLOAT *filteredDataPtr() {return filteredDataBuffer;}
+  FILTERPARAMTYPE *filteredDataPtr() {return filteredDataBuffer;}
   void init();
-  DSPFLOAT avgVolume;
+  DSPFLOAT avgVolumeDb;
+  unsigned int *getVolumePtr() {return volumeBuffer;}
 
 private:
 	void normalizeGain();
-  DSPFLOAT *filteredDataBuffer;
+  FILTERPARAMTYPE *filteredDataBuffer;
+  unsigned int *volumeBuffer;
   FILTERPARAMTYPE *filterParams;
 	unsigned int filterLength;
-	DSPFLOAT *samplesI;
-	DSPFLOAT *samplesQ;
+  FILTERPARAMTYPE *samplesI;
+  FILTERPARAMTYPE *samplesQ;
+  DSPFLOAT *volSamples;
 	unsigned int length;
   int zeroes;
   int ssize;
+//  unsigned int rxBytes;
+  bool first;
 
 };
 
diff --git a/qsstv/dsp/filter.cpp b/qsstv/dsp/filter.cpp
index 9acf12a..311509e 100644
--- a/qsstv/dsp/filter.cpp
+++ b/qsstv/dsp/filter.cpp
@@ -1,241 +1,328 @@
-/***************************************************************************
- *   Copyright (C) 2000-2008 by Johan Maes                                 *
- *   on4qz at telenet.be                                                      *
- *   http://users.telenet.be/on4qz                                         *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   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.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- ***************************************************************************/
 #include "filter.h"
-#include "configparams.h"
+#include "nco.h"
 
+filter::filter(efilterType fType, uint dataLenght)
+{
+  filterType=fType;
+  resetPointers();
+  dataLen=dataLenght;
+}
 
 
+filter::~filter()
+{
+  deleteBuffers();
+}
 
 
-filter::filter()
+void filter::init()
 {
-	filteredDataBuffer=0;
-	volumeBuffer=0;
-	filterParams=0;
-	samplesI=0;
-	samplesQ=0;
-	filterLength=0;
+  deleteBuffers();
+  nZeroes=0;
+  nPoles=0;
+  gain=1;
+  avgVolume=0;
+  volumeAttackIntegrator=1;
+  volumeDecayIntegrator=1;
+  prevTemp=0;
+  angleToFc=SAMPLERATE/(2*M_PI);
+  frCenter=0;
 }
 
-filter::~filter()
+void filter::resetPointers()
 {
-  if(filteredDataBuffer) delete [] filteredDataBuffer;
-  if(volumeBuffer) delete [] volumeBuffer;
-  if(filterParams) delete [] filterParams;
+  coefZPtr=NULL;
+  coefPPtr=NULL;
+  sampleBufferIPtr=NULL;
+  sampleBufferQPtr=NULL;
+  sampleBufferYIPtr=NULL;
+  filteredPtr=NULL;
+  volumePtr=NULL;
+  demodPtr=NULL;
 }
 
-filter::filter(unsigned int len, const FILTERPARAMTYPE *fparam, unsigned int filterLen, DSPFLOAT centerFrequency, DSPFLOAT clock, bool scaled, DSPFLOAT volumeIntegrator)
+void filter::deleteBuffers()
 {
-  filteredDataBuffer=0;
-  volumeBuffer=0;
-	filterParams=0;
-	samplesI=0;
-	samplesQ=0;
-	filterLength=0;
-	allocate(len);
-  setFilterParams(fparam,filterLen,centerFrequency,clock,scaled,volumeIntegrator);
-  resIprev=0;
-  resQprev=0;
+  //  if(coefZPtr!=NULL)          delete [] coefZPtr;
+  //  if(coefPPtr!=NULL)          delete [] coefPPtr;
+  if(sampleBufferIPtr!=NULL)  delete [] sampleBufferIPtr;
+  if(sampleBufferQPtr!=NULL)  delete [] sampleBufferQPtr;
+  if(sampleBufferYIPtr!=NULL) delete [] sampleBufferYIPtr;
+  if(filteredPtr!=NULL)       delete [] filteredPtr;
+  if(volumePtr!=NULL)         delete [] volumePtr;
+  if(demodPtr!=NULL)          delete [] demodPtr;
+  resetPointers();
 }
 
-void filter::allocate(unsigned int len)
+
+
+
+void filter::allocate()
 {
-	length=len;
-	if(filteredDataBuffer) delete [] filteredDataBuffer;
-	if(volumeBuffer) delete [] volumeBuffer;
-  filteredDataBuffer=new int [2*len]; // double the length for complex output in IQ filtering -output complex format
-  volumeBuffer=new int [len];
+  uint i;
+  bufSize=nZeroes*sizeof(FILTERPARAMTYPE);
+  sampleBufferIPtr=new FILTERPARAMTYPE[nZeroes+1];
+  sampleBufferQPtr=new FILTERPARAMTYPE[nZeroes+1];
+
+  for(i=0;i<=nZeroes;i++)
+    {
+      sampleBufferIPtr[i]=0;
+      sampleBufferQPtr[i]=0;
+    }
+
+  if(nPoles>0)
+    {
+      sampleBufferYIPtr=new FILTERPARAMTYPE[nPoles+1];
+      for(i=0;i<=nPoles;i++)  sampleBufferYIPtr[i] =0;
+    }
+  volumePtr=new FILTERPARAMTYPE[dataLen];
+  demodPtr=new quint16[dataLen];
+  filteredPtr=new FILTERPARAMTYPE[dataLen];
+  for(i=0;i<dataLen;i++)
+    {
+      volumePtr[i]=0;
+      demodPtr[i]=0;
+      filteredPtr[i]=0;
+    }
+  if(frCenter>0)
+    {
+      nco.init(frCenter/SAMPLERATE);
+    }
 }
 
-void filter::setFilterParams(const FILTERPARAMTYPE *fparam,unsigned filterLen,DSPFLOAT centerFrequency,DSPFLOAT clock,bool scaled,DSPFLOAT volumeIntegrator)
+
+void filter::processFIR(FILTERPARAMTYPE *dataPtr, double *dataOutputPtr)
 {
-	unsigned int i;
-  volIntegrator=volumeIntegrator;
-  if(filterLen!=filterLength)
+  FILTERPARAMTYPE resI=0;
+  FILTERPARAMTYPE *fp1;
+  const FILTERPARAMTYPE *cf1;
+  unsigned int i,k;
+  for (k=0;k<dataLen;k++)
     {
-      filterLength=filterLen;
-      if(filterParams) delete [] filterParams;
-      filterParams=new FILTERPARAMTYPE [filterLength];
-      if(samplesI) delete [] samplesI;
-      if(samplesQ) delete [] samplesQ;
-      samplesI=new DSPFLOAT[filterLength];
-      samplesQ=new DSPFLOAT[filterLength];
+      resI=0;
+      cf1 = coefZPtr;
+      fp1 = sampleBufferIPtr;
+      memmove(sampleBufferIPtr+1, sampleBufferIPtr, bufSize);
+      sampleBufferIPtr[0]=dataPtr[k];
+      for(i=0;i<=nZeroes;i++,fp1++,cf1++)
+        {
+          resI+=(*fp1)*(*cf1);
+        };
+      dataOutputPtr[k]=resI/gain;
+
+      //      double vol=sqrt(resI*resI);
+      //      if (vol>avgVolume) avgVolume=avgVolume*(1-volumeAttackIntegrator)+(volumeAttackIntegrator)*vol;
+      //      else if (vol<avgVolume) avgVolume=avgVolume*(1-volumeDecayIntegrator)+(volumeDecayIntegrator)*vol;
+      //      volumePtr[i]=avgVolume;
     }
-  zeroes=filterLength-1;
-  ssize=(zeroes)*sizeof(DSPFLOAT);
-  frCenter=centerFrequency;
-  nco.init(frCenter/clock);
-  angleToFc=clock/(2*M_PI);
-
-
-	for(i=0;i<filterLength;i++)
-		{
-			samplesI[i]=0;
-			samplesQ[i]=0;
-		}
-  DSPFLOAT gain=0;
-	for(i=0;i<filterLength;i++)
-		{
-      gain+=fparam[i];
-		}
-  for(i=0;i<filterLength;i++)
-    {
-      if(scaled) filterParams[i]=fparam[i]/gain;
-      else filterParams[i]=fparam[i];
+}
 
+void filter::processFIRInt(FILTERPARAMTYPE *dataPtr, quint16 *dataOutputPtr)
+{
+  FILTERPARAMTYPE resI=0;
+  FILTERPARAMTYPE *fp1;
+  const FILTERPARAMTYPE *cf1;
+  unsigned int i,k;
+  for (k=0;k<dataLen;k++)
+    {
+      resI=0;
+      cf1 = coefZPtr;
+      fp1 = sampleBufferIPtr;
+      memmove(sampleBufferIPtr+1, sampleBufferIPtr, bufSize);
+      sampleBufferIPtr[0]=dataPtr[k];
+      for(i=0;i<=nZeroes;i++,fp1++,cf1++)
+        {
+          resI+=(*fp1)*(*cf1);
+        };
+      dataOutputPtr[k]=(quint16)rint(resI/gain);
     }
-  avgVolume=0;
-  addToLog(QString("filtergain:=%1").arg(gain),LOGPERFORM);
 }
 
-void filter::processFM(DSPFLOAT *data)
+
+void filter::processFIRDemod(FILTERPARAMTYPE *dataPtr,FILTERPARAMTYPE *dataOutputPtr)
 {
+  FILTERPARAMTYPE  temp;
+  unsigned int i,k;
   FILTERPARAMTYPE resI=0, resQ=0;
-  int  temp;
-
+  FILTERPARAMTYPE *fp1, *fp2;
   const FILTERPARAMTYPE *cf1;
-  DSPFLOAT *fp1, *fp2;
   FILTERPARAMTYPE discRe,discIm;
-	unsigned int i,k;
-
-
-	for (k=0;k<length;k++)
-		{
-			resI=0;
-			resQ=0;
-			cf1 = filterParams;
-			fp1 = samplesI;
-			fp2 = samplesQ;
-      memmove(samplesI, samplesI+1, ssize);
-      memmove(samplesQ, samplesQ+1, ssize);
-      nco.multiply(samplesI[zeroes],samplesQ[zeroes],data[k]);
-			for(i=0;i<filterLength;i++,fp1++,fp2++,cf1++)
- 				{
-   				resI+=(*fp1)*(*cf1);
-   				resQ+=(*fp2)*(*cf1);
- 				}
-			discRe=resI*resIprev+resQ*resQprev;
-  		discIm=-resQ*resIprev+resQprev*resI;
-  		resIprev=resI;
-  		resQprev=resQ;
-  		if(discRe==0) discRe=0.0001;
-      temp=(int)round(frCenter-atan2(discIm,discRe)*angleToFc);
+
+  for (k=0;k<dataLen;k++)
+    {
+      resI=0;
+      resQ=0;
+      cf1 = coefZPtr;
+      fp1 = sampleBufferIPtr;
+      fp2 = sampleBufferQPtr;
+      memmove(sampleBufferIPtr, sampleBufferIPtr+1, bufSize);
+      memmove(sampleBufferQPtr, sampleBufferQPtr+1, bufSize);
+      nco.multiply(sampleBufferIPtr[nZeroes],sampleBufferQPtr[nZeroes],dataPtr[k]);
+      for(i=0;i<=nZeroes;i++,fp1++,fp2++,cf1++)
+        {
+          resI+=(*fp1)*(*cf1);
+          resQ+=(*fp2)*(*cf1);
+        }
+      resI/=gain;
+      resQ/=gain;
+      discRe=resI*resIprev+resQ*resQprev;
+      discIm=-resQ*resIprev+resQprev*resI;
+      resIprev=resI;
+      resQprev=resQ;
+      if(discRe==0) discRe=0.0001;
+      temp=frCenter-atan2(discIm,discRe)*angleToFc;
       if(temp<500) temp=prevTemp;
       if(temp>2600) temp=prevTemp;
       prevTemp=temp;
-			filteredDataBuffer[k]=temp;
-      avgVolume=avgVolume*(1-volIntegrator)+sqrt(resI*resI+resQ*resQ)*volIntegrator;
-      volumeBuffer[k]=(int)avgVolume;
-		}
+      dataOutputPtr[k]=temp;
+      double vol=sqrt(resI*resI+resQ*resQ);
+      if (vol>avgVolume) avgVolume=avgVolume*(1-volumeAttackIntegrator)+(volumeAttackIntegrator)*vol;
+      else if (vol<avgVolume) avgVolume=avgVolume*(1-volumeDecayIntegrator)+(volumeDecayIntegrator)*vol;
+      volumePtr[i]=avgVolume;
+    }
 }
 
-void filter::processIQ(DSPFLOAT *data, DSPFLOAT *output,int len)
-{
-  FILTERPARAMTYPE resQ=0;
 
-  const FILTERPARAMTYPE *cf1;
-  DSPFLOAT *fp1;
-  unsigned int i;
-  int k;
 
 
-  for (k=0;k<len;k++)
+void filter::processHILBVolume(FILTERPARAMTYPE *dataPtr)
+{
+  FILTERPARAMTYPE resI;
+  FILTERPARAMTYPE resQ;
+  const FILTERPARAMTYPE *cf1;
+  FILTERPARAMTYPE *fp1;
+  unsigned int i;
+  uint k;
+  for (k=0;k<dataLen;k++)
     {
       resQ=0;
-      cf1 = filterParams;
-      fp1 = samplesI;
-      memmove(samplesI+1, samplesI, ssize); // newest at index 0
-      samplesI[0]=data[k];
-      for(i=0;i<filterLength;i++,fp1++,cf1++)
+      cf1 = coefZPtr+1;
+      fp1 = sampleBufferIPtr+1;
+      memmove(sampleBufferIPtr+1, sampleBufferIPtr,bufSize);
+      sampleBufferIPtr[0]=dataPtr[k];
+      for(i=1;i<=nZeroes;i+=2,fp1+=2,cf1+=2)
         {
           resQ+=(*fp1)*(*cf1);
-        }
-      output[2*k+1]=samplesI[filterLength/2]; // just delay
-//      output[2*k]=resQ*0.911;
-      output[2*k]=(DSPFLOAT)resQ;
+        };
+      resQ/=gain;
+      resI=sampleBufferIPtr[nZeroes/2];
+      volumePtr[k]=sqrt(resQ*resQ+resI*resI);
     }
 }
 
+//void filter::processHILBDemod(FILTERPARAMTYPE *dataPtr)
+//{
+//  int  temp;
+//  uint i,k;
+//  FILTERPARAMTYPE resI;
+//  FILTERPARAMTYPE resQ;
+//  FILTERPARAMTYPE discRe;
+//  FILTERPARAMTYPE discIm;
+//  const FILTERPARAMTYPE *cf1;
+//  FILTERPARAMTYPE *fp1;
+
+//  for (k=0;k<dataLen;k++)
+//    {
+//      resQ=0;
+//      cf1 = coefZPtr+1;
+//      fp1 = sampleBufferIPtr+1;
+//      memmove(sampleBufferIPtr+1, sampleBufferIPtr, bufSize);
+//      sampleBufferIPtr[0]=dataPtr[k];
+//      for(i=1;i<=nZeroes;i+=2,fp1+=2,cf1+=2)
+//        {
+//          resQ+=(*fp1)*(*cf1);
+//        };
+//      resQ/=gain;
+//      resI=sampleBufferIPtr[nZeroes/2];
+//      discRe=resI*resIprev+resQ*resQprev;
+//      discIm=-resQ*resIprev+resQprev*resI;
+//      resIprev=resI;
+//      resQprev=resQ;
+//      if(discRe==0) discRe=0.0001;
+//      temp=(int)round(frCenter-atan2(discIm,discRe)*angleToFc);
+//      if(temp<500) temp=prevTemp;
+//      if(temp>2600) temp=prevTemp;
+//      prevTemp=temp;
+//      demodPtr[k]=temp;
+//      double vol=sqrt(resI*resI+resQ*resQ);
+//      if (vol>avgVolume) avgVolume=avgVolume*(1-volumeAttackIntegrator)+(volumeAttackIntegrator)*vol;
+//      else if (vol<avgVolume) avgVolume=avgVolume*(1-volumeDecayIntegrator)+(volumeDecayIntegrator)*vol;
+//      volumePtr[i]=avgVolume;
+//    }
+//}
 
-void filter::processAM(DSPFLOAT *data)
+
+void filter::processIIR(double *dataPtr)
 {
-  FILTERPARAMTYPE resI=0, resQ=0;
-  const FILTERPARAMTYPE *cf1;
-	DSPFLOAT *fp1, *fp2 ,amplitude;
-	unsigned int i,k;
-	int zeroes=filterLength-1;
-
-	for (k=0;k<length;k++)
-		{
-			resI=0;
-			resQ=0;
-			cf1 = filterParams;
-			fp1 = samplesI;
-			fp2 = samplesQ;
-			memmove(samplesI, samplesI+1, (zeroes)*sizeof(DSPFLOAT));
-  		memmove(samplesQ, samplesQ+1, (zeroes)*sizeof(DSPFLOAT));
-      nco.multiply(samplesI[zeroes],samplesQ[zeroes],data[k]);
-			for(i=0;i<filterLength;i++,fp1++,fp2++,cf1++)
- 				{
-   				resI+=(*fp1)*(*cf1);
-   				resQ+=(*fp2)*(*cf1);
- 				}
-			amplitude=sqrt(resI*resI+resQ*resQ);
-      filteredDataBuffer[k]=2*amplitude;
-		}
+  unsigned int i,j;
+  double resx;
+  for (i=0;i<dataLen;i++)
+    {
+      resx=0;
+      memmove(sampleBufferIPtr,sampleBufferIPtr+1,bufSize);
+      memmove(sampleBufferYIPtr,sampleBufferYIPtr+1,nPoles*sizeof(FILTERPARAMTYPE));
+      sampleBufferIPtr[nZeroes]=dataPtr[i]/gain;
+      if(!(nZeroes&1))
+        {
+          resx=sampleBufferIPtr[nZeroes/2]*coefZPtr[nZeroes/2];
+        }
+      for (j=0;j<((nZeroes+1)/2);j++)
+        {
+          resx+=(sampleBufferIPtr[j]+sampleBufferIPtr[nZeroes-j])*coefZPtr[j];
+        }
+      for (j=0;j<nPoles;j++)
+        {
+          resx+=sampleBufferYIPtr[j]*coefPPtr[j];
+        }
+      sampleBufferYIPtr[nPoles]=resx;
+      filteredPtr[i]=resx;
+    }
 }
 
-void filter::process(DSPFLOAT *data,DSPFLOAT *filteredData,int len)
+void filter::processIQ(FILTERPARAMTYPE *dataPtr, float *dataOutputPtr)
 {
-  FILTERPARAMTYPE resI=0;
+  FILTERPARAMTYPE resQ=0;
   const FILTERPARAMTYPE *cf1;
-  DSPFLOAT *fp1;
-  unsigned int i;
-  int k;
-  int zeroes=filterLength-1;
-  for (k=0;k<len;k++)
+  FILTERPARAMTYPE *fp1;
+  uint i,k;
+  for (k=0;k<dataLen;k++)
     {
-      resI=0;
-      cf1 = filterParams;
-      fp1 = samplesI;
-      memmove(samplesI+1, samplesI, (zeroes)*sizeof(DSPFLOAT));
-      samplesI[0]=data[k];
-      for(i=0;i<filterLength;i++,fp1++,cf1++)
+      resQ=0;
+      cf1 = coefZPtr;
+      fp1 = sampleBufferIPtr;
+      memmove(sampleBufferIPtr+1, sampleBufferIPtr,bufSize); // newest at index 0
+      sampleBufferIPtr[0]=dataPtr[k];
+      for(i=0;i<=nZeroes;i++,fp1++,cf1++)
         {
-          resI+=(*fp1)*(*cf1);
-        };
-      filteredData[k]=(DSPFLOAT)resI;
+          resQ+=(*fp1)*(*cf1);
+        }
+      dataOutputPtr[2*k+1]=sampleBufferIPtr[(nZeroes+1)/2]; // just delay
+      dataOutputPtr[2*k]=resQ/gain;
     }
 }
 
 
-void filter::delay(DSPFLOAT *data,DSPFLOAT *filteredData,int len)
+void filter::setupMatchedFilter(FILTERPARAMTYPE freq, uint numTaps)
 {
-  int k;
-  int zeroes=filterLength-1;
-  for (k=0;k<len;k++)
+  uint i;
+  init();
+  nZeroes=numTaps-1;
+  coefZPtr=new FILTERPARAMTYPE[nZeroes+1];
+
+  for(i=0;i<=nZeroes;i++)
     {
-      memmove(samplesI, samplesI+1, (zeroes)*sizeof(DSPFLOAT));
-      samplesI[zeroes]=data[k];
-      filteredData[k]=samplesI[filterLength/2];
+      if(freq==0)
+        {
+          coefZPtr[i]=1;
+        }
+      else
+        {
+          coefZPtr[i]=sin(i*2*M_PI/(SAMPLERATE/freq));
+        }
     }
+  if(freq==0) gain=numTaps;
+  else gain=numTaps/2;
+  allocate();
 }
 
+
diff --git a/qsstv/dsp/filter.h b/qsstv/dsp/filter.h
index d27421f..78bfc77 100644
--- a/qsstv/dsp/filter.h
+++ b/qsstv/dsp/filter.h
@@ -1,69 +1,65 @@
-/***************************************************************************
- *   Copyright (C) 2000-2008 by Johan Maes                                 *
- *   on4qz at telenet.be                                                      *
- *   http://users.telenet.be/on4qz                                         *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   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.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- ***************************************************************************/
 #ifndef FILTER_H
 #define FILTER_H
-#include "nco.h"
 #include "filterparam.h"
-
+#include "nco.h"
 
 class filter
 {
+
 public:
-	filter();
-  filter(unsigned int len,const FILTERPARAMTYPE *fparam,unsigned int filterLen,DSPFLOAT centerFrequency,DSPFLOAT clock,bool scaled,DSPFLOAT volumeIntegrator);
-	~filter();
-	void allocate(unsigned int dataLength);
-  void setFilterParams(const FILTERPARAMTYPE *fparam,unsigned int filterLen,DSPFLOAT centerFrequency,DSPFLOAT clock,bool scaled,DSPFLOAT volumeIntegrator);
-  void processFM(DSPFLOAT *data);
-  void processBP(DSPFLOAT *data);
-  void processAM(DSPFLOAT *data);
-  void processIQ(DSPFLOAT *data,DSPFLOAT *output, int len);
-  int *filteredDataPtr() {return filteredDataBuffer;}
-  int *volumePtr() {return volumeBuffer;}
-  void process(DSPFLOAT *data,DSPFLOAT *filteredData,int len);
-  void delay(DSPFLOAT *data,DSPFLOAT *filteredData,int len);
+  enum efilterType {FTNONE,FTFIR,FTIIR,FTHILB};
+  filter(efilterType fType,uint dataLenght);
+  ~filter();
+  void process();
+  void init();
+  void processFIR(FILTERPARAMTYPE *dataPtr,FILTERPARAMTYPE *dataOutputPtr);
+  void processFIRInt(FILTERPARAMTYPE *dataPtr, quint16 *dataOutputPtr);
+  void processFIRDemod(FILTERPARAMTYPE *dataPtr, FILTERPARAMTYPE *dataOutputPtr);
+  void processIIR(FILTERPARAMTYPE *dataPtr);
+  void processHILBVolume(FILTERPARAMTYPE *dataPtr);
+//  void processHILBDemod(FILTERPARAMTYPE *dataPtr);
+  void processIQ(FILTERPARAMTYPE *dataPtr,float *dataOutputPtr);
+  void setupMatchedFilter(FILTERPARAMTYPE freq, uint numTaps);
+  void allocate();
+  FILTERPARAMTYPE *coefZPtr;
+  FILTERPARAMTYPE *coefPPtr;
+  FILTERPARAMTYPE *filteredPtr;
+  FILTERPARAMTYPE *volumePtr;
+  FILTERPARAMTYPE gain;
+  quint16 *demodPtr;
+  FILTERPARAMTYPE frCenter;
+  FILTERPARAMTYPE volumeAttackIntegrator;
+  FILTERPARAMTYPE volumeDecayIntegrator;
+  uint nZeroes;
+  uint nPoles;
+  uint dataLen;
 
 private:
-	void normalizeGain();
-	bool demoluteFM;
-  int *filteredDataBuffer;
-  int *volumeBuffer;
-
-  FILTERPARAMTYPE *filterParams;
-	unsigned int filterLength;
-	DSPFLOAT *samplesI;
-	DSPFLOAT *samplesQ;
-  FILTERPARAMTYPE	resIprev;
-  FILTERPARAMTYPE	resQprev;
-  int prevTemp;
-	unsigned int length;
-	NCO nco;
-	DSPFLOAT frCenter;
-	DSPFLOAT angleToFc;
-  DSPFLOAT holdPrev;
-  DSPFLOAT amplitude;
-  int zeroes;
-  int ssize;
-  DSPFLOAT avgVolume;
-  DSPFLOAT volIntegrator;
+
+  void resetPointers();
+  void deleteBuffers();
+
+  FILTERPARAMTYPE *sampleBufferIPtr;
+  FILTERPARAMTYPE *sampleBufferQPtr;
+  FILTERPARAMTYPE *sampleBufferYIPtr;
+
+
+
+  FILTERPARAMTYPE resIprev;
+  FILTERPARAMTYPE resQprev;
+
+  FILTERPARAMTYPE angleToFc;
+  FILTERPARAMTYPE avgVolume;
+  FILTERPARAMTYPE prevTemp;
+
+  NCO nco;
+
+
+  uint bufSize;
+  efilterType filterType;
 };
 
-#endif
+
+
+
+#endif // FILTER_H
diff --git a/qsstv/dsp/filterparam.cpp b/qsstv/dsp/filterparam.cpp
index 306b43d..e0e75b7 100644
--- a/qsstv/dsp/filterparam.cpp
+++ b/qsstv/dsp/filterparam.cpp
@@ -21,3879 +21,711 @@
 #include "filterparam.h"
 
 
-
-#ifdef DWSBANDPASS
-// rFIR
-// localSamplingrate = 48000.000000
-// number of taps = 360
-// Band0 Lower=0.000000, Upper=50.000000, Desired=0.000000, Weight=1.000000
-// Band1 Lower=250.000000, Upper=2700.000000, Desired=1.000000, Weight=8.000000
-// Band2 Lower=2900.000000, Upper=24000.000000, Desired=0.000000, Weight=2.000000
-//Coefficients:
-const FILTERPARAMTYPE downSampleFilterParam[DSAMPLEFILTERLEN]=
+// blIIR  Chebyshev , Bandpass
+// localSamplingrate = 12000.000000
+// order = 4
+// Gain = 103035.237413
+// corner 1 frequency = 1050.000000
+// corner 2 frequency = 1350.000000
+//Ripple = -1.000000
+//
+// Coefficients - Zeroes:
+
+const double z_sync_bp[SYNCBPNUMZEROES+1]=
 {
-  -0.00151718585312103,
-  0.000309665297865725,
-  0.000266770230632739,
-  0.000220107262717653,
-  0.00017069787890033,
-  0.000119558768317707,
-  6.7937235925543e-05,
-  1.73219175796899e-05,
-  -3.04504220475478e-05,
-  -7.32505140153168e-05,
-  -0.000108809984498506,
-  -0.000134931038254037,
-  -0.000149757016582148,
-  -0.000152098343880838,
-  -0.00014173987237634,
-  -0.000119585246451574,
-  -8.77350358596666e-05,
-  -5.09192816488034e-05,
-  -8.16419424981514e-06,
-  2.40226851297579e-05,
-  5.3136899043456e-05,
-  6.99684228232289e-05,
-  6.87817534604667e-05,
-  4.87441013458151e-05,
-  1.16900843058164e-05,
-  -3.89696741104e-05,
-  -9.85468390916148e-05,
-  -0.000161009867428677,
-  -0.000219206981177775,
-  -0.000265621897813199,
-  -0.000293498241691715,
-  -0.000298003921541809,
-  -0.000277186705451158,
-  -0.000232676836925126,
-  -0.000169914967971405,
-  -9.62079979300535e-05,
-  -2.51125513131256e-05,
-  3.69809600262516e-05,
-  7.42043577814656e-05,
-  7.97817373854275e-05,
-  5.02385379851292e-05,
-  -1.57991871271694e-05,
-  -0.000114437287265163,
-  -0.000235897965918837,
-  -0.000366102814052958,
-  -0.000489103613086259,
-  -0.000589210258820819,
-  -0.000652743939524249,
-  -0.000669783890970928,
-  -0.000635975263583453,
-  -0.000553949112513262,
-  -0.000433593492614785,
-  -0.000290988579590895,
-  -0.00014832630995168,
-  -2.59207759511581e-05,
-  5.09331968833574e-05,
-  6.84394379409231e-05,
-  1.57208894447818e-05,
-  -0.000109405205140087,
-  -0.000296897689887665,
-  -0.000527902720342548,
-  -0.000777067132466488,
-  -0.00101453005859221,
-  -0.00120920779134417,
-  -0.001333593463007,
-  -0.00136857191046792,
-  -0.00130679331314755,
-  -0.00115412927772127,
-  -0.000929440598646113,
-  -0.000663135426651631,
-  -0.000394378459673436,
-  -0.000163967367349531,
-  -1.40577113630792e-05,
-  2.71166292762123e-05,
-  -6.07346253858535e-05,
-  -0.000278313442438686,
-  -0.000607429273487369,
-  -0.00101549130993907,
-  -0.00145608565994414,
-  -0.00187440115136921,
-  -0.0022154989505,
-  -0.00243231081057876,
-  -0.00249210523944556,
-  -0.00238167905234111,
-  -0.00211084486700502,
-  -0.00171301174998109,
-  -0.00124206062226084,
-  -0.000765464268534193,
-  -0.000354836981285895,
-  -7.91079665324665e-05,
-  1.09315658115454e-05,
-  -0.000117905256558107,
-  -0.00046606643180625,
-  -0.00100501188496882,
-  -0.00167912001559893,
-  -0.00240829932962692,
-  -0.00310083785299637,
-  -0.00366547762099869,
-  -0.00402294472888868,
-  -0.00411761180003572,
-  -0.0039274117727721,
-  -0.00346911661557856,
-  -0.00279793021625653,
-  -0.00200180220277536,
-  -0.00119111041913143,
-  -0.000485030551997283,
-  3.81268603366552e-06,
-  0.000188967667995569,
-  1.75771088832494e-05,
-  -0.000512433845333963,
-  -0.00135691951675416,
-  -0.00242506976696957,
-  -0.0035879472609761,
-  -0.0046981084325413,
-  -0.00560605758712609,
-  -0.00618109818486136,
-  -0.00633169671974863,
-  -0.00602029294983547,
-  -0.00527087376898266,
-  -0.00416920321248404,
-  -0.00285489367017525,
-  -0.0015052886779112,
-  -0.000313107859445306,
-  0.000539650875676152,
-  0.000908453023733856,
-  0.000704485989099417,
-  -8.34445326883886e-05,
-  -0.00139001723273659,
-  -0.0030720685622835,
-  -0.00492573659293609,
-  -0.00671350908243368,
-  -0.00819040896088137,
-  -0.00913994430276909,
-  -0.0094054510698947,
-  -0.00891440529630932,
-  -0.0076938432246964,
-  -0.00587332975516594,
-  -0.00367330078239809,
-  -0.00138024590473629,
-  0.000688237354624767,
-  0.00222495069867272,
-  0.00297549107050037,
-  0.00277514985073955,
-  0.00158149008174527,
-  -0.000518003816389104,
-  -0.00330261804405544,
-  -0.00644305708217242,
-  -0.00953836573752198,
-  -0.0121613753764521,
-  -0.0139192020967903,
-  -0.014506083994603,
-  -0.01375111070042,
-  -0.0116523257225599,
-  -0.00839011738751365,
-  -0.00431760602103533,
-  7.1663663982476e-05,
-  0.00419702982579153,
-  0.00745975192802291,
-  0.00931939464036898,
-  0.00936943884289081,
-  0.00740391343534496,
-  0.00345877565753137,
-  -0.00216217557912831,
-  -0.00890269263539967,
-  -0.015993306828616,
-  -0.0225185891488447,
-  -0.0275127194995281,
-  -0.0300581664238577,
-  -0.0293928821975884,
-  -0.0250048561965734,
-  -0.016704594395921,
-  -0.00466807376363805,
-  0.0105565992041111,
-  0.0280814505817365,
-  0.0467469851736764,
-  0.0652208053169884,
-  0.0821177670264463,
-  0.0961283100667419,
-  0.106140280278628,
-  0.111351899732022,
-  0.111349938479372,
-  0.106125325195358,
-  0.0961012215899245,
-  0.082083055541495,
-  0.065184044146694,
-  0.0467140460518445,
-  0.0280577028971195,
-  0.0105461819922317,
-  -0.0046628081022343,
-  -0.016683390465914,
-  -0.0249695791797853,
-  -0.0293472523705209,
-  -0.0300072425912863,
-  -0.0274622028497765,
-  -0.022474041565934,
-  -0.0159593912922312,
-  -0.00888254418083573,
-  -0.00215697336191281,
-  0.00344995890282234,
-  0.00738397867095158,
-  0.00934286593093756,
-  0.00929162187785759,
-  0.00743644458315651,
-  0.00418330943585274,
-  7.14189972924584e-05,
-  -0.0043022374712043,
-  -0.00835902931430361,
-  -0.0116074461548097,
-  -0.0136961306275393,
-  -0.0144459510742554,
-  -0.0138594474412668,
-  -0.0121073658888651,
-  -0.00949458766305608,
-  -0.00641252452164234,
-  -0.0032864730910068,
-  -0.000515393696874395,
-  0.00157328267532868,
-  0.00276032738480899,
-  0.00295914596667793,
-  0.00221238862228927,
-  0.000684245970120732,
-  -0.00137202854072664,
-  -0.00365086284841068,
-  -0.00583653949343313,
-  -0.00764444661708083,
-  -0.00885577187143843,
-  -0.00934210271690931,
-  -0.0090769334929006,
-  -0.00813263733184636,
-  -0.00666507779776451,
-  -0.0048894076705026,
-  -0.00304891264847757,
-  -0.00137931307597921,
-  -8.27882523334948e-05,
-  0.000698828976253759,
-  0.000901007241309603,
-  0.000535137629629946,
-  -0.000310436583942355,
-  -0.0014921914829033,
-  -0.00282956735303828,
-  -0.00413150220327286,
-  -0.0052223003458195,
-  -0.00596376643057263,
-  -0.00627113762676166,
-  -0.00612088948511199,
-  -0.00555045453310577,
-  -0.00465067025277631,
-  -0.00355107205618392,
-  -0.00239970572091919,
-  -0.00134247910335008,
-  -0.00050688602184144,
-  1.73835459454169e-05,
-  0.000186851328593862,
-  3.76926627593299e-06,
-  -0.000479414621359702,
-  -0.00117709065000749,
-  -0.00197785315902698,
-  -0.00276391086548602,
-  -0.00342625426272416,
-  -0.0038781081141346,
-  -0.00406509683686583,
-  -0.0039708255367144,
-  -0.00361724368824401,
-  -0.0030593974778865,
-  -0.00237561549230207,
-  -0.00165598131126649,
-  -0.000990950721816176,
-  -0.000459446555962234,
-  -0.000116205262140052,
-  1.07715840793517e-05,
-  -7.79329491288675e-05,
-  -0.000349488231502234,
-  -0.000753755485340556,
-  -0.00122278280128855,
-  -0.00168603625864065,
-  -0.00207712192979598,
-  -0.00234307978201088,
-  -0.0024511361597515,
-  -0.00239175337853265,
-  -0.0021780316539496,
-  -0.0018422541194682,
-  -0.00143076173464824,
-  -0.000997583010841567,
-  -0.000596568116623263,
-  -0.000273268167415817,
-  -5.96184688626525e-05,
-  2.66114681243663e-05,
-  -1.37922622490626e-05,
-  -0.000160829296086387,
-  -0.000386729139522771,
-  -0.000650101333555018,
-  -0.000910929474657119,
-  -0.00113083975447844,
-  -0.00128007745727489,
-  -0.00134022893970869,
-  -0.00130561817736569,
-  -0.00118351678315544,
-  -0.000992701356832596,
-  -0.000760137188210536,
-  -0.00051625788278049,
-  -0.000290267675160951,
-  -0.000106932250570691,
-  1.53612523294125e-05,
-  6.68551362116988e-05,
-  4.97402887713845e-05,
-  -2.53066542354481e-05,
-  -0.000144772078583238,
-  -0.000283937761679862,
-  -0.00042297186175046,
-  -0.000540233180356209,
-  -0.000620062798522562,
-  -0.00065285375357642,
-  -0.000636080094916979,
-  -0.000574023057935788,
-  -0.000476379090176037,
-  -0.000356492807082752,
-  -0.000229652579895355,
-  -0.000111382801539256,
-  -1.53742280913752e-05,
-  4.8877464993403e-05,
-  7.7605767545448e-05,
-  7.216807749654e-05,
-  3.5960542057589e-05,
-  -2.44162570500983e-05,
-  -9.35294421380662e-05,
-  -0.000165168538352502,
-  -0.000226161106310923,
-  -0.00026941255178708,
-  -0.000289641461254719,
-  -0.000285266901460065,
-  -0.000258185533558317,
-  -0.000213088908986053,
-  -0.000156536278671508,
-  -9.58253134180074e-05,
-  -3.79017941126775e-05,
-  1.13728141318785e-05,
-  4.74365397903835e-05,
-  6.69621860673353e-05,
-  6.81475404150919e-05,
-  5.17802014823365e-05,
-  2.34227340762627e-05,
-  -7.96541204893464e-06,
-  -4.97150185953007e-05,
-  -8.5727741580426e-05,
-  -0.000116950564089072,
-  -0.00013874814150351,
-  -0.000149040545002216,
-  -0.000146908318755611,
-  -0.000132520947558629,
-  -0.00010700115323508,
-  -7.21290149150481e-05,
-  -3.00264108515757e-05,
-  1.71059107790105e-05,
-  6.7193203421747e-05,
-  0.000118437876786714,
-  0.000169375448704034,
-  0.000218770083443505,
-  0.000265605181906194,
-  0.000308850143176507,
-  -0.0189481367078439
+   1,
+   0,
+   -4,
+   0,
+   6,
+   0,
+   -4,
+   0,
+   1
 };
-#else
-// rFIR
-// localSamplingrate = 48000.000000
-// number of taps = 181
-// Band0 Lower=0.000000, Upper=2800.000000, Desired=2.000000, Weight=1.000000
-// Band1 Lower=3500.000000, Upper=24000.000000, Desired=0.000000, Weight=10.000000
-//Coefficients:
- const FILTERPARAMTYPE downSampleFilterParam[DSAMPLEFILTERLEN]=
+
+// Coefficients - Poles:
+const double p_sync_bp[SYNCBPNUMPOLES]=
 {
-   -0.000726805371518309,
-   0.00212924341308074,
-   0.00209607515518649,
-   0.00258616863859503,
-   0.00312451941666017,
-   0.00351845737963003,
-   0.00365705393269608,
-   0.00347249738871369,
-   0.00294091277303658,
-   0.0020876784816062,
-   0.000989968644394825,
-   -0.000229536963193281,
-   -0.00141602838562286,
-   -0.00240355817861836,
-   -0.00303972686902264,
-   -0.00321109351395581,
-   -0.00286490657890866,
-   -0.00202335724664101,
-   -0.000787353876891696,
-   0.000672176418542286,
-   0.00213509217135987,
-   0.00336342008182743,
-   0.00413819652648567,
-   0.00429713243771618,
-   0.00376510708747164,
-   0.00257360789092004,
-   0.000863764615466942,
-   -0.001127792766604,
-   -0.00309663047609688,
-   -0.00472159091592147,
-   -0.0056999360876337,
-   -0.00583031339786136,
-   -0.00501710522705826,
-   -0.00331719263251476,
-   -0.000939525687925027,
-   0.00178104445626093,
-   0.00442648054106535,
-   0.00655781811862848,
-   0.00778470951795523,
-   0.00783457506289861,
-   0.00660582869791214,
-   0.00419854005559208,
-   0.000913611071336271,
-   -0.00278058458658644,
-   -0.00631166219807734,
-   -0.00908863549508422,
-   -0.0105968380602393,
-   -0.0104880827011458,
-   -0.00865059863609764,
-   -0.00524633117469452,
-   -0.000706169042697737,
-   0.00431853795460012,
-   0.00904473602072652,
-   0.0126740048689635,
-   0.0145210513202929,
-   0.0141339163209834,
-   0.0113860335748772,
-   0.00652568850180913,
-   0.000164013828194059,
-   -0.00678721495092159,
-   -0.0132450608783663,
-   -0.0181056223037124,
-   -0.0204244364948377,
-   -0.0195817855693473,
-   -0.0154088583976291,
-   -0.00825851456253797,
-   0.00100265183405794,
-   0.0110798178134256,
-   0.0204127669048817,
-   0.0273919133377699,
-   0.0306039642231267,
-   0.0290707628785015,
-   0.0224466971136873,
-   0.0111424375360727,
-   -0.00364878906373264,
-   -0.0200329664559621,
-   -0.0356023553816112,
-   -0.0477088371694707,
-   -0.053792701556172,
-   -0.0517250893361419,
-   -0.0401198095407566,
-   -0.0185705541637443,
-   0.0122205143308298,
-   0.0504455099076038,
-   0.093330253141237,
-   0.13739759113622,
-   0.178828272483524,
-   0.213871703505128,
-   0.239265440205684,
-   0.252600612879519,
-   0.252600612879519,
-   0.239265440205684,
-   0.213871703505128,
-   0.178828272483524,
-   0.13739759113622,
-   0.093330253141237,
-   0.0504455099076038,
-   0.0122205143308298,
-   -0.0185705541637443,
-   -0.0401198095407566,
-   -0.0517250893361419,
-   -0.053792701556172,
-   -0.0477088371694707,
-   -0.0356023553816112,
-   -0.0200329664559621,
-   -0.00364878906373264,
-   0.0111424375360727,
-   0.0224466971136873,
-   0.0290707628785015,
-   0.0306039642231267,
-   0.0273919133377699,
-   0.0204127669048817,
-   0.0110798178134256,
-   0.00100265183405794,
-   -0.00825851456253797,
-   -0.0154088583976291,
-   -0.0195817855693473,
-   -0.0204244364948377,
-   -0.0181056223037124,
-   -0.0132450608783663,
-   -0.00678721495092159,
-   0.000164013828194059,
-   0.00652568850180913,
-   0.0113860335748772,
-   0.0141339163209834,
-   0.0145210513202929,
-   0.0126740048689635,
-   0.00904473602072652,
-   0.00431853795460012,
-   -0.000706169042697737,
-   -0.00524633117469452,
-   -0.00865059863609764,
-   -0.0104880827011458,
-   -0.0105968380602393,
-   -0.00908863549508422,
-   -0.00631166219807734,
-   -0.00278058458658644,
-   0.000913611071336271,
-   0.00419854005559208,
-   0.00660582869791214,
-   0.00783457506289861,
-   0.00778470951795523,
-   0.00655781811862848,
-   0.00442648054106535,
-   0.00178104445626093,
-   -0.000939525687925027,
-   -0.00331719263251476,
-   -0.00501710522705826,
-   -0.00583031339786136,
-   -0.0056999360876337,
-   -0.00472159091592147,
-   -0.00309663047609688,
-   -0.001127792766604,
-   0.000863764615466942,
-   0.00257360789092004,
-   0.00376510708747164,
-   0.00429713243771618,
-   0.00413819652648567,
-   0.00336342008182743,
-   0.00213509217135987,
-   0.000672176418542286,
-   -0.000787353876891696,
-   -0.00202335724664101,
-   -0.00286490657890866,
-   -0.00321109351395581,
-   -0.00303972686902264,
-   -0.00240355817861836,
-   -0.00141602838562286,
-   -0.000229536963193281,
-   0.000989968644394825,
-   0.0020876784816062,
-   0.00294091277303658,
-   0.00347249738871369,
-   0.00365705393269608,
-   0.00351845737963003,
-   0.00312451941666017,
-   0.00258616863859503,
-   0.00209607515518649,
-   0.00212924341308074,
-   -0.000726805371518309
+   -0.861024987351637,
+   5.67674544613512,
+   -17.6022837176932,
+   33.0747979391828,
+   -41.0238598189095,
+   34.3363117528713,
+   -18.970571207451,
+   6.35126296063036
 };
 
 
-#endif
-
-
-/*
-
-FIR filter designed with
-http://t-filter.appspot.com
-
-sampling frequency: 48000 Hz
-
-* 0 Hz - 12000 Hz
-  gain = 1
-  desired ripple = 5 dB
-  actual ripple = 0.010064305090401647 dB
-
-* 14000 Hz - 24000 Hz
-  gain = 0
-  desired attenuation = -40 dB
-  actual attenuation = -82.0306697301112 dB
-
-*/
-
-//#define FILTER_TAP_NUM 120
-
-//const FILTERPARAMTYPE downSampleFilterParam[DSFILTERLEN]=
-//{
-//  -0.00001434671700912554,
-//  -0.000020562134651605815,
-//  0.00001876751754297483,
-//  0.000026445175446795552,
-//  -0.00006030588399278963,
-//  -0.00005828746852741699,
-//  0.00009853296830508344,
-//  0.00005931095017311163,
-//  -0.00019046483652338048,
-//  -0.0000701660667147503,
-//  0.0002856339556184428,
-//  0.000019827822393580995,
-//  -0.0004370075921714892,
-//  0.00005539702740416332,
-//  0.0005788569954831205,
-//  -0.00023331653626705516,
-//  -0.0007478536043794683,
-//  0.00047687246116682845,
-//  0.000857539467749795,
-//  -0.0008559863070902277,
-//  -0.0009222988328700723,
-//  0.001316670320186741,
-//  0.0008349709365650639,
-//  -0.0019017785484652815,
-//  -0.0005943042771593648,
-//  0.002521346756232543,
-//  0.00008790552871839043,
-//  -0.0031717280255955595,
-//  0.0006802888305853671,
-//  0.0037148625674325287,
-//  -0.0017975574392839607,
-//  -0.004094961253668418,
-//  0.003219684850878581,
-//  0.004129426138899979,
-//  -0.004972984552710972,
-//  -0.0037259328148558325,
-//  0.006937428069747955,
-//  0.002682000096803343,
-//  -0.009048195500263277,
-//  -0.0009009328077472075,
-//  0.011087098217581621,
-//  -0.0018057790712661997,
-//  -0.012884014811956659,
-//  0.005512716439276536,
-//  0.014111394052560285,
-//  -0.01038993718341453,
-//  -0.0144745570870615,
-//  0.016529612471778678,
-//  0.013477274536340088,
-//  -0.0242188112250576,
-//  -0.010528902562796134,
-//  0.03391653395396962,
-//  0.004470587562008853,
-//  -0.046963243031028244,
-//  0.007126082872329679,
-//  0.06721942081260658,
-//  -0.032209836572452265,
-//  -0.11187872022628036,
-//  0.12057492071696543,
-//  0.47614828001783693,
-//  0.47614828001783693,
-//  0.12057492071696543,
-//  -0.11187872022628036,
-//  -0.032209836572452265,
-//  0.06721942081260658,
-//  0.007126082872329679,
-//  -0.046963243031028244,
-//  0.004470587562008853,
-//  0.03391653395396962,
-//  -0.010528902562796134,
-//  -0.0242188112250576,
-//  0.013477274536340088,
-//  0.016529612471778678,
-//  -0.0144745570870615,
-//  -0.01038993718341453,
-//  0.014111394052560285,
-//  0.005512716439276536,
-//  -0.012884014811956659,
-//  -0.0018057790712661997,
-//  0.011087098217581621,
-//  -0.0009009328077472075,
-//  -0.009048195500263277,
-//  0.002682000096803343,
-//  0.006937428069747955,
-//  -0.0037259328148558325,
-//  -0.004972984552710972,
-//  0.004129426138899979,
-//  0.003219684850878581,
-//  -0.004094961253668418,
-//  -0.0017975574392839607,
-//  0.0037148625674325287,
-//  0.0006802888305853671,
-//  -0.0031717280255955595,
-//  0.00008790552871839043,
-//  0.002521346756232543,
-//  -0.0005943042771593648,
-//  -0.0019017785484652815,
-//  0.0008349709365650639,
-//  0.001316670320186741,
-//  -0.0009222988328700723,
-//  -0.0008559863070902277,
-//  0.000857539467749795,
-//  0.00047687246116682845,
-//  -0.0007478536043794683,
-//  -0.00023331653626705516,
-//  0.0005788569954831205,
-//  0.00005539702740416332,
-//  -0.0004370075921714892,
-//  0.000019827822393580995,
-//  0.0002856339556184428,
-//  -0.0000701660667147503,
-//  -0.00019046483652338048,
-//  0.00005931095017311163,
-//  0.00009853296830508344,
-//  -0.00005828746852741699,
-//  -0.00006030588399278963,
-//  0.000026445175446795552,
-//  0.00001876751754297483,
-//  -0.000020562134651605815,
-//  -0.00001434671700912554
-//};
+//==================================================================================
+
+// blIIR  Chebyshev , Bandpass
+// localSamplingrate = 12000.000000
+// order = 4
+// Gain = 2284.945151
+// corner 1 frequency = 1500.000000
+// corner 2 frequency = 2300.000000
+//Ripple = -1.000000
+//
+// Coefficients - Zeroes:
+#define VIDEOBPNUMZEROES 8
+#define VIDEOBPNUMPOLES 8
+#define VIDEOBPGAIN 2284.945151
+const double z_video_bp[VIDEOBPNUMZEROES+1]=
+{
+   1,
+   0,
+   -4,
+   0,
+   6,
+   0,
+   -4,
+   0,
+   1
+};
 
+// Coefficients - Poles:
+const double p_video_bp[VIDEOBPNUMPOLES]=
+{
+   -0.671359159217638,
+   3.06934557661143,
+   -8.13204301860416,
+   13.9576511061334,
+   -17.3434093144714,
+   15.4193178643578,
+   -9.92569527488599,
+   4.14238390732604
+};
 
-//// TFilter design
-//const DSPFLOAT downSampleFilterParam[DSFILTERLEN]=
-//{
-//-0.00031921241370338495,
-//0.0004949421700044819,
-//0.0013822939416138311,
-//0.0024512816581009097,
-//0.0031354286516971307,
-//0.0029158928250820424,
-//0.001661027141044636,
-//-0.00017924772122938603,
-//-0.001718399835583406,
-//-0.0021065617689579345,
-//-0.001080218804964031,
-//0.0007741897002425456,
-//0.0022803276925760932,
-//0.002370490501567989,
-//0.0008162184718294901,
-//-0.0015082994928116908,
-//-0.0030838686559974122,
-//-0.002712838485381115,
-//-0.00039730012077191765,
-//0.002503293797487666,
-//0.004036292913059631,
-//0.002948773728902641,
-//-0.0003454610920105798,
-//-0.0038302916183060387,
-//-0.005089732524335926,
-//-0.00295182534778405,
-//0.0015276238855431493,
-//0.005514356523235612,
-//0.006151496449877064,
-//0.0025611667129678915,
-//-0.0032836542253722617,
-//-0.007575527265201513,
-//-0.0071042856041813535,
-//-0.0015834913875678463,
-//0.005769176822509418,
-//0.010029690861770824,
-//0.007793764701402249,
-//-0.00023664441998894463,
-//-0.009197251927194018,
-//-0.012903337373983267,
-//-0.007999288652642442,
-//0.003296528685942004,
-//0.013945110147450536,
-//0.016304461562662808,
-//0.007384602945044693,
-//-0.008336298315850418,
-//-0.020829917188221893,
-//-0.020577775461447054,
-//-0.005292943361467393,
-//0.017139781366637633,
-//0.032108329389068505,
-//0.026911188696776438,
-//-0.0001361030874071249,
-//-0.03584756267942592,
-//-0.056825628460263636,
-//-0.04112767228986162,
-//0.01893335449923753,
-//0.11004116992869253,
-//0.2015954251233985,
-//0.25880099591048017,
-//0.25880099591048017,
-//0.2015954251233985,
-//0.11004116992869253,
-//0.01893335449923753,
-//-0.04112767228986162,
-//-0.056825628460263636,
-//-0.03584756267942592,
-//-0.0001361030874071249,
-//0.026911188696776438,
-//0.032108329389068505,
-//0.017139781366637633,
-//-0.005292943361467393,
-//-0.020577775461447054,
-//-0.020829917188221893,
-//-0.008336298315850418,
-//0.007384602945044693,
-//0.016304461562662808,
-//0.013945110147450536,
-//0.003296528685942004,
-//-0.007999288652642442,
-//-0.012903337373983267,
-//-0.009197251927194018,
-//-0.00023664441998894463,
-//0.007793764701402249,
-//0.010029690861770824,
-//0.005769176822509418,
-//-0.0015834913875678463,
-//-0.0071042856041813535,
-//-0.007575527265201513,
-//-0.0032836542253722617,
-//0.0025611667129678915,
-//0.006151496449877064,
-//0.005514356523235612,
-//0.0015276238855431493,
-//-0.00295182534778405,
-//-0.005089732524335926,
-//-0.0038302916183060387,
-//-0.0003454610920105798,
-//0.002948773728902641,
-//0.004036292913059631,
-//0.002503293797487666,
-//-0.00039730012077191765,
-//-0.002712838485381115,
-//-0.0030838686559974122,
-//-0.0015082994928116908,
-//0.0008162184718294901,
-//0.002370490501567989,
-//0.0022803276925760932,
-//0.0007741897002425456,
-//-0.001080218804964031,
-//-0.0021065617689579345,
-//-0.001718399835583406,
-//-0.00017924772122938603,
-//0.001661027141044636,
-//0.0029158928250820424,
-//0.0031354286516971307,
-//0.0024512816581009097,
-//0.0013822939416138311,
-//0.0004949421700044819,
-//-0.00031921241370338495,
-//};
+//==============================================================================
 
-// blFIR  Raised cosine
-// localSamplingrate = 48000.000000
-// number of taps = 120
-// corner frequency = 8000.000000
-// beta = 0.700000
+// blFIR  Hilbert
+// localSamplingrate = 12000.000000
+// number of taps = 121
 // window applied
 //Coefficients:
-
-//const DSPFLOAT downSampleFilterParam[DSFILTERLEN]=
-//{
-//    1.10951e-06,
-//    1.68217e-07,
-//    -3.53568e-11,
-//    1.91102e-06,
-//    1.89927e-06,
-//    2.59551e-11,
-//    1.15409e-06,
-//    2.97637e-06,
-//    9.28531e-11,
-//    -2.1707e-06,
-//    1.04504e-06,
-//    9.87304e-11,
-//    -6.71334e-06,
-//    -5.23393e-06,
-//    -4.59518e-12,
-//    -7.0149e-06,
-//    -1.20569e-05,
-//    -1.65625e-10,
-//    3.36226e-06,
-//    -9.32791e-06,
-//    -2.32704e-10,
-//    2.26407e-05,
-//    1.16112e-05,
-//    -8.50774e-11,
-//    3.2786e-05,
-//    4.26511e-05,
-//    2.10748e-10,
-//    6.05424e-06,
-//    4.96652e-05,
-//    4.01764e-10,
-//    -6.63556e-05,
-//    -1.08136e-05,
-//    2.6107e-10,
-//    -0.000136682,
-//    -0.000141189,
-//    -1.63979e-10,
-//    -9.11534e-05,
-//    -0.00024146,
-//    -5.30812e-10,
-//    0.000186548,
-//    -9.29759e-05,
-//    -4.81928e-10,
-//    0.000653162,
-//    0.000539686,
-//    6.14632e-12,
-//    0.000842028,
-//    0.0015963,
-//    5.48689e-10,
-//    -0.0005741,
-//    0.00187732,
-//    6.65763e-10,
-//    -0.00703948,
-//    -0.00483539,
-//    2.2005e-10,
-//    -0.0318124,
-//    -0.0807611,
-//    -4.31271e-10,
-//    0.334861,
-//    0.785553,
-//          1,
-//    0.785553,
-//    0.334861,
-//    -4.31271e-10,
-//    -0.0807611,
-//    -0.0318124,
-//    2.20049e-10,
-//    -0.00483539,
-//    -0.00703948,
-//    6.65763e-10,
-//    0.00187732,
-//    -0.0005741,
-//    5.48689e-10,
-//    0.0015963,
-//    0.000842028,
-//    6.14623e-12,
-//    0.000539686,
-//    0.000653162,
-//    -4.81928e-10,
-//    -9.29759e-05,
-//    0.000186548,
-//    -5.30812e-10,
-//    -0.00024146,
-//    -9.11534e-05,
-//    -1.63979e-10,
-//    -0.000141189,
-//    -0.000136682,
-//    2.6107e-10,
-//    -1.08136e-05,
-//    -6.63556e-05,
-//    4.01764e-10,
-//    4.96652e-05,
-//    6.05424e-06,
-//    2.10748e-10,
-//    4.26511e-05,
-//    3.2786e-05,
-//    -8.50774e-11,
-//    1.16112e-05,
-//    2.26407e-05,
-//    -2.32704e-10,
-//    -9.32791e-06,
-//    3.36226e-06,
-//    -1.65625e-10,
-//    -1.20569e-05,
-//    -7.0149e-06,
-//    -4.59518e-12,
-//    -5.23393e-06,
-//    -6.71334e-06,
-//    9.87304e-11,
-//    1.04504e-06,
-//    -2.1707e-06,
-//    9.28531e-11,
-//    2.97637e-06,
-//    1.15409e-06,
-//    2.59551e-11,
-//    1.89927e-06,
-//    1.91102e-06,
-//    -3.53568e-11,
-//    1.68217e-07,
-//    1.10951e-06,
-//    -7.38792e-10
-//};
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- // downSampleFilter filter
-// rFIR
-// localSamplingrate = 48000.000000
-// number of taps = 120
-// Band0 Lower=0.000000, Upper=3000.000000, Desired=1.000000, Weight=1.000000
-// Band1 Lower=4000.000000, Upper=6500.020000, Desired=0.000000, Weight=1.000000
-// Band2 Lower=7000.000000, Upper=23999.000000, Desired=0.000000, Weight=1.000000
-//Coefficients:
-
-
-//const DSPFLOAT downSampleFilterParam[DSFILTERLEN]=
-//{
-//   0.000302984,
-//   0.00251395,
-//   0.000720718,
-//   0.000752883,
-//   0.000313521,
-//   -0.000239004,
-//   -0.00082934,
-//   -0.00132562,
-//   -0.00160754,
-//   -0.00158137,
-//   -0.00119945,
-//   -0.000480743,
-//   0.000478348,
-//   0.00149955,
-//   0.00235235,
-//   0.00279834,
-//   0.00266094,
-//   0.00188006,
-//   0.00054949,
-//   -0.00109067,
-//   -0.00270158,
-//   -0.00391293,
-//   -0.00440711,
-//   -0.00398884,
-//   -0.00263551,
-//   -0.000521475,
-//   0.00199194,
-//   0.00440711,
-//   0.00617188,
-//   0.00679615,
-//   0.00597685,
-//   0.00369732,
-//   0.000277493,
-//   -0.00365566,
-//   -0.00727899,
-//   -0.00974173,
-//   -0.0103496,
-//   -0.00873256,
-//   -0.00495604,
-//   0.000443261,
-//   0.00651177,
-//   0.0120219,
-//   0.0156842,
-//   0.0164019,
-//   0.0135302,
-//   0.00709349,
-//   -0.00211602,
-//   -0.0125803,
-//   -0.0222385,
-//   -0.0288071,
-//   -0.0301798,
-//   -0.0248006,
-//   -0.0119883,
-//   0.00786467,
-//   0.0332831,
-//   0.0618213,
-//   0.0903879,
-//   0.115644,
-//    0.1345,
-//   0.144575,
-//   0.144575,
-//    0.1345,
-//   0.115644,
-//   0.0903879,
-//   0.0618213,
-//   0.0332831,
-//   0.00786467,
-//   -0.0119883,
-//   -0.0248006,
-//   -0.0301798,
-//   -0.0288071,
-//   -0.0222385,
-//   -0.0125803,
-//   -0.00211602,
-//   0.00709349,
-//   0.0135302,
-//   0.0164019,
-//   0.0156842,
-//   0.0120219,
-//   0.00651177,
-//   0.000443261,
-//   -0.00495604,
-//   -0.00873256,
-//   -0.0103496,
-//   -0.00974173,
-//   -0.00727899,
-//   -0.00365566,
-//   0.000277493,
-//   0.00369732,
-//   0.00597685,
-//   0.00679615,
-//   0.00617188,
-//   0.00440711,
-//   0.00199194,
-//   -0.000521475,
-//   -0.00263551,
-//   -0.00398884,
-//   -0.00440711,
-//   -0.00391293,
-//   -0.00270158,
-//   -0.00109067,
-//   0.00054949,
-//   0.00188006,
-//   0.00266094,
-//   0.00279834,
-//   0.00235235,
-//   0.00149955,
-//   0.000478348,
-//   -0.000480743,
-//   -0.00119945,
-//   -0.00158137,
-//   -0.00160754,
-//   -0.00132562,
-//   -0.00082934,
-//   -0.000239004,
-//   0.000313521,
-//   0.000752883,
-//   0.000720718,
-//   0.00251395,
-//   0.000302984
-//};
-
-
- // rFIR
- // localSamplingrate = 12000.000000
- // number of taps = 251
- // Band0 Lower=0.000000, Upper=550.000000, Desired=1.000000, Weight=1.000000
- // Band1 Lower=1050.000000, Upper=5999.000000, Desired=0.000000, Weight=1.000000
- //Coefficients:
- const FILTERPARAMTYPE wide600Hz[RXNUMTAPS]=
- {
-    1.02116e-08,
-    1.86956e-08,
-    2.95997e-08,
-    3.67411e-08,
-    3.28803e-08,
-    9.86893e-09,
-    -3.85738e-08,
-    -1.13046e-07,
-    -2.04568e-07,
-    -2.91967e-07,
-    -3.42147e-07,
-    -3.14635e-07,
-    -1.71071e-07,
-    1.1124e-07,
-    5.23967e-07,
-    1.01483e-06,
-    1.48207e-06,
-    1.78127e-06,
-    1.74781e-06,
-    1.23487e-06,
-    1.62235e-07,
-    -1.43354e-06,
-    -3.3612e-06,
-    -5.2643e-06,
-    -6.65105e-06,
-    -6.97116e-06,
-    -5.73598e-06,
-    -2.66528e-06,
-    2.16834e-06,
-    8.23547e-06,
-    1.45259e-05,
-    1.96364e-05,
-    2.19833e-05,
-    2.01253e-05,
-    1.31516e-05,
-    1.0579e-06,
-    -1.4981e-05,
-    -3.25401e-05,
-    -4.81454e-05,
-    -5.77759e-05,
-    -5.76296e-05,
-    -4.5044e-05,
-    -1.93995e-05,
-    1.72081e-05,
-    5.97375e-05,
-    0.000100575,
-    0.000130573,
-    0.000140686,
-    0.000123958,
-    7.75329e-05,
-    4.21222e-06,
-    -8.68583e-05,
-    -0.000180729,
-    -0.000258554,
-    -0.000300753,
-    -0.000290988,
-    -0.000220288,
-    -9.0445e-05,
-    8.41753e-05,
-    0.000277112,
-    0.000452921,
-    0.000572765,
-    0.000601767,
-    0.000516923,
-    0.000314004,
-    1.18484e-05,
-    -0.000347327,
-    -0.000702346,
-    -0.00098214,
-    -0.00111838,
-    -0.00105967,
-    -0.000784711,
-    -0.000311538,
-    0.000299689,
-    0.000951857,
-    0.00152431,
-    0.00189303,
-    0.00195464,
-    0.00164989,
-    0.000981973,
-    2.52672e-05,
-    -0.00107873,
-    -0.0021392,
-    -0.00294598,
-    -0.00330765,
-    -0.00309123,
-    -0.00225613,
-    -0.000874798,
-    0.000865638,
-    0.00268356,
-    0.00424397,
-    0.00521526,
-    0.00533284,
-    0.00445837,
-    0.0026227,
-    4.24788e-05,
-    -0.00289622,
-    -0.00568812,
-    -0.00778773,
-    -0.00870587,
-    -0.00810812,
-    -0.00589723,
-    -0.00226255,
-    0.00231648,
-    0.00711898,
-    0.0112808,
-    0.0139308,
-    0.0143459,
-    0.0121003,
-    0.00718252,
-    5.75686e-05,
-    -0.00834188,
-    -0.0167013,
-    -0.0234799,
-    -0.0271187,
-    -0.0262714,
-    -0.0200251,
-    -0.00807634,
-    0.00916805,
-    0.0305845,
-    0.0544271,
-    0.0785142,
-    0.100484,
-    0.118085,
-    0.129463,
-    0.133397,
-    0.129463,
-    0.118085,
-    0.100484,
-    0.0785142,
-    0.0544271,
-    0.0305845,
-    0.00916805,
-    -0.00807634,
-    -0.0200251,
-    -0.0262714,
-    -0.0271187,
-    -0.0234799,
-    -0.0167013,
-    -0.00834188,
-    5.75686e-05,
-    0.00718252,
-    0.0121003,
-    0.0143459,
-    0.0139308,
-    0.0112808,
-    0.00711898,
-    0.00231648,
-    -0.00226255,
-    -0.00589723,
-    -0.00810812,
-    -0.00870587,
-    -0.00778773,
-    -0.00568812,
-    -0.00289622,
-    4.24788e-05,
-    0.0026227,
-    0.00445837,
-    0.00533284,
-    0.00521526,
-    0.00424397,
-    0.00268356,
-    0.000865638,
-    -0.000874798,
-    -0.00225613,
-    -0.00309123,
-    -0.00330765,
-    -0.00294598,
-    -0.0021392,
-    -0.00107873,
-    2.52672e-05,
-    0.000981973,
-    0.00164989,
-    0.00195464,
-    0.00189303,
-    0.00152431,
-    0.000951857,
-    0.000299689,
-    -0.000311538,
-    -0.000784711,
-    -0.00105967,
-    -0.00111838,
-    -0.00098214,
-    -0.000702346,
-    -0.000347327,
-    1.18484e-05,
-    0.000314004,
-    0.000516923,
-    0.000601767,
-    0.000572765,
-    0.000452921,
-    0.000277112,
-    8.41753e-05,
-    -9.0445e-05,
-    -0.000220288,
-    -0.000290988,
-    -0.000300753,
-    -0.000258554,
-    -0.000180729,
-    -8.68583e-05,
-    4.21222e-06,
-    7.75329e-05,
-    0.000123958,
-    0.000140686,
-    0.000130573,
-    0.000100575,
-    5.97375e-05,
-    1.72081e-05,
-    -1.93995e-05,
-    -4.5044e-05,
-    -5.76296e-05,
-    -5.77759e-05,
-    -4.81454e-05,
-    -3.25401e-05,
-    -1.4981e-05,
-    1.0579e-06,
-    1.31516e-05,
-    2.01253e-05,
-    2.19833e-05,
-    1.96364e-05,
-    1.45259e-05,
-    8.23547e-06,
-    2.16834e-06,
-    -2.66528e-06,
-    -5.73598e-06,
-    -6.97116e-06,
-    -6.65105e-06,
-    -5.2643e-06,
-    -3.3612e-06,
-    -1.43354e-06,
-    1.62235e-07,
-    1.23487e-06,
-    1.74781e-06,
-    1.78127e-06,
-    1.48207e-06,
-    1.01483e-06,
-    5.23967e-07,
-    1.1124e-07,
-    -1.71071e-07,
-    -3.14635e-07,
-    -3.42147e-07,
-    -2.91967e-07,
-    -2.04568e-07,
-    -1.13046e-07,
-    -3.85738e-08,
-    9.86893e-09,
-    3.28803e-08,
-    3.67411e-08,
-    2.95997e-08,
-    1.86956e-08,
-    1.02116e-08
- };
-
+#define HILBERTTAPS 121
+const double hilbertCoef[HILBERTTAPS]=
+{
+   0,
+   0.00136661718665926,
+   0,
+   0.00150286602326731,
+   0,
+   0.00173952945285506,
+   0,
+   0.00208590573228844,
+   0,
+   0.00255170586026178,
+   0,
+   0.00314717426010419,
+   0,
+   0.00388325229212327,
+   0,
+   0.00477179734787085,
+   0,
+   0.00582587488644361,
+   0,
+   0.00706014741202653,
+   0,
+   0.00849139410563612,
+   0,
+   0.0101392092759233,
+   0,
+   0.0120269496929383,
+   0,
+   0.0141830347297422,
+   0,
+   0.0166427567783305,
+   0,
+   0.0194508462024743,
+   0,
+   0.0226651797747595,
+   0,
+   0.0263622704298864,
+   0,
+   0.0306456198604712,
+   0,
+   0.0356588395181044,
+   0,
+   0.0416070503214164,
+   0,
+   0.0487933752872309,
+   0,
+   0.0576846079563875,
+   0,
+   0.0690374724823236,
+   0,
+   0.0841625873868087,
+   0,
+   0.105540333458517,
+   0,
+   0.138492428026959,
+   0,
+   0.196865176018594,
+   0,
+   0.331445545557921,
+   0,
+   0.999369585987104,
+   0,
+   -0.999369585987104,
+   0,
+   -0.331445545557921,
+   0,
+   -0.196865176018594,
+   0,
+   -0.138492428026959,
+   0,
+   -0.105540333458517,
+   0,
+   -0.0841625873868087,
+   0,
+   -0.0690374724823236,
+   0,
+   -0.0576846079563875,
+   0,
+   -0.0487933752872309,
+   0,
+   -0.0416070503214164,
+   0,
+   -0.0356588395181044,
+   0,
+   -0.0306456198604712,
+   0,
+   -0.0263622704298864,
+   0,
+   -0.0226651797747595,
+   0,
+   -0.0194508462024743,
+   0,
+   -0.0166427567783305,
+   0,
+   -0.0141830347297422,
+   0,
+   -0.0120269496929383,
+   0,
+   -0.0101392092759233,
+   0,
+   -0.00849139410563612,
+   0,
+   -0.00706014741202653,
+   0,
+   -0.00582587488644361,
+   0,
+   -0.00477179734787085,
+   0,
+   -0.00388325229212327,
+   0,
+   -0.00314717426010419,
+   0,
+   -0.00255170586026178,
+   0,
+   -0.00208590573228844,
+   0,
+   -0.00173952945285506,
+   0,
+   -0.00150286602326731,
+   0,
+   -0.00136661718665926,
+   0
+};
 
 
- // blFIR  Root Raised Cosine
+ // blFIR  Raised cosine
  // localSamplingrate = 12000.000000
- // number of taps = 251
- // corner frequency = 175.000000
- // beta = 0.600000
+ // number of taps = 181
+ // corner frequency = 600.000000
+ // beta = 0.750000
  // window applied
+ // demodulator frequency = 1900.000000
  //Coefficients:
- const  FILTERPARAMTYPE wide1200BP[RXNUMTAPS]=
+  const double videoFilterCoefFIR[VIDEOFIRNUMTAPS]=
  {
-    -0.000609128,
-    -0.000552292,
-    -0.000480985,
-    -0.000395195,
-    -0.000294978,
-    -0.000180515,
-    -5.21677e-05,
-    8.9455e-05,
-    0.000243425,
-    0.000408425,
-    0.000582684,
-    0.000763914,
-    0.000949268,
-    0.0011353,
-    0.00131798,
-    0.00149267,
-    0.00165418,
-    0.00179686,
-    0.00191467,
-    0.0020013,
-    0.00205037,
-    0.00205558,
-    0.00201094,
-    0.00191099,
-    0.00175106,
-    0.00152749,
-    0.00123794,
-    0.000881561,
-    0.000459301,
-    -2.59536e-05,
-    -0.000569184,
-    -0.00116312,
-    -0.0017982,
-    -0.00246251,
-    -0.00314192,
-    -0.00382017,
-    -0.00447909,
-    -0.00509894,
-    -0.00565873,
-    -0.00613672,
-    -0.00651091,
-    -0.00675969,
-    -0.00686239,
-    -0.00680006,
-    -0.00655616,
-    -0.00611727,
-    -0.00547384,
-    -0.00462086,
-    -0.00355856,
-    -0.00229294,
-    -0.000836296,
-    0.000792401,
-    0.00256725,
-    0.00445533,
-    0.00641673,
-    0.0084048,
-    0.0103666,
-    0.0122434,
-    0.0139717,
-    0.0154841,
-    0.0167105,
-    0.0175795,
-    0.0180201,
-    0.017963,
-    0.0173428,
-    0.0160997,
-    0.0141814,
-    0.0115451,
-    0.00815967,
-    0.00400701,
-    -0.000915743,
-    -0.00659481,
-    -0.0129983,
-    -0.0200751,
-    -0.0277539,
-    -0.0359425,
-    -0.0445279,
-    -0.0533762,
-    -0.0623329,
-    -0.0712244,
-    -0.0798588,
-    -0.0880279,
-    -0.0955092,
-    -0.102069,
-    -0.107464,
-    -0.111446,
-    -0.113765,
-    -0.114172,
-    -0.112426,
-    -0.108292,
-    -0.101553,
-    -0.0920066,
-    -0.079476,
-    -0.0638084,
-    -0.0448816,
-    -0.0226067,
-    0.00306903,
-    0.0321591,
-    0.064636,
-    0.10043,
-    0.139426,
-    0.181466,
-    0.226349,
-    0.273829,
-    0.32362,
-    0.375396,
-    0.428795,
-    0.483422,
-    0.538853,
-    0.594642,
-    0.650321,
-    0.705409,
-    0.759419,
-    0.81186,
-    0.862247,
-    0.910103,
-    0.95497,
-    0.996411,
-    1.03402,
-    1.06742,
-    1.09628,
-     1.1203,
-    1.13925,
-    1.15292,
-    1.16118,
-    1.16394,
-    1.16118,
-    1.15292,
-    1.13925,
-     1.1203,
-    1.09628,
-    1.06742,
-    1.03402,
-    0.996411,
-    0.95497,
-    0.910103,
-    0.862247,
-    0.81186,
-    0.759419,
-    0.705409,
-    0.650321,
-    0.594642,
-    0.538853,
-    0.483422,
-    0.428795,
-    0.375396,
-    0.32362,
-    0.273829,
-    0.226349,
-    0.181466,
-    0.139426,
-    0.10043,
-    0.064636,
-    0.0321591,
-    0.00306903,
-    -0.0226067,
-    -0.0448816,
-    -0.0638084,
-    -0.079476,
-    -0.0920066,
-    -0.101553,
-    -0.108292,
-    -0.112426,
-    -0.114172,
-    -0.113765,
-    -0.111446,
-    -0.107464,
-    -0.102069,
-    -0.0955092,
-    -0.0880279,
-    -0.0798588,
-    -0.0712244,
-    -0.0623329,
-    -0.0533762,
-    -0.0445279,
-    -0.0359425,
-    -0.0277539,
-    -0.0200751,
-    -0.0129983,
-    -0.00659481,
-    -0.000915743,
-    0.00400701,
-    0.00815967,
-    0.0115451,
-    0.0141814,
-    0.0160997,
-    0.0173428,
-    0.017963,
-    0.0180201,
-    0.0175795,
-    0.0167105,
-    0.0154841,
-    0.0139717,
-    0.0122434,
-    0.0103666,
-    0.0084048,
-    0.00641673,
-    0.00445533,
-    0.00256725,
-    0.000792401,
-    -0.000836296,
-    -0.00229294,
-    -0.00355856,
-    -0.00462086,
-    -0.00547384,
-    -0.00611727,
-    -0.00655616,
-    -0.00680006,
-    -0.00686239,
-    -0.00675969,
-    -0.00651091,
-    -0.00613672,
-    -0.00565873,
-    -0.00509894,
-    -0.00447909,
-    -0.00382017,
-    -0.00314192,
-    -0.00246251,
-    -0.0017982,
-    -0.00116312,
-    -0.000569184,
-    -2.59536e-05,
-    0.000459301,
-    0.000881561,
-    0.00123794,
-    0.00152749,
-    0.00175106,
-    0.00191099,
-    0.00201094,
-    0.00205558,
-    0.00205037,
-    0.0020013,
-    0.00191467,
-    0.00179686,
-    0.00165418,
-    0.00149267,
-    0.00131798,
-    0.0011353,
-    0.000949268,
-    0.000763914,
-    0.000582684,
-    0.000408425,
-    0.000243425,
-    8.9455e-05,
-    -5.21677e-05,
-    -0.000180515,
-    -0.000294978,
-    -0.000395195,
-    -0.000480985,
-    -0.000552292,
-    -0.000609128
+    -5.95079099057804e-10,
+    2.61594114263829e-06,
+    3.07729445250339e-06,
+    1.13346812319689e-06,
+    -2.81039541066542e-06,
+    -7.71403862925782e-06,
+    -1.20902779206499e-05,
+    -1.43480585720805e-05,
+    -1.32321049757815e-05,
+    -8.25642905210925e-06,
+    -8.8690505641396e-10,
+    9.85490870415174e-06,
+    1.88370834684704e-05,
+    2.43089145306048e-05,
+    2.43023278940623e-05,
+    1.83229993522338e-05,
+    7.85321630695235e-06,
+    -3.68955136329723e-06,
+    -1.16535011354391e-05,
+    -1.14292066221272e-05,
+    -8.56425709155406e-10,
+    2.26937879393592e-05,
+    5.31013029640608e-05,
+    8.44693399972315e-05,
+    0.000108437566877532,
+    0.000117516745719292,
+    0.000107804015822502,
+    8.10619160782521e-05,
+    4.53200756323171e-05,
+    1.34836012044786e-05,
+    4.67663404802913e-10,
+    1.63077977096724e-05,
+    6.63373159783328e-05,
+    0.000143602388130073,
+    0.000231167770515414,
+    0.000305100922643006,
+    0.000340960709772466,
+    0.000321776690478599,
+    0.00024516504372674,
+    0.000127040816986674,
+    3.07474299002907e-09,
+    -9.41572318815693e-05,
+    -0.000116551026159502,
+    -4.48417913051135e-05,
+    0.000115715984449913,
+    0.000328008733459506,
+    0.000528359700943291,
+    0.000641639760490251,
+    0.000603309341113929,
+    0.000382667745394857,
+    5.07420985957315e-09,
+    -0.000469217752322882,
+    -0.000907327495708766,
+    -0.00118411058956563,
+    -0.00119735462753749,
+    -0.000913688724887437,
+    -0.000396724829308208,
+    0.000189401487028102,
+    0.000607970575897167,
+    0.000607729096403849,
+    4.04354956239952e-09,
+    -0.00126468871755123,
+    -0.0030447073080987,
+    -0.0050026587472757,
+    -0.00666218441709886,
+    -0.00752559482438273,
+    -0.00723379086110548,
+    -0.00573280278322614,
+    -0.00339989003366721,
+    -0.00108070804009379,
+    -4.47539616976694e-10,
+    -0.00153133221611757,
+    -0.00684316096120548,
+    -0.0164729300340849,
+    -0.0299100809708232,
+    -0.0452851334961788,
+    -0.0592593190702364,
+    -0.0671852210265427,
+    -0.0635655234097977,
+    -0.0427809457400524,
+    -5.79017893606645e-09,
+    0.0678656067027252,
+    0.161324303280179,
+    0.277750017046145,
+    0.411240997967613,
+    0.552962972340781,
+    0.691968966816512,
+    0.816404845411836,
+    0.914937426323293,
+    0.978195191561545,
+    0.999999991829453,
+    0.978195191561545,
+    0.914937426323293,
+    0.816404845411835,
+    0.691968966816512,
+    0.552962972340781,
+    0.411240997967613,
+    0.277750017046145,
+    0.161324303280179,
+    0.0678656067027251,
+    -5.7901789909994e-09,
+    -0.0427809457400526,
+    -0.0635655234097978,
+    -0.0671852210265427,
+    -0.0592593190702365,
+    -0.0452851334961789,
+    -0.0299100809708232,
+    -0.0164729300340851,
+    -0.0068431609612055,
+    -0.00153133221611756,
+    -4.47539662828152e-10,
+    -0.00108070804009387,
+    -0.00339989003366724,
+    -0.00573280278322617,
+    -0.0072337908611055,
+    -0.00752559482438273,
+    -0.00666218441709888,
+    -0.00500265874727575,
+    -0.00304470730809871,
+    -0.00126468871755125,
+    4.04354947839136e-09,
+    0.000607729096403787,
+    0.000607970575897167,
+    0.000189401487028064,
+    -0.000396724829308279,
+    -0.000913688724887445,
+    -0.00119735462753749,
+    -0.00118411058956567,
+    -0.000907327495708759,
+    -0.000469217752322886,
+    5.07420985335003e-09,
+    0.000382667745394851,
+    0.000603309341113924,
+    0.000641639760490234,
+    0.000528359700943286,
+    0.000328008733459503,
+    0.000115715984449906,
+    -4.48417913051266e-05,
+    -0.000116551026159501,
+    -9.41572318815944e-05,
+    3.07474298592771e-09,
+    0.000127040816986674,
+    0.000245165043726731,
+    0.000321776690478589,
+    0.000340960709772462,
+    0.000305100922643003,
+    0.000231167770515413,
+    0.000143602388130061,
+    6.63373159783267e-05,
+    1.63077977096627e-05,
+    4.6766337918414e-10,
+    1.34836012044776e-05,
+    4.53200756322965e-05,
+    8.10619160782543e-05,
+    0.000107804015822502,
+    0.000117516745719295,
+    0.000108437566877516,
+    8.44693399972232e-05,
+    5.31013029640469e-05,
+    2.26937879393536e-05,
+    -8.56425709045839e-10,
+    -1.14292066221334e-05,
+    -1.16535011354395e-05,
+    -3.68955136329843e-06,
+    7.85321630695073e-06,
+    1.83229993522318e-05,
+    2.43023278940613e-05,
+    2.43089145306041e-05,
+    1.88370834684694e-05,
+    9.85490870414851e-06,
+    -8.86905056186294e-10,
+    -8.25642905211096e-06,
+    -1.32321049757817e-05,
+    -1.43480585720802e-05,
+    -1.20902779206511e-05,
+    -7.71403862925922e-06,
+    -2.81039541066544e-06,
+    1.13346812319585e-06,
+    3.07729445250303e-06,
+    2.61594114263834e-06,
+    -5.95079099262779e-10
  };
 
 
- // rFIR
- // localSamplingrate = 48000.000000
- // number of taps = 121
- // Band0 Lower=0.000000, Upper=2700.000000, Desired=1.000000, Weight=1.000000
- // Band1 Lower=3500.000000, Upper=23999.000000, Desired=0.000000, Weight=1.000000
- //Coefficients:
-  const  FILTERPARAMTYPE wfFilter[TXWFNUMTAPS]=
- {
-    0.00116433,
-    -0.00494437,
-    -0.00227196,
-    -0.00162745,
-    -0.00119222,
-    -0.000602408,
-    0.000154827,
-    0.000987978,
-    0.00175857,
-    0.00231978,
-    0.00254186,
-    0.00234367,
-    0.0017027,
-    0.000677718,
-    -0.000595763,
-    -0.00192037,
-    -0.00307107,
-    -0.0038171,
-    -0.00398386,
-    -0.00346983,
-    -0.00228737,
-    -0.000567514,
-    0.00145033,
-    0.00344646,
-    0.00506842,
-    0.00599002,
-    0.00597109,
-    0.00490811,
-    0.00286844,
-    9.73674e-05,
-    -0.00300691,
-    -0.00594212,
-    -0.00817976,
-    -0.00925143,
-    -0.00883636,
-    -0.00682964,
-    -0.00339026,
-    0.00106452,
-    0.00589068,
-    0.0103035,
-    0.0134903,
-    0.0147392,
-    0.0135693,
-    0.00983817,
-    0.00380649,
-    -0.00385039,
-    -0.0120879,
-    -0.0196086,
-    -0.0250088,
-    -0.0269742,
-    -0.0244494,
-    -0.0168371,
-    -0.004072,
-    0.0132752,
-    0.034055,
-    0.0566447,
-    0.0790638,
-    0.0992571,
-    0.115295,
-    0.12561,
-    0.129165,
-    0.12561,
-    0.115295,
-    0.0992571,
-    0.0790638,
-    0.0566447,
-    0.034055,
-    0.0132752,
-    -0.004072,
-    -0.0168371,
-    -0.0244494,
-    -0.0269742,
-    -0.0250088,
-    -0.0196086,
-    -0.0120879,
-    -0.00385039,
-    0.00380649,
-    0.00983817,
-    0.0135693,
-    0.0147392,
-    0.0134903,
-    0.0103035,
-    0.00589068,
-    0.00106452,
-    -0.00339026,
-    -0.00682964,
-    -0.00883636,
-    -0.00925143,
-    -0.00817976,
-    -0.00594212,
-    -0.00300691,
-    9.73674e-05,
-    0.00286844,
-    0.00490811,
-    0.00597109,
-    0.00599002,
-    0.00506842,
-    0.00344646,
-    0.00145033,
-    -0.000567514,
-    -0.00228737,
-    -0.00346983,
-    -0.00398386,
-    -0.0038171,
-    -0.00307107,
-    -0.00192037,
-    -0.000595763,
-    0.000677718,
-    0.0017027,
-    0.00234367,
-    0.00254186,
-    0.00231978,
-    0.00175857,
-    0.000987978,
-    0.000154827,
-    -0.000602408,
-    -0.00119222,
-    -0.00162745,
-    -0.00227196,
-    -0.00494437,
-    0.00116433
- };
-
-// // blFIR  Raised cosine
-// // localSamplingrate = 12000.000000
-// // number of taps = 251
-// // corner frequency = 750.000000
-// // beta = 0.600000
-// // window applied
-// //Coefficients:
-// const  DSPFLOAT  wideVolumeFilter[RXNUMTAPS]=
-// {
-//    -1.64544e-06,
-//    -2.80612e-06,
-//    -3.45436e-06,
-//    -3.203e-06,
-//    -1.96312e-06,
-//    2.05821e-19,
-//    2.13622e-06,
-//    3.79135e-06,
-//    4.44443e-06,
-//    3.91982e-06,
-//    2.49121e-06,
-//    8.24608e-07,
-//    -2.39152e-07,
-//          0,
-//    1.79747e-06,
-//    4.79367e-06,
-//    8.06507e-06,
-//    1.04095e-05,
-//    1.07867e-05,
-//    8.75844e-06,
-//    4.75057e-06,
-//    -4.21053e-19,
-//    -3.83858e-06,
-//    -5.31774e-06,
-//    -3.83133e-06,
-//    4.45013e-09,
-//    4.42064e-06,
-//    7.05764e-06,
-//    5.86252e-06,
-//          0,
-//    -9.60024e-06,
-//    -2.03439e-05,
-//    -2.8777e-05,
-//    -3.18678e-05,
-//    -2.83026e-05,
-//    -1.92589e-05,
-//    -8.2549e-06,
-//    -2.78137e-19,
-//    1.42117e-06,
-//    -5.6256e-06,
-//    -1.92495e-05,
-//    -3.42703e-05,
-//    -4.38597e-05,
-//    -4.21144e-05,
-//    -2.66287e-05,
-//          0,
-//    3.05108e-05,
-//    5.52904e-05,
-//    6.59811e-05,
-//    5.90786e-05,
-//    3.8027e-05,
-//    1.27283e-05,
-//    -3.70396e-06,
-//    -1.21098e-19,
-//    2.82294e-05,
-//    7.55602e-05,
-//    0.000127442,
-//    0.000164744,
-//    0.000170855,
-//    0.000138769,
-//    7.52615e-05,
-//          0,
-//    -6.07716e-05,
-//    -8.41658e-05,
-//    -6.06472e-05,
-//    1.49487e-08,
-//    6.98882e-05,
-//    0.000111706,
-//    9.29209e-05,
-//    -3.02042e-19,
-//    -0.000152851,
-//    -0.000324975,
-//    -0.000461565,
-//    -0.000513668,
-//    -0.000458879,
-//    -0.000314394,
-//    -0.000135826,
-//          0,
-//    2.38653e-05,
-//    -9.53061e-05,
-//    -0.000330391,
-//    -0.000596491,
-//    -0.000775191,
-//    -0.00075694,
-//    -0.000487457,
-//    3.07131e-18,
-//    0.000582257,
-//    0.00108022,
-//    0.00132227,
-//    0.00121691,
-//    0.000806873,
-//    0.000278913,
-//    -8.38671e-05,
-//          0,
-//    0.000690779,
-//    0.00192988,
-//    0.00340841,
-//    0.00462998,
-//    0.00506502,
-//    0.00435752,
-//    0.00251474,
-//    1.4594e-18,
-//    -0.00233525,
-//    -0.00349956,
-//    -0.00274763,
-//    2.46719e-08,
-//    0.00384959,
-//    0.0068861,
-//    0.00648597,
-//          0,
-//    -0.0142972,
-//    -0.0362032,
-//    -0.0628097,
-//    -0.0882278,
-//    -0.10402,
-//    -0.100387,
-//    -0.0679779,
-//    -3.55038e-18,
-//    0.105805,
-//    0.245799,
-//    0.41008,
-//    0.583323,
-//    0.74676,
-//    0.881013,
-//    0.96924,
-//          1,
-//    0.96924,
-//    0.881013,
-//    0.74676,
-//    0.583323,
-//    0.41008,
-//    0.245799,
-//    0.105805,
-//    -3.55038e-18,
-//    -0.0679779,
-//    -0.100387,
-//    -0.10402,
-//    -0.0882278,
-//    -0.0628097,
-//    -0.0362032,
-//    -0.0142972,
-//          0,
-//    0.00648597,
-//    0.0068861,
-//    0.00384959,
-//    2.46719e-08,
-//    -0.00274763,
-//    -0.00349956,
-//    -0.00233525,
-//    1.4594e-18,
-//    0.00251474,
-//    0.00435752,
-//    0.00506502,
-//    0.00462998,
-//    0.00340841,
-//    0.00192988,
-//    0.000690779,
-//          0,
-//    -8.38671e-05,
-//    0.000278913,
-//    0.000806873,
-//    0.00121691,
-//    0.00132227,
-//    0.00108022,
-//    0.000582257,
-//    3.07131e-18,
-//    -0.000487457,
-//    -0.00075694,
-//    -0.000775191,
-//    -0.000596491,
-//    -0.000330391,
-//    -9.53061e-05,
-//    2.38653e-05,
-//          0,
-//    -0.000135826,
-//    -0.000314394,
-//    -0.000458879,
-//    -0.000513668,
-//    -0.000461565,
-//    -0.000324975,
-//    -0.000152851,
-//    -3.02042e-19,
-//    9.29209e-05,
-//    0.000111706,
-//    6.98882e-05,
-//    1.49487e-08,
-//    -6.06472e-05,
-//    -8.41658e-05,
-//    -6.07716e-05,
-//          0,
-//    7.52615e-05,
-//    0.000138769,
-//    0.000170855,
-//    0.000164744,
-//    0.000127442,
-//    7.55602e-05,
-//    2.82294e-05,
-//    -1.21098e-19,
-//    -3.70396e-06,
-//    1.27283e-05,
-//    3.8027e-05,
-//    5.90786e-05,
-//    6.59811e-05,
-//    5.52904e-05,
-//    3.05108e-05,
-//          0,
-//    -2.66287e-05,
-//    -4.21144e-05,
-//    -4.38597e-05,
-//    -3.42703e-05,
-//    -1.92495e-05,
-//    -5.6256e-06,
-//    1.42117e-06,
-//    -2.78137e-19,
-//    -8.2549e-06,
-//    -1.92589e-05,
-//    -2.83026e-05,
-//    -3.18678e-05,
-//    -2.8777e-05,
-//    -2.03439e-05,
-//    -9.60024e-06,
-//          0,
-//    5.86252e-06,
-//    7.05764e-06,
-//    4.42064e-06,
-//    4.45013e-09,
-//    -3.83133e-06,
-//    -5.31774e-06,
-//    -3.83858e-06,
-//    -4.21053e-19,
-//    4.75057e-06,
-//    8.75844e-06,
-//    1.07867e-05,
-//    1.04095e-05,
-//    8.06507e-06,
-//    4.79367e-06,
-//    1.79747e-06,
-//          0,
-//    -2.39152e-07,
-//    8.24608e-07,
-//    2.49121e-06,
-//    3.91982e-06,
-//    4.44443e-06,
-//    3.79135e-06,
-//    2.13622e-06,
-//    2.05821e-19,
-//    -1.96312e-06,
-//    -3.203e-06,
-//    -3.45436e-06,
-//    -2.80612e-06,
-//    -1.64544e-06
-// };
-
 
-//// rFIR
-//// localSamplingrate = 11025.000000
-//// number of taps = 251
-//// Band0 Lower=0.000000, Upper=400.000000, Desired=1.000000, Weight=1.000000
-//// Band1 Lower=500.001000, Upper=5512.000000, Desired=0.000000, Weight=10.000000
-////Coefficients:
 
-
-//const  DSPFLOAT  narrowRX[RXNUMTAPS]=
-//{
-//	 -0.00111256,
-//	 -0.000482835,
-//	 -0.000555539,
-//	 -0.000610215,
-//	 -0.000640108,
-//	 -0.000639526,
-//	 -0.000603611,
-//	 -0.000529568,
-//	 -0.000416333,
-//	 -0.000265628,
-//	 -8.12867e-05,
-//	 0.00013,
-//	 0.000359701,
-//	 0.000596908,
-//	 0.000829677,
-//	 0.00104457,
-//	 0.00122841,
-//	 0.00136826,
-//	 0.00145366,
-//	 0.00147624,
-//	 0.00143148,
-//	 0.00131749,
-//	 0.00113691,
-//	 0.000896014,
-//	 0.000607194,
-//	 0.000285308,
-//	 -5.19563e-05,
-//	 -0.000387275,
-//	 -0.000695131,
-//	 -0.000958842,
-//	 -0.00115846,
-//	 -0.00127739,
-//	 -0.00130528,
-//	 -0.00123462,
-//	 -0.00106591,
-//	 -0.000804428,
-//	 -0.000463007,
-//	 -5.92664e-05,
-//	 0.000383167,
-//	 0.000837539,
-//	 0.00127394,
-//	 0.0016627,
-//	 0.001975,
-//	 0.00218602,
-//	 0.00227539,
-//	 0.00223003,
-//	 0.00204437,
-//	 0.00172242,
-//	 0.00127682,
-//	 0.000729308,
-//	 0.000108946,
-//	 -0.000547891,
-//	 -0.00120085,
-//	 -0.00180748,
-//	 -0.00232648,
-//	 -0.00271827,
-//	 -0.00295119,
-//	 -0.00300112,
-//	 -0.00285435,
-//	 -0.00251011,
-//	 -0.0019793,
-//	 -0.00128641,
-//	 -0.000467246,
-//	 0.000431672,
-//	 0.00135632,
-//	 0.00224783,
-//	 0.00304629,
-//	 0.00369428,
-//	 0.0041409,
-//	 0.00434539,
-//	 0.0042804,
-//	 0.00393443,
-//	 0.00331349,
-//	 0.00244167,
-//	 0.00136081,
-//	 0.000128749,
-//	 -0.00118363,
-//	 -0.00249613,
-//	 -0.00372356,
-//	 -0.00478096,
-//	 -0.00558948,
-//	 -0.00608132,
-//	 -0.00620458,
-//	 -0.0059281,
-//	 -0.00524423,
-//	 -0.00417056,
-//	 -0.00275136,
-//	 -0.00105514,
-//	 0.000826848,
-//	 0.00278589,
-//	 0.00470061,
-//	 0.00644423,
-//	 0.00789173,
-//	 0.00892786,
-//	 0.00945467,
-//	 0.00939881,
-//	 0.00871756,
-//	 0.0074038,
-//	 0.0054889,
-//	 0.00304369,
-//	 0.000177241,
-//	 -0.00296638,
-//	 -0.00621362,
-//	 -0.00936894,
-//	 -0.012224,
-//	 -0.0145674,
-//	 -0.0161961,
-//	 -0.0169261,
-//	 -0.0166028,
-//	 -0.015111,
-//	 -0.0123822,
-//	 -0.0084009,
-//	 -0.00320751,
-//	 0.00310037,
-//	 0.0103705,
-//	 0.0184005,
-//	 0.0269456,
-//	 0.0357282,
-//	 0.044449,
-//	 0.0528009,
-//	 0.0604811,
-//	 0.0672059,
-//	 0.0727227,
-//	 0.0768219,
-//	 0.0793463,
-//	 0.0801988,
-//	 0.0793463,
-//	 0.0768219,
-//	 0.0727227,
-//	 0.0672059,
-//	 0.0604811,
-//	 0.0528009,
-//	 0.044449,
-//	 0.0357282,
-//	 0.0269456,
-//	 0.0184005,
-//	 0.0103705,
-//	 0.00310037,
-//	 -0.00320751,
-//	 -0.0084009,
-//	 -0.0123822,
-//	 -0.015111,
-//	 -0.0166028,
-//	 -0.0169261,
-//	 -0.0161961,
-//	 -0.0145674,
-//	 -0.012224,
-//	 -0.00936894,
-//	 -0.00621362,
-//	 -0.00296638,
-//	 0.000177241,
-//	 0.00304369,
-//	 0.0054889,
-//	 0.0074038,
-//	 0.00871756,
-//	 0.00939881,
-//	 0.00945467,
-//	 0.00892786,
-//	 0.00789173,
-//	 0.00644423,
-//	 0.00470061,
-//	 0.00278589,
-//	 0.000826848,
-//	 -0.00105514,
-//	 -0.00275136,
-//	 -0.00417056,
-//	 -0.00524423,
-//	 -0.0059281,
-//	 -0.00620458,
-//	 -0.00608132,
-//	 -0.00558948,
-//	 -0.00478096,
-//	 -0.00372356,
-//	 -0.00249613,
-//	 -0.00118363,
-//	 0.000128749,
-//	 0.00136081,
-//	 0.00244167,
-//	 0.00331349,
-//	 0.00393443,
-//	 0.0042804,
-//	 0.00434539,
-//	 0.0041409,
-//	 0.00369428,
-//	 0.00304629,
-//	 0.00224783,
-//	 0.00135632,
-//	 0.000431672,
-//	 -0.000467246,
-//	 -0.00128641,
-//	 -0.0019793,
-//	 -0.00251011,
-//	 -0.00285435,
-//	 -0.00300112,
-//	 -0.00295119,
-//	 -0.00271827,
-//	 -0.00232648,
-//	 -0.00180748,
-//	 -0.00120085,
-//	 -0.000547891,
-//	 0.000108946,
-//	 0.000729308,
-//	 0.00127682,
-//	 0.00172242,
-//	 0.00204437,
-//	 0.00223003,
-//	 0.00227539,
-//	 0.00218602,
-//	 0.001975,
-//	 0.0016627,
-//	 0.00127394,
-//	 0.000837539,
-//	 0.000383167,
-//	 -5.92664e-05,
-//	 -0.000463007,
-//	 -0.000804428,
-//	 -0.00106591,
-//	 -0.00123462,
-//	 -0.00130528,
-//	 -0.00127739,
-//	 -0.00115846,
-//	 -0.000958842,
-//	 -0.000695131,
-//	 -0.000387275,
-//	 -5.19563e-05,
-//	 0.000285308,
-//	 0.000607194,
-//	 0.000896014,
-//	 0.00113691,
-//	 0.00131749,
-//	 0.00143148,
-//	 0.00147624,
-//	 0.00145366,
-//	 0.00136826,
-//	 0.00122841,
-//	 0.00104457,
-//	 0.000829677,
-//	 0.000596908,
-//	 0.000359701,
-//	 0.00013,
-//	 -8.12867e-05,
-//	 -0.000265628,
-//	 -0.000416333,
-//	 -0.000529568,
-//	 -0.000603611,
-//	 -0.000639526,
-//	 -0.000640108,
-//	 -0.000610215,
-//	 -0.000555539,
-//	 -0.000482835,
-//	 -0.00111256
-//};
+  //==========================================================
+  // rFIR
+  // localSamplingrate = 48000.000000
+  // number of taps = 121
+  // Band0 Lower=0.000000, Upper=2700.000000, Desired=1.000000, Weight=1.000000
+  // Band1 Lower=3500.000000, Upper=23999.000000, Desired=0.000000, Weight=1.000000
+  //Coefficients:
+   const  FILTERPARAMTYPE wfFilterCoef[TXWFNUMTAPS]=
+  {
+     0.00116433,
+     -0.00494437,
+     -0.00227196,
+     -0.00162745,
+     -0.00119222,
+     -0.000602408,
+     0.000154827,
+     0.000987978,
+     0.00175857,
+     0.00231978,
+     0.00254186,
+     0.00234367,
+     0.0017027,
+     0.000677718,
+     -0.000595763,
+     -0.00192037,
+     -0.00307107,
+     -0.0038171,
+     -0.00398386,
+     -0.00346983,
+     -0.00228737,
+     -0.000567514,
+     0.00145033,
+     0.00344646,
+     0.00506842,
+     0.00599002,
+     0.00597109,
+     0.00490811,
+     0.00286844,
+     9.73674e-05,
+     -0.00300691,
+     -0.00594212,
+     -0.00817976,
+     -0.00925143,
+     -0.00883636,
+     -0.00682964,
+     -0.00339026,
+     0.00106452,
+     0.00589068,
+     0.0103035,
+     0.0134903,
+     0.0147392,
+     0.0135693,
+     0.00983817,
+     0.00380649,
+     -0.00385039,
+     -0.0120879,
+     -0.0196086,
+     -0.0250088,
+     -0.0269742,
+     -0.0244494,
+     -0.0168371,
+     -0.004072,
+     0.0132752,
+     0.034055,
+     0.0566447,
+     0.0790638,
+     0.0992571,
+     0.115295,
+     0.12561,
+     0.129165,
+     0.12561,
+     0.115295,
+     0.0992571,
+     0.0790638,
+     0.0566447,
+     0.034055,
+     0.0132752,
+     -0.004072,
+     -0.0168371,
+     -0.0244494,
+     -0.0269742,
+     -0.0250088,
+     -0.0196086,
+     -0.0120879,
+     -0.00385039,
+     0.00380649,
+     0.00983817,
+     0.0135693,
+     0.0147392,
+     0.0134903,
+     0.0103035,
+     0.00589068,
+     0.00106452,
+     -0.00339026,
+     -0.00682964,
+     -0.00883636,
+     -0.00925143,
+     -0.00817976,
+     -0.00594212,
+     -0.00300691,
+     9.73674e-05,
+     0.00286844,
+     0.00490811,
+     0.00597109,
+     0.00599002,
+     0.00506842,
+     0.00344646,
+     0.00145033,
+     -0.000567514,
+     -0.00228737,
+     -0.00346983,
+     -0.00398386,
+     -0.0038171,
+     -0.00307107,
+     -0.00192037,
+     -0.000595763,
+     0.000677718,
+     0.0017027,
+     0.00234367,
+     0.00254186,
+     0.00231978,
+     0.00175857,
+     0.000987978,
+     0.000154827,
+     -0.000602408,
+     -0.00119222,
+     -0.00162745,
+     -0.00227196,
+     -0.00494437,
+     0.00116433
+  };
+
+
+   // blFIR  Hilbert
+   // localSamplingrate = 12000.000000
+   // number of taps = 153
+   // corner frequency = 1000.000000
+   // beta = 0.500000
+   // window applied
+   //Coefficients:
+    const FILTERPARAMTYPE drmHilbertCoef[DRMHILBERTTAPS]=
+   {
+      0,
+      0.00107190601522455,
+      0,
+      0.00114428127836931,
+      0,
+      0.00126465142463967,
+      0,
+      0.00143657040680006,
+      0,
+      0.00166370297755838,
+      0,
+      0.00194984843584138,
+      0,
+      0.00229897112682306,
+      0,
+      0.00271523918124115,
+      0,
+      0.00320307336657778,
+      0,
+      0.00376720843252962,
+      0,
+      0.00441277001061758,
+      0,
+      0.00514537103613413,
+      0,
+      0.00597123289056438,
+      0,
+      0.00689733814551449,
+      0,
+      0.00793162411788592,
+      0,
+      0.00908322970767581,
+      0,
+      0.0103628126183723,
+      0,
+      0.0117829607223439,
+      0,
+      0.0133587310729627,
+      0,
+      0.015108364544715,
+      0,
+      0.0170542460109686,
+      0,
+      0.0192242138609088,
+      0,
+      0.0216533762307932,
+      0,
+      0.0243866781537711,
+      0,
+      0.027482608550733,
+      0,
+      0.0310186849032487,
+      0,
+      0.035099797177604,
+      0,
+      0.0398713166388587,
+      0,
+      0.0455404799655691,
+      0,
+      0.0524128630218771,
+      0,
+      0.0609580273296193,
+      0,
+      0.0719357553084729,
+      0,
+      0.0866599865154828,
+      0,
+      0.10761465561151,
+      0,
+      0.140125234561542,
+      0,
+      0.198041949770117,
+      0,
+      0.332155822226347,
+      0,
+      0.999607048858159,
+      0,
+      -0.999607048858159,
+      0,
+      -0.332155822226347,
+      0,
+      -0.198041949770117,
+      0,
+      -0.140125234561542,
+      0,
+      -0.10761465561151,
+      0,
+      -0.0866599865154828,
+      0,
+      -0.0719357553084729,
+      0,
+      -0.0609580273296193,
+      0,
+      -0.0524128630218771,
+      0,
+      -0.0455404799655691,
+      0,
+      -0.0398713166388587,
+      0,
+      -0.035099797177604,
+      0,
+      -0.0310186849032487,
+      0,
+      -0.027482608550733,
+      0,
+      -0.0243866781537711,
+      0,
+      -0.0216533762307932,
+      0,
+      -0.0192242138609088,
+      0,
+      -0.0170542460109686,
+      0,
+      -0.015108364544715,
+      0,
+      -0.0133587310729627,
+      0,
+      -0.0117829607223439,
+      0,
+      -0.0103628126183723,
+      0,
+      -0.00908322970767581,
+      0,
+      -0.00793162411788592,
+      0,
+      -0.00689733814551449,
+      0,
+      -0.00597123289056438,
+      0,
+      -0.00514537103613413,
+      0,
+      -0.00441277001061758,
+      0,
+      -0.00376720843252962,
+      0,
+      -0.00320307336657778,
+      0,
+      -0.00271523918124115,
+      0,
+      -0.00229897112682306,
+      0,
+      -0.00194984843584138,
+      0,
+      -0.00166370297755838,
+      0,
+      -0.00143657040680006,
+      0,
+      -0.00126465142463967,
+      0,
+      -0.00114428127836931,
+      0,
+      -0.00107190601522455,
+      0
+   };
 
 
-// // rFIR
-// // localSamplingrate = 11025.000000
-// // number of taps = 251
-// // Band0 Lower=0.000000, Upper=500.000000, Desired=1.000000, Weight=1.000000
-// // Band1 Lower=630.000000, Upper=5512.000000, Desired=0.000000, Weight=10.000000
-// //Coefficients:
-//  const  DSPFLOAT  wideRX[RXNUMTAPS]=
-// {
-//    0.000300231,
-//    -8.20897e-06,
-//    -4.11537e-05,
-//    -9.46388e-05,
-//    -0.000165678,
-//    -0.000249422,
-//    -0.000339104,
-//    -0.000426459,
-//    -0.00050217,
-//    -0.000556782,
-//    -0.000581556,
-//    -0.000569598,
-//    -0.000516739,
-//    -0.000422463,
-//    -0.000290329,
-//    -0.000128235,
-//    5.20287e-05,
-//    0.000235434,
-//    0.0004051,
-//    0.000543697,
-//    0.000635391,
-//    0.000667432,
-//    0.000631989,
-//    0.000527203,
-//    0.00035825,
-//    0.000137199,
-//    -0.000117217,
-//    -0.000381393,
-//    -0.000628444,
-//    -0.000831458,
-//    -0.000965562,
-//    -0.00101162,
-//    -0.000955948,
-//    -0.000797507,
-//    -0.00054387,
-//    -0.000213404,
-//    0.000165331,
-//    0.000557083,
-//    0.000921971,
-//    0.00122013,
-//    0.00141525,
-//    0.00147924,
-//    0.00139533,
-//    0.00116112,
-//    0.000789527,
-//    0.000308943,
-//    -0.000238925,
-//    -0.000802116,
-//    -0.00132339,
-//    -0.00174556,
-//    -0.00201774,
-//    -0.00210088,
-//    -0.00197294,
-//    -0.0016322,
-//    -0.00109903,
-//    -0.000415164,
-//    0.000359026,
-//    0.00114961,
-//    0.00187576,
-//    0.00245778,
-//    0.00282554,
-//    0.00292636,
-//    0.00273164,
-//    0.00224121,
-//    0.00148608,
-//    0.000526493,
-//    -0.000552233,
-//    -0.00164623,
-//    -0.00264352,
-//    -0.00343428,
-//    -0.00392291,
-//    -0.00403842,
-//    -0.00374381,
-//    -0.00304178,
-//    -0.00197746,
-//    -0.000636259,
-//    0.000861911,
-//    0.00237298,
-//    0.00374158,
-//    0.00481658,
-//    0.00546654,
-//    0.00559482,
-//    0.00515159,
-//    0.00414242,
-//    0.00263122,
-//    0.000738094,
-//    -0.00136926,
-//    -0.00348897,
-//    -0.00540332,
-//    -0.00689939,
-//    -0.00779119,
-//    -0.00794022,
-//    -0.00727319,
-//    -0.00579387,
-//    -0.00358894,
-//    -0.000825621,
-//    0.00225865,
-//    0.00537444,
-//    0.00820404,
-//    0.0104312,
-//    0.0117713,
-//    0.0120024,
-//    0.0109917,
-//    0.00871646,
-//    0.00527566,
-//    0.000892733,
-//    -0.00409393,
-//    -0.00925022,
-//    -0.014076,
-//    -0.0180419,
-//    -0.0206315,
-//    -0.0213845,
-//    -0.0199384,
-//    -0.0160644,
-//    -0.009694,
-//    -0.000934707,
-//    0.00992761,
-//    0.0224406,
-//    0.0360101,
-//    0.0499371,
-//    0.0634635,
-//    0.0758241,
-//     0.0863,
-//    0.0942695,
-//    0.0992533,
-//    0.100949,
-//    0.0992533,
-//    0.0942695,
-//     0.0863,
-//    0.0758241,
-//    0.0634635,
-//    0.0499371,
-//    0.0360101,
-//    0.0224406,
-//    0.00992761,
-//    -0.000934707,
-//    -0.009694,
-//    -0.0160644,
-//    -0.0199384,
-//    -0.0213845,
-//    -0.0206315,
-//    -0.0180419,
-//    -0.014076,
-//    -0.00925022,
-//    -0.00409393,
-//    0.000892733,
-//    0.00527566,
-//    0.00871646,
-//    0.0109917,
-//    0.0120024,
-//    0.0117713,
-//    0.0104312,
-//    0.00820404,
-//    0.00537444,
-//    0.00225865,
-//    -0.000825621,
-//    -0.00358894,
-//    -0.00579387,
-//    -0.00727319,
-//    -0.00794022,
-//    -0.00779119,
-//    -0.00689939,
-//    -0.00540332,
-//    -0.00348897,
-//    -0.00136926,
-//    0.000738094,
-//    0.00263122,
-//    0.00414242,
-//    0.00515159,
-//    0.00559482,
-//    0.00546654,
-//    0.00481658,
-//    0.00374158,
-//    0.00237298,
-//    0.000861911,
-//    -0.000636259,
-//    -0.00197746,
-//    -0.00304178,
-//    -0.00374381,
-//    -0.00403842,
-//    -0.00392291,
-//    -0.00343428,
-//    -0.00264352,
-//    -0.00164623,
-//    -0.000552233,
-//    0.000526493,
-//    0.00148608,
-//    0.00224121,
-//    0.00273164,
-//    0.00292636,
-//    0.00282554,
-//    0.00245778,
-//    0.00187576,
-//    0.00114961,
-//    0.000359026,
-//    -0.000415164,
-//    -0.00109903,
-//    -0.0016322,
-//    -0.00197294,
-//    -0.00210088,
-//    -0.00201774,
-//    -0.00174556,
-//    -0.00132339,
-//    -0.000802116,
-//    -0.000238925,
-//    0.000308943,
-//    0.000789527,
-//    0.00116112,
-//    0.00139533,
-//    0.00147924,
-//    0.00141525,
-//    0.00122013,
-//    0.000921971,
-//    0.000557083,
-//    0.000165331,
-//    -0.000213404,
-//    -0.00054387,
-//    -0.000797507,
-//    -0.000955948,
-//    -0.00101162,
-//    -0.000965562,
-//    -0.000831458,
-//    -0.000628444,
-//    -0.000381393,
-//    -0.000117217,
-//    0.000137199,
-//    0.00035825,
-//    0.000527203,
-//    0.000631989,
-//    0.000667432,
-//    0.000635391,
-//    0.000543697,
-//    0.0004051,
-//    0.000235434,
-//    5.20287e-05,
-//    -0.000128235,
-//    -0.000290329,
-//    -0.000422463,
-//    -0.000516739,
-//    -0.000569598,
-//    -0.000581556,
-//    -0.000556782,
-//    -0.00050217,
-//    -0.000426459,
-//    -0.000339104,
-//    -0.000249422,
-//    -0.000165678,
-//    -9.46388e-05,
-//    -4.11537e-05,
-//    -8.20897e-06,
-//    0.000300231
-// };
-
-//// rFIR
-//// localSamplingrate = 11025.000000
-//// number of taps = 251
-//// Band0 Lower=0.000000, Upper=999.999000, Desired=0.000000, Weight=10.000000
-//// Band1 Lower=1110.000000, Upper=1290.000000, Desired=1.000000, Weight=1.000000
-//// Band2 Lower=1400.000000, Upper=5512.000000, Desired=0.000000, Weight=10.000000
-////Coefficients:
-// const  DSPFLOAT sharp1200BP[RXNUMTAPS]=
-//{
-//	 -0.000181001,
-//	 0.000251417,
-//	 -0.000407553,
-//	 -0.000113892,
-//	 0.000360061,
-//	 0.000633657,
-//	 0.000641274,
-//	 0.000395862,
-//	 -5.12681e-05,
-//	 -0.000553689,
-//	 -0.000879439,
-//	 -0.000820056,
-//	 -0.00032433,
-//	 0.000435928,
-//	 0.00111676,
-//	 0.00135737,
-//	 0.000967803,
-//	 5.29504e-05,
-//	 -0.00100229,
-//	 -0.00169484,
-//	 -0.00164687,
-//	 -0.000809972,
-//	 0.000478952,
-//	 0.0016339,
-//	 0.00209334,
-//	 0.00160099,
-//	 0.000349433,
-//	 -0.00109484,
-//	 -0.00205749,
-//	 -0.00208466,
-//	 -0.00116866,
-//	 0.000247443,
-//	 0.00149138,
-//	 0.00199728,
-//	 0.00158125,
-//	 0.000514645,
-//	 -0.000639633,
-//	 -0.00133383,
-//	 -0.00131654,
-//	 -0.000735591,
-//	 -1.20504e-05,
-//	 0.000432654,
-//	 0.000430428,
-//	 0.000148421,
-//	 -5.08362e-05,
-//	 0.000116712,
-//	 0.000625307,
-//	 0.00110932,
-//	 0.00107711,
-//	 0.000255083,
-//	 -0.00114975,
-//	 -0.0024561,
-//	 -0.00282831,
-//	 -0.00176363,
-//	 0.00052394,
-//	 0.00307314,
-//	 0.00457652,
-//	 0.00404712,
-//	 0.00141358,
-//	 -0.00230461,
-//	 -0.00538379,
-//	 -0.00621703,
-//	 -0.00415245,
-//	 6.94677e-05,
-//	 0.00457672,
-//	 0.00721896,
-//	 0.00662798,
-//	 0.00294486,
-//	 -0.00218784,
-//	 -0.00638383,
-//	 -0.0076732,
-//	 -0.00547554,
-//	 -0.00088151,
-//	 0.00389921,
-//	 0.00665079,
-//	 0.00624499,
-//	 0.00314513,
-//	 -0.00092486,
-//	 -0.00394617,
-//	 -0.00467243,
-//	 -0.00320729,
-//	 -0.000793654,
-//	 0.00102892,
-//	 0.00138505,
-//	 0.00056018,
-//	 -0.000275589,
-//	 5.06196e-05,
-//	 0.00178544,
-//	 0.00389119,
-//	 0.00456457,
-//	 0.00240679,
-//	 -0.00243394,
-//	 -0.00790812,
-//	 -0.0108727,
-//	 -0.00877531,
-//	 -0.00135218,
-//	 0.00867904,
-//	 0.0165229,
-//	 0.0175639,
-//	 0.00992846,
-//	 -0.00402369,
-//	 -0.0182552,
-//	 -0.0256507,
-//	 -0.0215475,
-//	 -0.00645296,
-//	 0.013569,
-//	 0.0293071,
-//	 0.0326681,
-//	 0.0208103,
-//	 -0.00195836,
-//	 -0.0256691,
-//	 -0.0391028,
-//	 -0.0351489,
-//	 -0.01453,
-//	 0.0140466,
-//	 0.0376031,
-//	 0.044869,
-//	 0.0317345,
-//	 0.00350871,
-//	 -0.027234,
-//	 -0.0463481,
-//	 -0.0447258,
-//	 -0.0226958,
-//	 0.00994727,
-//	 0.0383706,
-//	 0.0495577,
-//	 0.0383706,
-//	 0.00994727,
-//	 -0.0226958,
-//	 -0.0447258,
-//	 -0.0463481,
-//	 -0.027234,
-//	 0.00350871,
-//	 0.0317345,
-//	 0.044869,
-//	 0.0376031,
-//	 0.0140466,
-//	 -0.01453,
-//	 -0.0351489,
-//	 -0.0391028,
-//	 -0.0256691,
-//	 -0.00195836,
-//	 0.0208103,
-//	 0.0326681,
-//	 0.0293071,
-//	 0.013569,
-//	 -0.00645296,
-//	 -0.0215475,
-//	 -0.0256507,
-//	 -0.0182552,
-//	 -0.00402369,
-//	 0.00992846,
-//	 0.0175639,
-//	 0.0165229,
-//	 0.00867904,
-//	 -0.00135218,
-//	 -0.00877531,
-//	 -0.0108727,
-//	 -0.00790812,
-//	 -0.00243394,
-//	 0.00240679,
-//	 0.00456457,
-//	 0.00389119,
-//	 0.00178544,
-//	 5.06196e-05,
-//	 -0.000275589,
-//	 0.00056018,
-//	 0.00138505,
-//	 0.00102892,
-//	 -0.000793654,
-//	 -0.00320729,
-//	 -0.00467243,
-//	 -0.00394617,
-//	 -0.00092486,
-//	 0.00314513,
-//	 0.00624499,
-//	 0.00665079,
-//	 0.00389921,
-//	 -0.00088151,
-//	 -0.00547554,
-//	 -0.0076732,
-//	 -0.00638383,
-//	 -0.00218784,
-//	 0.00294486,
-//	 0.00662798,
-//	 0.00721896,
-//	 0.00457672,
-//	 6.94677e-05,
-//	 -0.00415245,
-//	 -0.00621703,
-//	 -0.00538379,
-//	 -0.00230461,
-//	 0.00141358,
-//	 0.00404712,
-//	 0.00457652,
-//	 0.00307314,
-//	 0.00052394,
-//	 -0.00176363,
-//	 -0.00282831,
-//	 -0.0024561,
-//	 -0.00114975,
-//	 0.000255083,
-//	 0.00107711,
-//	 0.00110932,
-//	 0.000625307,
-//	 0.000116712,
-//	 -5.08362e-05,
-//	 0.000148421,
-//	 0.000430428,
-//	 0.000432654,
-//	 -1.20504e-05,
-//	 -0.000735591,
-//	 -0.00131654,
-//	 -0.00133383,
-//	 -0.000639633,
-//	 0.000514645,
-//	 0.00158125,
-//	 0.00199728,
-//	 0.00149138,
-//	 0.000247443,
-//	 -0.00116866,
-//	 -0.00208466,
-//	 -0.00205749,
-//	 -0.00109484,
-//	 0.000349433,
-//	 0.00160099,
-//	 0.00209334,
-//	 0.0016339,
-//	 0.000478952,
-//	 -0.000809972,
-//	 -0.00164687,
-//	 -0.00169484,
-//	 -0.00100229,
-//	 5.29504e-05,
-//	 0.000967803,
-//	 0.00135737,
-//	 0.00111676,
-//	 0.000435928,
-//	 -0.00032433,
-//	 -0.000820056,
-//	 -0.000879439,
-//	 -0.000553689,
-//	 -5.12681e-05,
-//	 0.000395862,
-//	 0.000641274,
-//	 0.000633657,
-//	 0.000360061,
-//	 -0.000113892,
-//	 -0.000407553,
-//	 0.000251417,
-//	 -0.000181001
-//};
-
-
-
-//// rFIR
-//// localSamplingrate = 11025.000000
-//// number of taps = 251
-//// Band0 Lower=0.000000, Upper=550.000000, Desired=1.000000, Weight=1.000000
-//// Band1 Lower=850.000000, Upper=5512.000000, Desired=0.000000, Weight=10.000000
-//// demodulator frequency = 1750.000000
-////Coefficients:
-// const  DSPFLOAT wideVolume[RXNUMTAPS]=
-//{
-//	 -8.12983e-07,
-//	 -6.20807e-07,
-//	 -5.71262e-07,
-//	 -2.08463e-07,
-//	 5.61841e-07,
-//	 1.76677e-06,
-//	 3.32807e-06,
-//	 5.03565e-06,
-//	 6.54698e-06,
-//	 7.4188e-06,
-//	 7.17643e-06,
-//	 5.41296e-06,
-//	 1.90859e-06,
-//	 -3.25452e-06,
-//	 -9.60746e-06,
-//	 -1.62721e-05,
-//	 -2.20201e-05,
-//	 -2.54248e-05,
-//	 -2.50993e-05,
-//	 -1.99967e-05,
-//	 -9.71913e-06,
-//	 5.22566e-06,
-//	 2.32837e-05,
-//	 4.18857e-05,
-//	 5.77019e-05,
-//	 6.70942e-05,
-//	 6.67504e-05,
-//	 5.43975e-05,
-//	 2.94745e-05,
-//	 -6.37004e-06,
-//	 -4.91004e-05,
-//	 -9.25291e-05,
-//	 -0.000129015,
-//	 -0.000150574,
-//	 -0.000150291,
-//	 -0.000123799,
-//	 -7.05844e-05,
-//	 5.16902e-06,
-//	 9.44505e-05,
-//	 0.000184149,
-//	 0.000258662,
-//	 0.000302252,
-//	 0.000301838,
-//	 0.000249793,
-//	 0.000146241,
-//	 3.42773e-07,
-//	 -0.000169823,
-//	 -0.000338982,
-//	 -0.000477957,
-//	 -0.000558161,
-//	 -0.000556692,
-//	 -0.00046121,
-//	 -0.000273687,
-//	 -1.22083e-05,
-//	 0.000289784,
-//	 0.000587038,
-//	 0.000828607,
-//	 0.000965818,
-//	 0.000960953,
-//	 0.000795233,
-//	 0.000474608,
-//	 3.2073e-05,
-//	 -0.000474377,
-//	 -0.000968335,
-//	 -0.00136559,
-//	 -0.00158739,
-//	 -0.00157453,
-//	 -0.00129973,
-//	 -0.000776269,
-//	 -6.06608e-05,
-//	 0.000751585,
-//	 0.00153735,
-//	 0.00216326,
-//	 0.00250687,
-//	 0.00247833,
-//	 0.00203924,
-//	 0.00121491,
-//	 9.73382e-05,
-//	 -0.0011625,
-//	 -0.00237319,
-//	 -0.00333006,
-//	 -0.00384765,
-//	 -0.00379243,
-//	 -0.0031105,
-//	 -0.00184508,
-//	 -0.000139903,
-//	 0.00177363,
-//	 0.00360499,
-//	 0.00504579,
-//	 0.00581827,
-//	 0.00572385,
-//	 0.0046839,
-//	 0.00276522,
-//	 0.000184684,
-//	 -0.00270984,
-//	 -0.00548173,
-//	 -0.00766633,
-//	 -0.00884263,
-//	 -0.00870541,
-//	 -0.00712658,
-//	 -0.00419509,
-//	 -0.000226991,
-//	 0.00425896,
-//	 0.00859967,
-//	 0.0120746,
-//	 0.0140108,
-//	 0.0138925,
-//	 0.0114587,
-//	 0.00677437,
-//	 0.000261833,
-//	 -0.00731507,
-//	 -0.0149163,
-//	 -0.0213353,
-//	 -0.0253404,
-//	 -0.0258336,
-//	 -0.0220032,
-//	 -0.0134525,
-//	 -0.000284783,
-//	 0.0168686,
-//	 0.0368837,
-//	 0.058241,
-//	 0.079175,
-//	 0.0978591,
-//	 0.112604,
-//	 0.122044,
-//	 0.125293,
-//	 0.122044,
-//	 0.112604,
-//	 0.0978591,
-//	 0.079175,
-//	 0.058241,
-//	 0.0368837,
-//	 0.0168686,
-//	 -0.000284783,
-//	 -0.0134525,
-//	 -0.0220032,
-//	 -0.0258336,
-//	 -0.0253404,
-//	 -0.0213353,
-//	 -0.0149163,
-//	 -0.00731507,
-//	 0.000261833,
-//	 0.00677437,
-//	 0.0114587,
-//	 0.0138925,
-//	 0.0140108,
-//	 0.0120746,
-//	 0.00859967,
-//	 0.00425896,
-//	 -0.000226991,
-//	 -0.00419509,
-//	 -0.00712658,
-//	 -0.00870541,
-//	 -0.00884263,
-//	 -0.00766633,
-//	 -0.00548173,
-//	 -0.00270984,
-//	 0.000184684,
-//	 0.00276522,
-//	 0.0046839,
-//	 0.00572385,
-//	 0.00581827,
-//	 0.00504579,
-//	 0.00360499,
-//	 0.00177363,
-//	 -0.000139903,
-//	 -0.00184508,
-//	 -0.0031105,
-//	 -0.00379243,
-//	 -0.00384765,
-//	 -0.00333006,
-//	 -0.00237319,
-//	 -0.0011625,
-//	 9.73382e-05,
-//	 0.00121491,
-//	 0.00203924,
-//	 0.00247833,
-//	 0.00250687,
-//	 0.00216326,
-//	 0.00153735,
-//	 0.000751585,
-//	 -6.06608e-05,
-//	 -0.000776269,
-//	 -0.00129973,
-//	 -0.00157453,
-//	 -0.00158739,
-//	 -0.00136559,
-//	 -0.000968335,
-//	 -0.000474377,
-//	 3.2073e-05,
-//	 0.000474608,
-//	 0.000795233,
-//	 0.000960953,
-//	 0.000965818,
-//	 0.000828607,
-//	 0.000587038,
-//	 0.000289784,
-//	 -1.22083e-05,
-//	 -0.000273687,
-//	 -0.00046121,
-//	 -0.000556692,
-//	 -0.000558161,
-//	 -0.000477957,
-//	 -0.000338982,
-//	 -0.000169823,
-//	 3.42773e-07,
-//	 0.000146241,
-//	 0.000249793,
-//	 0.000301838,
-//	 0.000302252,
-//	 0.000258662,
-//	 0.000184149,
-//	 9.44505e-05,
-//	 5.16902e-06,
-//	 -7.05844e-05,
-//	 -0.000123799,
-//	 -0.000150291,
-//	 -0.000150574,
-//	 -0.000129015,
-//	 -9.25291e-05,
-//	 -4.91004e-05,
-//	 -6.37004e-06,
-//	 2.94745e-05,
-//	 5.43975e-05,
-//	 6.67504e-05,
-//	 6.70942e-05,
-//	 5.77019e-05,
-//	 4.18857e-05,
-//	 2.32837e-05,
-//	 5.22566e-06,
-//	 -9.71913e-06,
-//	 -1.99967e-05,
-//	 -2.50993e-05,
-//	 -2.54248e-05,
-//	 -2.20201e-05,
-//	 -1.62721e-05,
-//	 -9.60746e-06,
-//	 -3.25452e-06,
-//	 1.90859e-06,
-//	 5.41296e-06,
-//	 7.17643e-06,
-//	 7.4188e-06,
-//	 6.54698e-06,
-//	 5.03565e-06,
-//	 3.32807e-06,
-//	 1.76677e-06,
-//	 5.61841e-07,
-//	 -2.08463e-07,
-//	 -5.71262e-07,
-//	 -6.20807e-07,
-//	 -8.12983e-07
-//};
-// const DSPFLOAT veryWideVolume[RXNUMTAPS]=
-//{
-//	 1.64357e-05,
-//	 -4.23193e-05,
-//	 -4.14901e-05,
-//	 -4.74921e-05,
-//	 -4.96931e-05,
-//	 -4.33244e-05,
-//	 -2.66581e-05,
-//	 -7.16336e-07,
-//	 3.07848e-05,
-//	 6.18288e-05,
-//	 8.51506e-05,
-//	 9.37278e-05,
-//	 8.25922e-05,
-//	 5.04016e-05,
-//	 5.18827e-07,
-//	 -5.8932e-05,
-//	 -0.000116071,
-//	 -0.000157418,
-//	 -0.000170751,
-//	 -0.0001482,
-//	 -8.87869e-05,
-//	 1.59863e-07,
-//	 0.000103401,
-//	 0.000199998,
-//	 0.00026727,
-//	 0.000285688,
-//	 0.000243843,
-//	 0.0001422,
-//	 -5.26495e-06,
-//	 -0.000172346,
-//	 -0.000324768,
-//	 -0.000426854,
-//	 -0.000449283,
-//	 -0.000376571,
-//	 -0.000212291,
-//	 1.92053e-05,
-//	 0.000275638,
-//	 0.000503917,
-//	 0.000650668,
-//	 0.000673945,
-//	 0.000553971,
-//	 0.000299992,
-//	 -4.82102e-05,
-//	 -0.000425738,
-//	 -0.000753809,
-//	 -0.000955647,
-//	 -0.000973745,
-//	 -0.000783958,
-//	 -0.000405082,
-//	 0.000101089,
-//	 0.000638559,
-//	 0.00109458,
-//	 0.00136236,
-//	 0.00136503,
-//	 0.00107529,
-//	 0.000526322,
-//	 -0.000189418,
-//	 -0.000934401,
-//	 -0.00155146,
-//	 -0.00189586,
-//	 -0.00186775,
-//	 -0.00143799,
-//	 -0.00066103,
-//	 0.000329022,
-//	 0.00133993,
-//	 0.0021574,
-//	 0.00258906,
-//	 0.00250785,
-//	 0.00188506,
-//	 0.000805333,
-//	 -0.000541519,
-//	 -0.00189182,
-//	 -0.00295802,
-//	 -0.00348805,
-//	 -0.00332229,
-//	 -0.00243558,
-//	 -0.000954212,
-//	 0.000857982,
-//	 0.00264405,
-//	 0.00402195,
-//	 0.00466364,
-//	 0.00436938,
-//	 0.00312112,
-//	 0.00110175,
-//	 -0.00132647,
-//	 -0.00368338,
-//	 -0.00546249,
-//	 -0.00623577,
-//	 -0.00575096,
-//	 -0.00399989,
-//	 -0.00124154,
-//	 0.0020292,
-//	 0.00516496,
-//	 0.00748838,
-//	 0.00843175,
-//	 0.00766589,
-//	 0.005191,
-//	 0.00136708,
-//	 -0.0031274,
-//	 -0.0074065,
-//	 -0.010541,
-//	 -0.0117467,
-//	 -0.0105615,
-//	 -0.00697387,
-//	 -0.00147219,
-//	 0.00500105,
-//	 0.0111914,
-//	 0.0157512,
-//	 0.0175002,
-//	 0.0156816,
-//	 0.0101648,
-//	 0.0015515,
-//	 -0.0088417,
-//	 -0.0191334,
-//	 -0.0271425,
-//	 -0.0307308,
-//	 -0.0281698,
-//	 -0.0184676,
-//	 -0.00160082,
-//	 0.0213961,
-//	 0.0485054,
-//	 0.0769597,
-//	 0.103604,
-//	 0.125334,
-//	 0.139537,
-//	 0.144475,
-//	 0.139537,
-//	 0.125334,
-//	 0.103604,
-//	 0.0769597,
-//	 0.0485054,
-//	 0.0213961,
-//	 -0.00160082,
-//	 -0.0184676,
-//	 -0.0281698,
-//	 -0.0307308,
-//	 -0.0271425,
-//	 -0.0191334,
-//	 -0.0088417,
-//	 0.0015515,
-//	 0.0101648,
-//	 0.0156816,
-//	 0.0175002,
-//	 0.0157512,
-//	 0.0111914,
-//	 0.00500105,
-//	 -0.00147219,
-//	 -0.00697387,
-//	 -0.0105615,
-//	 -0.0117467,
-//	 -0.010541,
-//	 -0.0074065,
-//	 -0.0031274,
-//	 0.00136708,
-//	 0.005191,
-//	 0.00766589,
-//	 0.00843175,
-//	 0.00748838,
-//	 0.00516496,
-//	 0.0020292,
-//	 -0.00124154,
-//	 -0.00399989,
-//	 -0.00575096,
-//	 -0.00623577,
-//	 -0.00546249,
-//	 -0.00368338,
-//	 -0.00132647,
-//	 0.00110175,
-//	 0.00312112,
-//	 0.00436938,
-//	 0.00466364,
-//	 0.00402195,
-//	 0.00264405,
-//	 0.000857982,
-//	 -0.000954212,
-//	 -0.00243558,
-//	 -0.00332229,
-//	 -0.00348805,
-//	 -0.00295802,
-//	 -0.00189182,
-//	 -0.000541519,
-//	 0.000805333,
-//	 0.00188506,
-//	 0.00250785,
-//	 0.00258906,
-//	 0.0021574,
-//	 0.00133993,
-//	 0.000329022,
-//	 -0.00066103,
-//	 -0.00143799,
-//	 -0.00186775,
-//	 -0.00189586,
-//	 -0.00155146,
-//	 -0.000934401,
-//	 -0.000189418,
-//	 0.000526322,
-//	 0.00107529,
-//	 0.00136503,
-//	 0.00136236,
-//	 0.00109458,
-//	 0.000638559,
-//	 0.000101089,
-//	 -0.000405082,
-//	 -0.000783958,
-//	 -0.000973745,
-//	 -0.000955647,
-//	 -0.000753809,
-//	 -0.000425738,
-//	 -4.82102e-05,
-//	 0.000299992,
-//	 0.000553971,
-//	 0.000673945,
-//	 0.000650668,
-//	 0.000503917,
-//	 0.000275638,
-//	 1.92053e-05,
-//	 -0.000212291,
-//	 -0.000376571,
-//	 -0.000449283,
-//	 -0.000426854,
-//	 -0.000324768,
-//	 -0.000172346,
-//	 -5.26495e-06,
-//	 0.0001422,
-//	 0.000243843,
-//	 0.000285688,
-//	 0.00026727,
-//	 0.000199998,
-//	 0.000103401,
-//	 1.59863e-07,
-//	 -8.87869e-05,
-//	 -0.0001482,
-//	 -0.000170751,
-//	 -0.000157418,
-//	 -0.000116071,
-//	 -5.8932e-05,
-//	 5.18827e-07,
-//	 5.04016e-05,
-//	 8.25922e-05,
-//	 9.37278e-05,
-//	 8.51506e-05,
-//	 6.18288e-05,
-//	 3.07848e-05,
-//	 -7.16336e-07,
-//	 -2.66581e-05,
-//	 -4.33244e-05,
-//	 -4.96931e-05,
-//	 -4.74921e-05,
-//	 -4.14901e-05,
-//	 -4.23193e-05,
-//	 1.64357e-05
-//};
-
-// // blFIR  Raised cosine
-// // localSamplingrate = 11025.000000
-// // number of taps = 251
-// // corner frequency = 400.000000
-// // beta = 0.600000
-// // window applied
-// // demodulator frequency = 1900.000000
-// //Coefficients:
-//  const DSPFLOAT narrowRXBLFIR[RXNUMTAPS]=
-// {
-//    -9.43009e-07,
-//    5.86068e-08,
-//    2.59295e-06,
-//    6.51998e-06,
-//    1.15194e-05,
-//    1.71102e-05,
-//    2.26892e-05,
-//    2.75867e-05,
-//    3.11375e-05,
-//    3.27613e-05,
-//    3.20439e-05,
-//    2.88109e-05,
-//    2.31824e-05,
-//    1.55969e-05,
-//    6.79757e-06,
-//    -2.2262e-06,
-//    -1.03411e-05,
-//    -1.64097e-05,
-//    -1.94538e-05,
-//    -1.88235e-05,
-//    -1.43458e-05,
-//    -6.42942e-06,
-//    3.89847e-06,
-//    1.50404e-05,
-//    2.49686e-05,
-//    3.14515e-05,
-//    3.23475e-05,
-//    2.59321e-05,
-//    1.12168e-05,
-//    -1.17913e-05,
-//    -4.19352e-05,
-//    -7.69e-05,
-//    -0.000113373,
-//    -0.000147376,
-//    -0.000174744,
-//    -0.000191702,
-//    -0.000195469,
-//    -0.000184804,
-//    -0.000160398,
-//    -0.000125046,
-//    -8.35194e-05,
-//    -4.21352e-05,
-//    -8.02811e-06,
-//    1.18057e-05,
-//    1.15857e-05,
-//    -1.21957e-05,
-//    -5.98941e-05,
-//    -0.000128166,
-//    -0.00020988,
-//    -0.000294572,
-//    -0.000369439,
-//    -0.00042083,
-//    -0.000436057,
-//    -0.000405344,
-//    -0.000323618,
-//    -0.00019189,
-//    -1.79507e-05,
-//    0.000183806,
-//    0.000393536,
-//    0.000588041,
-//    0.000743654,
-//    0.000839602,
-//    0.000861438,
-//    0.000804074,
-//    0.000673905,
-//    0.00048961,
-//    0.000281309,
-//    8.79499e-05,
-//    -4.69626e-05,
-//    -8.09498e-05,
-//    2.11247e-05,
-//    0.000280781,
-//    0.000700568,
-//    0.0012605,
-//    0.0019171,
-//    0.00260546,
-//    0.00324473,
-//    0.00374659,
-//    0.00402614,
-//    0.00401415,
-//    0.00366917,
-//    0.00298774,
-//    0.00201128,
-//    0.000827827,
-//    -0.000432323,
-//    -0.00160758,
-//    -0.00252251,
-//    -0.00301058,
-//    -0.00294038,
-//    -0.00224255,
-//    -0.000934317,
-//    0.000861952,
-//    0.00290941,
-//    0.00485956,
-//    0.00626926,
-//    0.00663259,
-//    0.00542685,
-//    0.00217056,
-//    -0.00351075,
-//    -0.011816,
-//    -0.0227036,
-//    -0.0358372,
-//    -0.0505484,
-//    -0.0658229,
-//    -0.0803145,
-//    -0.0923896,
-//    -0.100202,
-//    -0.101798,
-//    -0.0952396,
-//    -0.078749,
-//    -0.0508547,
-//    -0.0105335,
-//    0.0426651,
-//    0.108522,
-//    0.186092,
-//    0.273685,
-//    0.368909,
-//    0.46875,
-//    0.569709,
-//    0.667969,
-//    0.759603,
-//    0.840785,
-//    0.908018,
-//    0.95833,
-//    0.989462,
-//          1,
-//    0.989462,
-//    0.95833,
-//    0.908018,
-//    0.840785,
-//    0.759603,
-//    0.667969,
-//    0.569709,
-//    0.46875,
-//    0.368909,
-//    0.273685,
-//    0.186092,
-//    0.108522,
-//    0.0426651,
-//    -0.0105335,
-//    -0.0508547,
-//    -0.078749,
-//    -0.0952396,
-//    -0.101798,
-//    -0.100202,
-//    -0.0923896,
-//    -0.0803145,
-//    -0.0658229,
-//    -0.0505484,
-//    -0.0358372,
-//    -0.0227036,
-//    -0.011816,
-//    -0.00351075,
-//    0.00217056,
-//    0.00542685,
-//    0.00663259,
-//    0.00626926,
-//    0.00485956,
-//    0.00290941,
-//    0.000861952,
-//    -0.000934317,
-//    -0.00224255,
-//    -0.00294038,
-//    -0.00301058,
-//    -0.00252251,
-//    -0.00160758,
-//    -0.000432323,
-//    0.000827827,
-//    0.00201128,
-//    0.00298774,
-//    0.00366917,
-//    0.00401415,
-//    0.00402614,
-//    0.00374659,
-//    0.00324473,
-//    0.00260546,
-//    0.0019171,
-//    0.0012605,
-//    0.000700568,
-//    0.000280781,
-//    2.11247e-05,
-//    -8.09498e-05,
-//    -4.69626e-05,
-//    8.79499e-05,
-//    0.000281309,
-//    0.00048961,
-//    0.000673905,
-//    0.000804074,
-//    0.000861438,
-//    0.000839602,
-//    0.000743654,
-//    0.000588041,
-//    0.000393536,
-//    0.000183806,
-//    -1.79507e-05,
-//    -0.00019189,
-//    -0.000323618,
-//    -0.000405344,
-//    -0.000436057,
-//    -0.00042083,
-//    -0.000369439,
-//    -0.000294572,
-//    -0.00020988,
-//    -0.000128166,
-//    -5.98941e-05,
-//    -1.21957e-05,
-//    1.15857e-05,
-//    1.18057e-05,
-//    -8.02811e-06,
-//    -4.21352e-05,
-//    -8.35194e-05,
-//    -0.000125046,
-//    -0.000160398,
-//    -0.000184804,
-//    -0.000195469,
-//    -0.000191702,
-//    -0.000174744,
-//    -0.000147376,
-//    -0.000113373,
-//    -7.69e-05,
-//    -4.19352e-05,
-//    -1.17913e-05,
-//    1.12168e-05,
-//    2.59321e-05,
-//    3.23475e-05,
-//    3.14515e-05,
-//    2.49686e-05,
-//    1.50404e-05,
-//    3.89847e-06,
-//    -6.42942e-06,
-//    -1.43458e-05,
-//    -1.88235e-05,
-//    -1.94538e-05,
-//    -1.64097e-05,
-//    -1.03411e-05,
-//    -2.2262e-06,
-//    6.79757e-06,
-//    1.55969e-05,
-//    2.31824e-05,
-//    2.88109e-05,
-//    3.20439e-05,
-//    3.27613e-05,
-//    3.11375e-05,
-//    2.75867e-05,
-//    2.26892e-05,
-//    1.71102e-05,
-//    1.15194e-05,
-//    6.51998e-06,
-//    2.59295e-06,
-//    5.86068e-08,
-//    -9.43009e-07
-// };
-
-//  // blFIR  Raised cosine
-//  // localSamplingrate = 12000.000000
-//  // number of taps = 251
-//  // corner frequency = 500.000000
-//  // beta = 0.700000
-//  // window applied
-//  const DSPFLOAT wideRXBLFIR[RXNUMTAPS]=
-//  {
-//     6.78868e-06,
-//     7.62652e-06,
-//     7.3611e-06,
-//     5.89395e-06,
-//     3.33524e-06,
-//     1.60138e-10,
-//     -3.63027e-06,
-//     -6.98132e-06,
-//     -9.48175e-06,
-//     -1.06723e-05,
-//     -1.03077e-05,
-//     -8.43229e-06,
-//     -5.41094e-06,
-//     -1.90134e-06,
-//     1.23557e-06,
-//     3.08018e-06,
-//     2.83336e-06,
-//     -7.55651e-10,
-//     -5.46557e-06,
-//     -1.30733e-05,
-//     -2.18248e-05,
-//     -3.03406e-05,
-//     -3.70925e-05,
-//     -4.0704e-05,
-//     -4.02644e-05,
-//     -3.5593e-05,
-//     -2.73867e-05,
-//     -1.7202e-05,
-//     -7.24703e-06,
-//     -1.63e-09,
-//     2.28199e-06,
-//     -1.89402e-06,
-//     -1.28279e-05,
-//     -2.93639e-05,
-//     -4.89128e-05,
-//     -6.77847e-05,
-//     -8.18086e-05,
-//     -8.71484e-05,
-//     -8.11663e-05,
-//     -6.31571e-05,
-//     -3.47725e-05,
-//     -1.22628e-09,
-//     3.5357e-05,
-//     6.46837e-05,
-//     8.18541e-05,
-//     8.26343e-05,
-//     6.58754e-05,
-//     3.42194e-05,
-//     -5.90498e-06,
-//     -4.5097e-05,
-//     -7.25517e-05,
-//     -7.81545e-05,
-//     -5.47315e-05,
-//     8.4255e-10,
-//     8.22444e-05,
-//     0.000182046,
-//     0.000284521,
-//     0.00037229,
-//     0.000428806,
-//     0.000441971,
-//     0.000407341,
-//     0.000330171,
-//     0.000225707,
-//     0.000117409,
-//     3.31634e-05,
-//     2.85785e-09,
-//     3.82104e-05,
-//     0.000155948,
-//     0.000345618,
-//     0.000582967,
-//     0.000829548,
-//     0.00103851,
-//     0.00116306,
-//     0.00116619,
-//     0.00102993,
-//     0.000762039,
-//     0.00039841,
-//     2.79295e-09,
-//     -0.000356014,
-//     -0.000589978,
-//     -0.000636324,
-//     -0.000460149,
-//     -7.0336e-05,
-//     0.000473995,
-//     0.00106621,
-//     0.00156515,
-//     0.00181749,
-//     0.00168694,
-//     0.00108532,
-//     7.96117e-10,
-//     -0.00148873,
-//     -0.00320568,
-//     -0.00489779,
-//     -0.00627071,
-//     -0.00704213,
-//     -0.00700509,
-//     -0.00609177,
-//     -0.00442574,
-//     -0.00235059,
-//     -0.00042436,
-//     0.000627163,
-//     -1.18464e-09,
-//     -0.00306066,
-//     -0.00910697,
-//     -0.0183266,
-//     -0.0303951,
-//     -0.0443657,
-//     -0.0586203,
-//     -0.0708981,
-//     -0.0784119,
-//     -0.0780524,
-//     -0.0666671,
-//     -0.0413915,
-//     -1.94497e-09,
-//     0.0587624,
-//     0.134907,
-//     0.227025,
-//     0.332237,
-//     0.44628,
-//     0.563746,
-//     0.678442,
-//     0.783855,
-//     0.873667,
-//     0.942288,
-//     0.985332,
-//           1,
-//     0.985332,
-//     0.942288,
-//     0.873667,
-//     0.783855,
-//     0.678442,
-//     0.563746,
-//     0.44628,
-//     0.332237,
-//     0.227025,
-//     0.134907,
-//     0.0587624,
-//     -1.94497e-09,
-//     -0.0413915,
-//     -0.0666671,
-//     -0.0780524,
-//     -0.0784119,
-//     -0.0708981,
-//     -0.0586203,
-//     -0.0443657,
-//     -0.0303951,
-//     -0.0183266,
-//     -0.00910697,
-//     -0.00306066,
-//     -1.18464e-09,
-//     0.000627163,
-//     -0.00042436,
-//     -0.00235059,
-//     -0.00442574,
-//     -0.00609177,
-//     -0.00700509,
-//     -0.00704213,
-//     -0.00627071,
-//     -0.00489779,
-//     -0.00320568,
-//     -0.00148873,
-//     7.96117e-10,
-//     0.00108532,
-//     0.00168694,
-//     0.00181749,
-//     0.00156515,
-//     0.00106621,
-//     0.000473995,
-//     -7.0336e-05,
-//     -0.000460149,
-//     -0.000636324,
-//     -0.000589978,
-//     -0.000356014,
-//     2.79295e-09,
-//     0.00039841,
-//     0.000762039,
-//     0.00102993,
-//     0.00116619,
-//     0.00116306,
-//     0.00103851,
-//     0.000829548,
-//     0.000582967,
-//     0.000345618,
-//     0.000155948,
-//     3.82104e-05,
-//     2.85785e-09,
-//     3.31634e-05,
-//     0.000117409,
-//     0.000225707,
-//     0.000330171,
-//     0.000407341,
-//     0.000441971,
-//     0.000428806,
-//     0.00037229,
-//     0.000284521,
-//     0.000182046,
-//     8.22444e-05,
-//     8.4255e-10,
-//     -5.47315e-05,
-//     -7.81545e-05,
-//     -7.25517e-05,
-//     -4.5097e-05,
-//     -5.90498e-06,
-//     3.42194e-05,
-//     6.58754e-05,
-//     8.26343e-05,
-//     8.18541e-05,
-//     6.46837e-05,
-//     3.5357e-05,
-//     -1.22628e-09,
-//     -3.47725e-05,
-//     -6.31571e-05,
-//     -8.11663e-05,
-//     -8.71484e-05,
-//     -8.18086e-05,
-//     -6.77847e-05,
-//     -4.89128e-05,
-//     -2.93639e-05,
-//     -1.28279e-05,
-//     -1.89402e-06,
-//     2.28199e-06,
-//     -1.63e-09,
-//     -7.24703e-06,
-//     -1.7202e-05,
-//     -2.73867e-05,
-//     -3.5593e-05,
-//     -4.02644e-05,
-//     -4.0704e-05,
-//     -3.70925e-05,
-//     -3.03406e-05,
-//     -2.18248e-05,
-//     -1.30733e-05,
-//     -5.46557e-06,
-//     -7.55651e-10,
-//     2.83336e-06,
-//     3.08018e-06,
-//     1.23557e-06,
-//     -1.90134e-06,
-//     -5.41094e-06,
-//     -8.43229e-06,
-//     -1.03077e-05,
-//     -1.06723e-05,
-//     -9.48175e-06,
-//     -6.98132e-06,
-//     -3.63027e-06,
-//     1.60138e-10,
-//     3.33524e-06,
-//     5.89395e-06,
-//     7.3611e-06,
-//     7.62652e-06,
-//     6.78868e-06
-//  };
-
-
-
-//const DSPFLOAT f800TX[TXNUMTAPS]=
-//{
-
-//};
 
 DSPFLOAT calculateGain(const DSPFLOAT *fp,unsigned int len)
 {
@@ -3906,12 +738,12 @@ DSPFLOAT calculateGain(const DSPFLOAT *fp,unsigned int len)
 	return fs;
 }
 
-sfilters filterStruct[NUMRXFILTERS]=
-{
-//	{"800 Hz",narrowRX,1900},
-//	{"1000 Hz",wideRX,1900},
-   {"600Hz Video",wide600Hz,1700},
+//sfilters filterStruct[NUMRXFILTERS]=
+//{
+////	{"800 Hz",narrowRX,1900},
+////	{"1000 Hz",wideRX,1900},
 //   {"600Hz Video",wide600Hz,1700},
+////   {"600Hz Video",wide600Hz,1700},
 
-};
+//};
 
diff --git a/qsstv/dsp/filterparam.h b/qsstv/dsp/filterparam.h
index e7c95fd..0ad80cb 100644
--- a/qsstv/dsp/filterparam.h
+++ b/qsstv/dsp/filterparam.h
@@ -20,38 +20,47 @@
  ***************************************************************************/
 #ifndef FILTERPARAM_H
 #define FILTERPARAM_H
-#include "qsstvdefs.h"
+#include "appdefs.h"
 #include <QString>
 
-#define FILTERPARAMTYPE DSPFLOAT
-//#define FILTERPARAMTYPE FILTERPARAMTYPE
- 
-#define RXNUMTAPS 251
+#define FILTERPARAMTYPE double
+
+
 #define TXWFNUMTAPS 121
 #define NUMTAPSPOST 0
 #define NUMRXFILTERS 1
-//#define DWSBANDPASS
 
-#ifdef DWSBANDPASS
-#define DSAMPLEFILTERLEN 360
-#else
-#define DSAMPLEFILTERLEN 180
-#endif
- 
+#define SYNCBPNUMZEROES 8
+#define SYNCBPNUMPOLES  8
+#define SYNCBPGAIN 103035.237413
+extern const double z_sync_bp[SYNCBPNUMZEROES+1];
+extern const double p_sync_bp[SYNCBPNUMPOLES];
+#define VIDEOBPNUMZEROES 8
+#define VIDEOBPNUMPOLES 8
+#define VIDEOBPGAIN 2284.945151
+extern const double z_video_bp[VIDEOBPNUMZEROES+1];
+extern const double p_video_bp[VIDEOBPNUMPOLES];
+
+
+#define VIDEOFIRNUMTAPS 181
+#define VIDEOFIRGAIN 10.000014
+#define VIDEOFIRCENTER 1900
+extern const double videoFilterCoefFIR[VIDEOFIRNUMTAPS];
+
+
+#define HILBERTTAPS 121
+#define HILBERTGAIN 1.569474
+extern const double hilbertCoef[HILBERTTAPS];
+
+
+#define DRMHILBERTTAPS 153
+#define DRMHILBERTGAIN 1.569749
+extern const FILTERPARAMTYPE drmHilbertCoef[DRMHILBERTTAPS];
+
 enum efilterType {FNARROW,FWIDE};
 enum epostFilterType {NONE};
-//extern const DSPFLOAT sharp1200BP[RXNUMTAPS];
-extern const FILTERPARAMTYPE wide1200BP[RXNUMTAPS];
-extern const FILTERPARAMTYPE wide600Hz[RXNUMTAPS];
-//extern const DSPFLOAT wideVolume[RXNUMTAPS];
-//extern const DSPFLOAT veryWideVolume[RXNUMTAPS];
-//extern const DSPFLOAT narrowRX[RXNUMTAPS];
-//extern const DSPFLOAT wideRX[RXNUMTAPS];
-//extern const DSPFLOAT wideRXBLFIR[RXNUMTAPS];
-//extern const DSPFLOAT narrowRXBLFIR[RXNUMTAPS];
-extern const FILTERPARAMTYPE downSampleFilterParam[DSAMPLEFILTERLEN];
-extern const  FILTERPARAMTYPE wfFilter[TXWFNUMTAPS];
-//extern const  DSPFLOAT  wideVolumeFilter[RXNUMTAPS];
+extern const  FILTERPARAMTYPE wfFilterCoef[TXWFNUMTAPS];
+
 DSPFLOAT calculateGain(const DSPFLOAT *fp,unsigned int len);
 
 struct sfilters
@@ -59,10 +68,9 @@ struct sfilters
   const QString filterName;
   const FILTERPARAMTYPE *filterPtr;
   DSPFLOAT centerFrequency;
-
 };
 
-extern sfilters filterStruct[NUMRXFILTERS];
+//extern sfilters filterStruct[NUMRXFILTERS];
 
 
  
diff --git a/qsstv/dsp/filters.cpp b/qsstv/dsp/filters.cpp
new file mode 100644
index 0000000..77a1a63
--- /dev/null
+++ b/qsstv/dsp/filters.cpp
@@ -0,0 +1,179 @@
+#include "filters.h"
+#include "filter.h"
+
+#include <QDebug>
+
+
+
+syncFilter:: syncFilter(uint maxLength):
+  sync1200(filter::FTFIR,maxLength),sync1900(filter::FTFIR,maxLength),
+  vol1200(filter::FTFIR,maxLength),vol1900(filter::FTFIR,maxLength)
+{
+  init();
+}
+
+syncFilter::~syncFilter()
+{
+
+}
+
+void syncFilter:: init()
+{
+  // setup the syncFilters
+  sync1200.init();
+  sync1200.setupMatchedFilter(1200,60);
+
+  sync1900.init();
+  sync1900.setupMatchedFilter(1900,60);
+
+  vol1200.init();
+  vol1200.nZeroes=HILBERTTAPS-1;
+  vol1200.coefZPtr=(FILTERPARAMTYPE *)hilbertCoef;
+  vol1200.gain=HILBERTGAIN;
+  vol1200.volumeAttackIntegrator=0.07;
+  vol1200.volumeDecayIntegrator=0.05;
+  vol1200.allocate();
+
+  vol1900.init();
+  vol1900.nZeroes=HILBERTTAPS-1;
+  vol1900.coefZPtr=(FILTERPARAMTYPE *)hilbertCoef;
+  vol1900.gain=HILBERTGAIN;
+  vol1900.volumeAttackIntegrator=0.07;
+  vol1900.volumeDecayIntegrator=0.05;
+  vol1900.allocate();
+  detect1200Ptr= vol1200.volumePtr;
+  detect1900Ptr= vol1900.volumePtr;
+}
+
+void syncFilter::process(FILTERPARAMTYPE *dataPtr)
+{
+  sync1200.processFIR(dataPtr,sync1200.filteredPtr);
+  sync1900.processFIR(dataPtr,sync1900.filteredPtr);
+  vol1200.processHILBVolume(sync1200.filteredPtr);
+  vol1900.processHILBVolume(sync1900.filteredPtr);
+}
+
+
+
+
+
+
+videoFilter::videoFilter(uint maxLength):videoFltr(filter::FTFIR,maxLength),lpFltr(filter::FTFIR,maxLength)
+{
+  init();
+}
+
+videoFilter::~videoFilter()
+{
+}
+
+void videoFilter::init()
+{
+  videoFltr.init();
+  lpFltr.init();
+  videoFltr.volumeAttackIntegrator=0.07;
+  videoFltr.volumeDecayIntegrator=0.01;
+  videoFltr.nZeroes=VIDEOFIRNUMTAPS-1;
+  videoFltr.gain=VIDEOFIRGAIN;
+  videoFltr.frCenter=VIDEOFIRCENTER;
+  videoFltr.coefZPtr=(FILTERPARAMTYPE *)videoFilterCoefFIR;
+  videoFltr.allocate();
+  demodPtr=videoFltr.demodPtr;
+
+  lpFltr.setupMatchedFilter(0,1);
+}
+
+void videoFilter::process(FILTERPARAMTYPE *dataPtr)
+{
+
+  videoFltr.processFIRDemod(dataPtr,videoFltr.filteredPtr);
+  lpFltr.processFIRInt(videoFltr.filteredPtr,videoFltr.demodPtr);
+}
+
+
+
+wfFilter::wfFilter(uint maxLength):wfFltr(filter::FTFIR,maxLength)
+{
+   init();
+}
+
+wfFilter::~wfFilter()
+{
+
+}
+
+void wfFilter::init()
+{
+  wfFltr.init();
+  wfFltr.nZeroes=TXWFNUMTAPS-1;
+  wfFltr.gain=1;
+  wfFltr.coefZPtr=(FILTERPARAMTYPE *)wfFilterCoef;
+  wfFltr.volumeAttackIntegrator=0.07;
+  wfFltr.volumeDecayIntegrator=0.01;
+  wfFltr.allocate();
+}
+
+void  wfFilter::process(double *dataPtr, uint dataLength)
+{
+  wfFltr.dataLen=dataLength;
+  wfFltr.processFIR(dataPtr,dataPtr);
+}
+
+
+
+drmHilbertFilter::drmHilbertFilter(uint maxLength):drmFltr(filter::FTFIR,maxLength)
+{
+  init();
+}
+
+drmHilbertFilter::~drmHilbertFilter()
+{
+}
+
+void drmHilbertFilter::init()
+{
+  drmFltr.init();
+  drmFltr.nZeroes=DRMHILBERTTAPS-1;
+  drmFltr.nPoles=0;
+  drmFltr.coefZPtr=(FILTERPARAMTYPE *)drmHilbertCoef;
+  drmFltr.gain=DRMHILBERTGAIN;
+  drmFltr.allocate();
+}
+
+//void drmHilbertFilter::process(float *dataPtr,uint dataLength)
+//{
+
+//  process(dataPtr,dataPtr,dataLength);
+//}
+
+void drmHilbertFilter::process(FILTERPARAMTYPE *dataPtr, float *outputPtr,uint dataLength)
+{
+  drmFltr.dataLen=dataLength;
+  drmFltr.processIQ(dataPtr,outputPtr);
+}
+
+//void drmHilbertFilter::processIQ(FILTERPARAMTYPE *data, FILTERPARAMTYPE *output,uint dataLength)
+//{
+//  length=dataLength;
+//  FILTERPARAMTYPE resQ=0;
+//  const FILTERPARAMTYPE *cf1;
+//  FILTERPARAMTYPE *fp1;
+//  unsigned int i;
+//  uint k;
+//  for (k=0;k<length;k++)
+//    {
+//      resQ=0;
+//      cf1 = hilbCoef;
+//      fp1 = sampleBufferI;
+//      memmove(sampleBufferI+1, sampleBufferI,sizeof(FILTERPARAMTYPE)); // newest at index 0
+//      sampleBufferI[0]=data[k];
+//      for(i=0;i<hilbTaps;i++,fp1++,cf1++)
+//        {
+//          resQ+=(*fp1)*(*cf1);
+//        }
+//      output[2*k+1]=sampleBufferI[hilbTaps/2]; // just delay
+//      output[2*k]=(FILTERPARAMTYPE)resQ;
+//    }
+//}
+
+
diff --git a/qsstv/dsp/filters.h b/qsstv/dsp/filters.h
new file mode 100644
index 0000000..4dd350a
--- /dev/null
+++ b/qsstv/dsp/filters.h
@@ -0,0 +1,62 @@
+#ifndef FILTERS_H
+#define FILTERS_H
+#include "filter.h"
+
+
+class syncFilter
+{
+public:
+  syncFilter(uint maxLength);
+  ~syncFilter();
+  void process(FILTERPARAMTYPE *dataPtr);
+  void init();
+  FILTERPARAMTYPE *detect1200Ptr;
+  FILTERPARAMTYPE *detect1900Ptr;
+private:
+  filter sync1200;
+  filter sync1900;
+  filter vol1200;
+  filter vol1900;
+
+
+};
+
+
+class videoFilter
+{
+public:
+  videoFilter(uint maxLength);
+  ~videoFilter();
+  void process(FILTERPARAMTYPE *dataPtr);
+  void init();
+  quint16 *demodPtr;
+private:
+  filter videoFltr;
+  filter lpFltr;
+};
+
+class wfFilter
+{
+public:
+  wfFilter(uint maxLength);
+  ~wfFilter();
+  void process(FILTERPARAMTYPE *dataPtr, uint dataLength=RXSTRIPE);
+  void init();
+private:
+  filter wfFltr;
+};
+
+class drmHilbertFilter
+{
+public:
+  drmHilbertFilter(uint maxLength);
+  ~drmHilbertFilter();
+//  void process(FILTERPARAMTYPE *dataPtr, uint =RXSTRIPE);
+  void process(FILTERPARAMTYPE *dataPtr, float *outputPtr,uint dataLength);
+  void init();
+private:
+  filter drmFltr;
+};
+
+
+#endif // FILTERS_H
diff --git a/qsstv/dsp/nco.h b/qsstv/dsp/nco.h
index 1817add..7f3058d 100644
--- a/qsstv/dsp/nco.h
+++ b/qsstv/dsp/nco.h
@@ -21,8 +21,8 @@
 #ifndef NCO_H
 #define NCO_H
 #include <math.h>
-#include "qsstvglobal.h"
-#include <qsstvdefs.h>
+//#include "appglobal.h"
+#include "appdefs.h"
 
 /**
 @author Johan Maes
@@ -41,7 +41,7 @@ class NCO  // numerical controlled oscillator
 
 	\warning the frequency is the normilized frequency i.e F/samplingrate;
 */
-  NCO(DSPFLOAT freq=0.5)
+  NCO(double freq=0.5)
     {
       init(freq);
     }
@@ -54,7 +54,7 @@ class NCO  // numerical controlled oscillator
 			\param[in] frequency the frequency the oscillator must be running at
 			\warning the frequency is the normilized frequency i.e F/samplingrate;
 */
-  void init(DSPFLOAT frequency)
+  void init(double frequency)
     {
       w=(2*frequency*M_PI);
       b=2.*cos(w);
@@ -68,7 +68,7 @@ class NCO  // numerical controlled oscillator
 		\param[out] sinVal  sine value
 		\param[out] cosVal  cosine value
 	*/
-  void getSinCos(DSPFLOAT &sinVal,DSPFLOAT &cosVal)
+  void getSinCos(double &cosVal,double &sinVal)
     {
       sinVal=b*s1-s2;
       s2=s1;
@@ -81,9 +81,9 @@ class NCO  // numerical controlled oscillator
 	/** get the sine value
 		\return sine value
 	*/
-  DSPFLOAT getSine()
+  double getSine()
     {
-      float sinVal=b*s1-s2;
+      double sinVal=b*s1-s2;
       s2=s1;
       return(s1=sinVal);
     }
@@ -92,9 +92,9 @@ class NCO  // numerical controlled oscillator
 	\param[out] Q the Q component (val multiplied by a cosine)
 	\param[in] val the real value of the sample
  */
-  void multiply(DSPFLOAT &i, DSPFLOAT &q,DSPFLOAT val)
+  void multiply(double &i, double &q,double val)
 		{
-			DSPFLOAT t=b*s1-s2;
+      double t=b*s1-s2;
       i=val*t;
 			s2=s1;
 			s1=t;
@@ -105,10 +105,10 @@ class NCO  // numerical controlled oscillator
   	}
 
  private:
-  DSPFLOAT w;
-  DSPFLOAT b;
-  DSPFLOAT s1,s2;
-  DSPFLOAT c1,c2;
+  double w;
+  double b;
+  double s1,s2;
+  double c1,c2;
 };
 
 
diff --git a/qsstv/dsp/synthes.cpp b/qsstv/dsp/synthes.cpp
index c9acd59..d6999f2 100644
--- a/qsstv/dsp/synthes.cpp
+++ b/qsstv/dsp/synthes.cpp
@@ -19,16 +19,18 @@
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 #include "synthes.h"
-#include "qsstvglobal.h"
-#include "sound/soundio.h"
-#include "sound/waterfalltext.h"
-#include "utils/supportfunctions.h"
+#include "appglobal.h"
+#include "soundbase.h"
+#include "soundconfig.h"
+
+#include "supportfunctions.h"
+#include <unistd.h>
 
 /*
   To generate the frequency, we have to calculate the instant phase jump of the signal
   by dividing the frequency by the SR.
   We multiply this by the number of entries in the sine lookup table.
-  This value is added to the old index  of the sine table.
+//  This value is added to the old index  of the sine table.
 */
 
 synthesizer *synthesPtr;
@@ -41,10 +43,17 @@ synthesizer::synthesizer(double txSmpClock)
   addToLog(QString("synthes: tx sampling clock=%1").arg(txSamplingClock),LOGSOUND);
   for (i=0;i<SINTABLEN;i++)
     {
-      sineTable[i]=(sin(((double)i*M_PI*2.)/SINTABLEN)*8000.+0.5);
+      sineTable[i]=(sin(((double)i*M_PI*2.)/SINTABLEN)*8000.);
     }
-	oldAngle=0.;
-	adjust=0.;
+
+//  waterfallPtr= new waterfallText;
+  for(i=0;i<TONEBUFLEN;i++)
+  {
+    toneBuffer[i]=sin((i*2*M_PI)*1200./BASESAMPLERATE)*8000.;
+  }
+  oldAngle=0.;
+  adjust=0.;
+  pttToneCounter=0;
 }
 
 synthesizer::~synthesizer()
@@ -111,7 +120,7 @@ void synthesizer::sendSilence(double duration)
 	unsigned int ns=(uint)(duration*txSamplingClock+0.5);
 	for(i=0;i<ns;i++)
 		{
-			write(filter(0.));
+      write(0);
 		}
 }
 
@@ -125,18 +134,28 @@ void synthesizer::sendSample(double freq)
 SOUNDFRAME synthesizer::filter(double sample)
 {
  quint32 tst;
+ quint32 ptt;
  tst=(quint32) round(sample);
- tst+=tst<<16;
+// if(outputStereo)
+//   {
+//      tst+=tst<<16;
+//   }
+ if(pttToneRightChannel)
+   {
+     ptt=((quint32)toneBuffer[(pttToneCounter++)%TONEBUFLEN])<< 16;
+     tst+=ptt;
+   }
  return tst;
 }
 
 void synthesizer::write(double sample)
 {
-  while(!soundIOPtr->txBuffer.put(filter(sample)))
+  quint32 smp=filter(sample);
+//  while((!soundIOPtr->txBuffer.put(smp)) && (soundIOPtr->isPlaying()))
+     while((!soundIOPtr->txBuffer.put(smp)))
     {
       usleep(2000);
     }
-
 }
 
 
@@ -144,7 +163,7 @@ void synthesizer::write(double sample)
 // buffer must already contain correct stereo information
 void synthesizer::writeBuffer(quint32 *buffer, int len)
 {
-  while((!soundIOPtr->txBuffer.put(buffer,len)) && (!soundIOPtr->stoppedPlaying()))
+  while((!soundIOPtr->txBuffer.put(buffer,len)) && (soundIOPtr->isPlaying()))
     {
       usleep(2000);
     }
diff --git a/qsstv/dsp/synthes.h b/qsstv/dsp/synthes.h
index 0e060f9..1a238f0 100644
--- a/qsstv/dsp/synthes.h
+++ b/qsstv/dsp/synthes.h
@@ -23,8 +23,11 @@
 
 #include <math.h>
 #include "filterparam.h"
+#include "waterfalltext.h"
+
 
 #define SINTABLEN 2048
+#define TONEBUFLEN (BASESAMPLERATE/1200)
 
 class synthesizer
 {
@@ -58,9 +61,14 @@ private:
   void write(double sample);
 	double sample;
 	double adjust;
+//  waterfallText *waterfallPtr;
+  double toneBuffer[TONEBUFLEN];
+  uint pttToneCounter;
 //  void fillBuffer();  //only for test
 };
 
+extern synthesizer *synthesPtr;
+
 
 
 #endif
diff --git a/qsstv/editor/canvassizeform.cpp b/qsstv/editor/canvassizeform.cpp
new file mode 100644
index 0000000..aeeee26
--- /dev/null
+++ b/qsstv/editor/canvassizeform.cpp
@@ -0,0 +1,30 @@
+#include "canvassizeform.h"
+#include "ui_canvassizeform.h"
+#include "supportfunctions.h"
+
+canvasSizeForm::canvasSizeForm(QWidget *parent) :
+  QDialog(parent),
+  ui(new Ui::canvasSizeForm)
+{
+  ui->setupUi(this);
+}
+
+canvasSizeForm::~canvasSizeForm()
+{
+  delete ui;
+}
+
+QRect canvasSizeForm::getSize()
+{
+  int x;
+  int y;
+  getValue(x,ui->widthSpinBox);
+  getValue(y,ui->heightSpinBox);
+  return QRect(0,0,x,y);
+}
+
+void canvasSizeForm::setSize(int x,int y)
+{
+  setValue(x,ui->widthSpinBox);
+  setValue(y,ui->heightSpinBox);
+}
diff --git a/qsstv/editor/canvassizeform.h b/qsstv/editor/canvassizeform.h
new file mode 100644
index 0000000..81f2ba2
--- /dev/null
+++ b/qsstv/editor/canvassizeform.h
@@ -0,0 +1,24 @@
+#ifndef CANVASSIZEFORM_H
+#define CANVASSIZEFORM_H
+
+#include <QDialog>
+
+namespace Ui {
+class canvasSizeForm;
+}
+
+class canvasSizeForm : public QDialog
+{
+  Q_OBJECT
+
+public:
+  explicit canvasSizeForm(QWidget *parent = 0);
+  ~canvasSizeForm();
+  QRect getSize();
+  void setSize(int x,int y);
+
+private:
+  Ui::canvasSizeForm *ui;
+};
+
+#endif // CANVASSIZEFORM_H
diff --git a/qsstv/editor/canvassizeform.ui b/qsstv/editor/canvassizeform.ui
new file mode 100644
index 0000000..3baa352
--- /dev/null
+++ b/qsstv/editor/canvassizeform.ui
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>canvasSizeForm</class>
+ <widget class="QDialog" name="canvasSizeForm">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>202</width>
+    <height>138</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Image Size</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <layout class="QGridLayout" name="gridLayout">
+       <item row="0" column="0">
+        <widget class="QLabel" name="label_2">
+         <property name="text">
+          <string>Width</string>
+         </property>
+        </widget>
+       </item>
+       <item row="0" column="1">
+        <widget class="QSpinBox" name="widthSpinBox">
+         <property name="minimum">
+          <number>300</number>
+         </property>
+         <property name="maximum">
+          <number>1800</number>
+         </property>
+         <property name="singleStep">
+          <number>1</number>
+         </property>
+         <property name="value">
+          <number>800</number>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="0">
+        <widget class="QLabel" name="label">
+         <property name="text">
+          <string>Height</string>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="1">
+        <widget class="QSpinBox" name="heightSpinBox">
+         <property name="minimum">
+          <number>256</number>
+         </property>
+         <property name="maximum">
+          <number>1024</number>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <spacer name="verticalSpacer">
+     <property name="orientation">
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>20</width>
+       <height>16</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+   <item>
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>canvasSizeForm</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>canvasSizeForm</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/qsstv/editor/editor.cpp b/qsstv/editor/editor.cpp
index 766ed18..2138322 100644
--- a/qsstv/editor/editor.cpp
+++ b/qsstv/editor/editor.cpp
@@ -21,8 +21,8 @@
 #include "editor.h"
 
 #include <QtGui>
-#include "qsstvglobal.h"
-#include "utils/supportfunctions.h"
+#include "appglobal.h"
+#include "utils/dirdialog.h"
 #include "editorview.h"
 #include "configparams.h"
 #include "dispatcher.h"
@@ -133,8 +133,8 @@ void editor::initActions()
   deleteAction->setShortcut(tr("Del"));
   connect(deleteAction, SIGNAL(triggered()), ev->getScene(), SLOT(slotDeleteItem()));
 
-  dump= new QAction(tr("dump"),this);
-  connect(dump, SIGNAL(triggered()), ev, SLOT(slotDump()));
+//  dump= new QAction(tr("dump"),this);
+//  connect(dump, SIGNAL(triggered()), ev, SLOT(slotDump()));
 }
 
 
@@ -153,7 +153,7 @@ void editor::initMenubar()
   editMenu->addAction(copy);
   editMenu->addAction(paste);
   editMenu->addAction(clearAll);
-  editMenu->addAction(dump);
+//  editMenu->addAction(dump);
 }
 
 
@@ -184,7 +184,7 @@ void editor::slotFileOpen()
   /*	QFileDialog *fd = new QFileDialog(this,0,true);
   fd->show();*/
   dirDialog d(this,0);
-  QString s=d.openFileName(txImagesPath,"*.png *.gif *.jpg *.templ");
+  QString s=d.openFileName(txStockImagesPath,"*.png *.gif *.jpg *.templ");
   if (s==QString::null) return ;
   if (s.isEmpty()) return ;
   localFile.setFileName(s);
@@ -221,7 +221,7 @@ void editor::slotFileSaveImage()
   QString s(localFile.fileName());
   if(s.isEmpty())
     {
-      s=txImagesPath;
+      s=txStockImagesPath;
     }
   s=d.saveFileName(s,"*.png","png");
   if (s==QString::null) return ;
diff --git a/qsstv/editor/editor.h b/qsstv/editor/editor.h
index 891c261..d0a71b7 100644
--- a/qsstv/editor/editor.h
+++ b/qsstv/editor/editor.h
@@ -77,7 +77,7 @@ private:
 	QAction *copy;
 	QAction *paste;
 	QAction *deleteAction;
-	QAction *dump;
+//	QAction *dump;
 	QMenu *fileMenu;
 	QMenu *editMenu;
 	QFile localFile;
diff --git a/qsstv/editor/editorform.ui b/qsstv/editor/editorform.ui
index dd299fd..1eb9440 100644
--- a/qsstv/editor/editorform.ui
+++ b/qsstv/editor/editorform.ui
@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>808</width>
-    <height>520</height>
+    <width>648</width>
+    <height>697</height>
    </rect>
   </property>
   <property name="sizePolicy">
@@ -32,24 +32,9 @@
    <item>
     <layout class="QHBoxLayout" name="horizontalLayout_7">
      <item>
-      <widget class="QComboBox" name="sizeComboBox">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
-         <horstretch>0</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
-       </property>
-       <property name="minimumSize">
-        <size>
-         <width>80</width>
-         <height>22</height>
-        </size>
-       </property>
-       <property name="maximumSize">
-        <size>
-         <width>16777215</width>
-         <height>22</height>
-        </size>
+      <widget class="QPushButton" name="imageSizePushButton">
+       <property name="text">
+        <string>Image Size</string>
        </property>
       </widget>
      </item>
@@ -292,7 +277,7 @@
      <item>
       <layout class="QVBoxLayout" name="verticalLayout_2">
        <property name="spacing">
-        <number>2</number>
+        <number>1</number>
        </property>
        <item>
         <widget class="QGroupBox" name="groupBox">
@@ -301,9 +286,18 @@
          </property>
          <layout class="QVBoxLayout" name="verticalLayout_4">
           <property name="spacing">
-           <number>2</number>
+           <number>1</number>
           </property>
-          <property name="margin">
+          <property name="leftMargin">
+           <number>1</number>
+          </property>
+          <property name="topMargin">
+           <number>1</number>
+          </property>
+          <property name="rightMargin">
+           <number>1</number>
+          </property>
+          <property name="bottomMargin">
            <number>1</number>
           </property>
           <item>
@@ -401,7 +395,7 @@
                <string/>
               </property>
               <property name="icon">
-               <iconset resource="../qsstv.qrc">
+               <iconset>
                 <normaloff>:/icons/line.png</normaloff>:/icons/line.png</iconset>
               </property>
               <property name="iconSize">
@@ -587,7 +581,10 @@
         </widget>
        </item>
        <item>
-        <layout class="QHBoxLayout" name="horizontalLayout_5" stretch="0,1,0">
+        <layout class="QHBoxLayout" name="horizontalLayout_5" stretch="0,0,0">
+         <property name="spacing">
+          <number>1</number>
+         </property>
          <item>
           <spacer name="horizontalSpacer_4">
            <property name="orientation">
@@ -603,41 +600,20 @@
          </item>
          <item>
           <widget class="QSlider" name="vshearSlider">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="minimumSize">
-            <size>
-             <width>0</width>
-             <height>0</height>
-            </size>
-           </property>
-           <property name="maximumSize">
-            <size>
-             <width>40</width>
-             <height>16777215</height>
-            </size>
-           </property>
            <property name="minimum">
             <number>-25</number>
            </property>
            <property name="maximum">
             <number>25</number>
            </property>
-           <property name="pageStep">
-            <number>5</number>
-           </property>
            <property name="orientation">
             <enum>Qt::Vertical</enum>
            </property>
            <property name="tickPosition">
-            <enum>QSlider::TicksAbove</enum>
+            <enum>QSlider::TicksBelow</enum>
            </property>
            <property name="tickInterval">
-            <number>5</number>
+            <number>10</number>
            </property>
           </widget>
          </item>
@@ -755,7 +731,7 @@
          <property name="smallDecimalPoint">
           <bool>true</bool>
          </property>
-         <property name="numDigits">
+         <property name="digitCount">
           <number>4</number>
          </property>
          <property name="mode">
@@ -791,117 +767,6 @@
    </item>
    <item>
     <layout class="QGridLayout" name="gridLayout">
-     <item row="0" column="0">
-      <widget class="QLabel" name="hshearLabel">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
-         <horstretch>0</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
-       </property>
-       <property name="minimumSize">
-        <size>
-         <width>60</width>
-         <height>25</height>
-        </size>
-       </property>
-       <property name="maximumSize">
-        <size>
-         <width>60</width>
-         <height>16777215</height>
-        </size>
-       </property>
-       <property name="text">
-        <string>H-Shear</string>
-       </property>
-       <property name="alignment">
-        <set>Qt::AlignCenter</set>
-       </property>
-       <property name="wordWrap">
-        <bool>false</bool>
-       </property>
-      </widget>
-     </item>
-     <item row="0" column="1" colspan="3">
-      <widget class="QSlider" name="hshearSlider">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="Expanding" vsizetype="Maximum">
-         <horstretch>0</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
-       </property>
-       <property name="minimumSize">
-        <size>
-         <width>100</width>
-         <height>30</height>
-        </size>
-       </property>
-       <property name="maximumSize">
-        <size>
-         <width>16777215</width>
-         <height>30</height>
-        </size>
-       </property>
-       <property name="palette">
-        <palette>
-         <active>
-          <colorrole role="Button">
-           <brush brushstyle="SolidPattern">
-            <color alpha="255">
-             <red>255</red>
-             <green>0</green>
-             <blue>0</blue>
-            </color>
-           </brush>
-          </colorrole>
-         </active>
-         <inactive>
-          <colorrole role="Button">
-           <brush brushstyle="SolidPattern">
-            <color alpha="255">
-             <red>255</red>
-             <green>0</green>
-             <blue>0</blue>
-            </color>
-           </brush>
-          </colorrole>
-         </inactive>
-         <disabled>
-          <colorrole role="Button">
-           <brush brushstyle="SolidPattern">
-            <color alpha="255">
-             <red>255</red>
-             <green>0</green>
-             <blue>0</blue>
-            </color>
-           </brush>
-          </colorrole>
-         </disabled>
-        </palette>
-       </property>
-       <property name="minimum">
-        <number>-25</number>
-       </property>
-       <property name="maximum">
-        <number>25</number>
-       </property>
-       <property name="singleStep">
-        <number>1</number>
-       </property>
-       <property name="pageStep">
-        <number>5</number>
-       </property>
-       <property name="orientation">
-        <enum>Qt::Horizontal</enum>
-       </property>
-       <property name="tickPosition">
-        <enum>QSlider::TicksBelow</enum>
-       </property>
-       <property name="tickInterval">
-        <number>5</number>
-       </property>
-      </widget>
-     </item>
      <item row="0" column="4">
       <widget class="QLCDNumber" name="hshearLCD">
        <property name="sizePolicy">
@@ -1001,7 +866,7 @@
        <property name="smallDecimalPoint">
         <bool>true</bool>
        </property>
-       <property name="numDigits">
+       <property name="digitCount">
         <number>4</number>
        </property>
        <property name="mode">
@@ -1049,19 +914,6 @@
        </property>
       </widget>
      </item>
-     <item row="1" column="1">
-      <spacer name="horizontalSpacer_2">
-       <property name="orientation">
-        <enum>Qt::Horizontal</enum>
-       </property>
-       <property name="sizeHint" stdset="0">
-        <size>
-         <width>40</width>
-         <height>20</height>
-        </size>
-       </property>
-      </spacer>
-     </item>
      <item row="1" column="2">
       <widget class="QDial" name="rotateDial">
        <property name="minimumSize">
@@ -1533,6 +1385,37 @@
        </property>
       </spacer>
      </item>
+     <item row="0" column="0">
+      <widget class="QLabel" name="hshearLabel">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>60</width>
+         <height>25</height>
+        </size>
+       </property>
+       <property name="maximumSize">
+        <size>
+         <width>60</width>
+         <height>16777215</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>H-Shear</string>
+       </property>
+       <property name="alignment">
+        <set>Qt::AlignCenter</set>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
      <item row="1" column="4">
       <widget class="QLCDNumber" name="rotateLCD">
        <property name="sizePolicy">
@@ -1632,7 +1515,7 @@
        <property name="smallDecimalPoint">
         <bool>true</bool>
        </property>
-       <property name="numDigits">
+       <property name="digitCount">
         <number>4</number>
        </property>
        <property name="mode">
@@ -1649,6 +1532,99 @@
        </property>
       </widget>
      </item>
+     <item row="1" column="1">
+      <spacer name="horizontalSpacer_2">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item row="0" column="1" colspan="3">
+      <widget class="QSlider" name="hshearSlider">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Expanding" vsizetype="Maximum">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>100</width>
+         <height>30</height>
+        </size>
+       </property>
+       <property name="maximumSize">
+        <size>
+         <width>16777215</width>
+         <height>30</height>
+        </size>
+       </property>
+       <property name="palette">
+        <palette>
+         <active>
+          <colorrole role="Button">
+           <brush brushstyle="SolidPattern">
+            <color alpha="255">
+             <red>255</red>
+             <green>0</green>
+             <blue>0</blue>
+            </color>
+           </brush>
+          </colorrole>
+         </active>
+         <inactive>
+          <colorrole role="Button">
+           <brush brushstyle="SolidPattern">
+            <color alpha="255">
+             <red>255</red>
+             <green>0</green>
+             <blue>0</blue>
+            </color>
+           </brush>
+          </colorrole>
+         </inactive>
+         <disabled>
+          <colorrole role="Button">
+           <brush brushstyle="SolidPattern">
+            <color alpha="255">
+             <red>255</red>
+             <green>0</green>
+             <blue>0</blue>
+            </color>
+           </brush>
+          </colorrole>
+         </disabled>
+        </palette>
+       </property>
+       <property name="minimum">
+        <number>-25</number>
+       </property>
+       <property name="maximum">
+        <number>25</number>
+       </property>
+       <property name="singleStep">
+        <number>1</number>
+       </property>
+       <property name="pageStep">
+        <number>5</number>
+       </property>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="tickPosition">
+        <enum>QSlider::TicksBelow</enum>
+       </property>
+       <property name="tickInterval">
+        <number>5</number>
+       </property>
+      </widget>
+     </item>
     </layout>
    </item>
   </layout>
diff --git a/qsstv/editor/editorscene.cpp b/qsstv/editor/editorscene.cpp
index 9bc94d0..3c2a90f 100644
--- a/qsstv/editor/editorscene.cpp
+++ b/qsstv/editor/editorscene.cpp
@@ -22,35 +22,33 @@
 
 #include "editorscene.h"
 #include "gradientdialog.h"
-#include "qsstvglobal.h"
+#include "appglobal.h"
 #include "ui_textform.h"
-#include "gallerywidget.h"
-#include "utils/qjp2io.h"
+#include "mainwidgets/gallerywidget.h"
+#include "txwidget.h"
 
 editorScene::editorScene(QGraphicsView *parent)  : QGraphicsScene(parent)
 {
-	contextMenu=new QMenu();
-	arrange = new QMenu( "Arrange");
-	arrange->setTearOffEnabled(true);
-	arrange->addAction("Forward",this,SLOT(slotSendForward()));
-	arrange->addAction("Backward",this,SLOT(slotSendBackward()));
-	arrange->addAction("Bring to front",this,SLOT(slotBringToFront()));
-	arrange->addAction("Send to back",this,SLOT(slotSendToBack()));
-	contextMenu->addMenu(arrange);
-	contextMenu->addSeparator();
-	contextMenu->addAction("Change Text",this,SLOT(slotChangeText()));
-//	contextMenu->addAction("Copy",this,SLOT(slotCopy()));
-//	contextMenu->addAction("Paste",this,SLOT(slotPaste()));
-	contextMenu->addSeparator();
-	contextMenu->addAction("Delete",this,SLOT(slotDeleteItem()));
-	contextMenu->addAction("Expand",this,SLOT(slotExpand()));
-	contextMenu->addAction("Lock",this,SLOT(slotLock()));
-	contextMenu->addAction("Unlock",this,SLOT(slotUnlock()));
-	zMax=0;
-	pasted=false;
-	copyItem=NULL;
-	mode=MOVE;
-	imageType=NONE;
+  contextMenu=new QMenu();
+  arrange = new QMenu( "Arrange");
+  arrange->setTearOffEnabled(true);
+  arrange->addAction("Forward",this,SLOT(slotSendForward()));
+  arrange->addAction("Backward",this,SLOT(slotSendBackward()));
+  arrange->addAction("Bring to front",this,SLOT(slotBringToFront()));
+  arrange->addAction("Send to back",this,SLOT(slotSendToBack()));
+  contextMenu->addMenu(arrange);
+  contextMenu->addSeparator();
+  contextMenu->addAction("Change Text",this,SLOT(slotChangeText()));
+  contextMenu->addSeparator();
+  contextMenu->addAction("Delete",this,SLOT(slotDeleteItem()));
+  contextMenu->addAction("Expand",this,SLOT(slotExpand()));
+  contextMenu->addAction("Lock",this,SLOT(slotLock()));
+  contextMenu->addAction("Unlock",this,SLOT(slotUnlock()));
+  zMax=0;
+  pasted=false;
+  copyItem=NULL;
+  mode=MOVE;
+  imageType=NONE;
   localImage=NULL;
   rotate=0;
   vShear=0;
@@ -63,7 +61,7 @@ editorScene::editorScene(QGraphicsView *parent)  : QGraphicsScene(parent)
 editorScene::~editorScene()
 {
   if(localImage!=NULL) delete localImage;
-	if((!pasted) &&(copyItem!=NULL)) delete copyItem;
+  if((!pasted) &&(copyItem!=NULL)) delete copyItem;
   delete arrange;
   delete contextMenu;
 }
@@ -72,100 +70,96 @@ editorScene::~editorScene()
 bool editorScene::load(QFile &f)
 {
   bool borderSet=false;
-	QImage im;
-	itemBase *item;
-	quint32 magic;
-	QString version;
-	quint16 streamVersion;
-	int type;
-	if(!f.open(QIODevice::ReadOnly)) return false;
-	QDataStream str(&f);
+  QImage im;
+  itemBase *item;
+  quint32 magic;
+  QString version;
+  quint16 streamVersion;
+  int type;
+  if(f.fileName().isEmpty()) return false;
+  if(!f.open(QIODevice::ReadOnly)) return false;
+  QDataStream str(&f);
   str >> magic;
-	
+
   if (magic != MAGICNUMBER)
-		{
-			//try to load an image
-			f.reset();
-			if(im.load(&f,0))
-				{
+    {
+      //try to load an image
+      f.reset();
+      if(im.load(&f,0))
+        {
           addToLog("image loaded",LOGEDIT);
-					imageType=FLATIMAGE;
-					setImage(&im);
+          imageType=FLATIMAGE;
+          setImage(&im);
           border=QRect(0,0,im.width(),im.height());
           borderSet=true;
-					f.close();
-					return true;
-				}
-			else
-				{
+          f.close();
+          return true;
+        }
+      else
+        {
           addToLog("image failed to load",LOGEDIT);
-					f.close();
-					return false;
-				}
-		}
-	imageType=TEMPLATE;
-	str >> version;  // at this moment we do not use the version
-	str >> streamVersion;
-	str.setVersion(streamVersion);
-	while (!str.atEnd())
-		{
-			str >> type;
-			switch (type)
-				{
-					case itemBase::RECTANGLE:
-						item=new itemRectangle(contextMenu);
-					break;
-					case itemBase::ELLIPSE:
-						item=new itemEllipse(contextMenu);
-					break;
-					case itemBase::LINE:
-						item=new itemLine(contextMenu);
-					break;
-					case itemBase::TEXT:
-						item=new itemText(contextMenu);
-					break;
-					case itemBase::IMAGE:
-						item=new itemImage(contextMenu);
-					break;
-          case itemBase::REPLAY:
-            item=new itemReplayImage(contextMenu);
+          f.close();
+          return false;
+        }
+    }
+  imageType=TEMPLATE;
+  str >> version;  // at this moment we do not use the version
+  str >> streamVersion;
+  str.setVersion(streamVersion);
+  while (!str.atEnd())
+    {
+      str >> type;
+      switch (type)
+        {
+        case itemBase::RECTANGLE:
+          item=new itemRectangle(contextMenu);
+          break;
+        case itemBase::ELLIPSE:
+          item=new itemEllipse(contextMenu);
+          break;
+        case itemBase::LINE:
+          item=new itemLine(contextMenu);
+          break;
+        case itemBase::TEXT:
+          item=new itemText(contextMenu);
+          break;
+        case itemBase::IMAGE:
+          item=new itemImage(contextMenu);
+          break;
+        case itemBase::REPLAY:
+          item=new itemReplayImage(contextMenu);
           break;
         case itemBase::SBORDER:
-            borderSet=true;
-            item=new itemImage(contextMenu);
-            item->load(str);
-            border=item->rect();
-            delete item;
-            continue;
-        break;
-					default:
-            addToLog("Error in datastream",LOGEDIT);
-						f.close();
-						return false;
-					break;
-				}
-			item->load(str);
+          borderSet=true;
+          item=new itemImage(contextMenu);
+          item->load(str);
+          border=item->rect();
+          delete item;
+          continue;
+          break;
+        default:
+          addToLog("Error in datastream",LOGEDIT);
+          f.close();
+          return false;
+          break;
+        }
+      item->load(str);
       addItem(item);
-
-//      item->setTransform();
-      //itemSetup(item);
-		}
-  //border=sceneRect();
+    }
   optimizeDepth();
   if(!borderSet) border=QRectF(0,0,320,256);
   addToLog(QString("border position %1,%2 size: %3 x %4 border set=%5")
-               .arg(border.topLeft().x()).arg(border.topLeft().y())
-               .arg(border.width()).arg(border.height()).arg(borderSet),LOGEDIT);
+           .arg(border.topLeft().x()).arg(border.topLeft().y())
+           .arg(border.width()).arg(border.height()).arg(borderSet),LOGEDIT);
   f.close();
   setSceneRect(border);
-	return true;
+  return true;
 }
 
 QImage *editorScene::renderImage(int w,int h)
 {
   clearSelection();
   if (localImage!=NULL) delete localImage;
-  //border=sceneRect();
   if(w==0)
     {
       localImage=new QImage(border.width(),border.height(),QImage::Format_ARGB32_Premultiplied);
@@ -177,7 +171,6 @@ QImage *editorScene::renderImage(int w,int h)
   addToLog(QString("editorScene: pre-render size: %1 x %2").arg(localImage->size().width()).arg(localImage->size().height()),LOGEDIT);
   QPainter painter(localImage);
   painter.setRenderHint(QPainter::Antialiasing);
-  //setSceneRect(0,0,localImage->width(),localImage->height());
   localImage->fill(0);
   render(&painter);
   addToLog(QString("editor: post-render size: %1 x %2").arg(localImage->size().width()).arg(localImage->size().height()),LOGEDIT);
@@ -188,13 +181,11 @@ void editorScene::flattenImage(int w,int h)
 {
   if (localImage!=NULL) delete localImage;
   setSceneRect(border);
-//  border=sceneRect();
   localImage=new QImage(w,h,QImage::Format_ARGB32_Premultiplied);
   convertText();
   convertReplayImage();
   QPainter painter(localImage);
   painter.setRenderHint(QPainter::Antialiasing);
-//  setSceneRect(0,0,localImage->width(),localImage->height());
   localImage->fill(0);
   render(&painter);
 }
@@ -202,22 +193,14 @@ void editorScene::flattenImage(int w,int h)
 
 void editorScene::convertReplayImage()
 {
-    QString fn;
-    QImage im;
-    fn=galleryWidgetPtr->getLastRxImage();
-    if(fn.right(4).toUpper()==".JP2")
-    {
-        im=readJP2Image(fn);
-    }
-    else
-    {
-        im.load(fn);
-    }
-   if(im.isNull()) return;
-  //itemBase *it;
+  QString fn;
+  QImage im;
+  fn=txWidgetPtr->getPreviewFilename();
+  if(fn.isEmpty()) return;
+  im.load(fn);
+  if(im.isNull()) return;
   foreach(QGraphicsItem *t,items())
     {
-      //it=qgraphicsitem_cast<itemBase *>(t);
       if(t->type()==itemBase::REPLAY)
         {
           itemReplayImage *itt=qgraphicsitem_cast<itemReplayImage *>(t);
@@ -228,467 +211,432 @@ void editorScene::convertReplayImage()
 
 void editorScene::convertText()
 {
-  //itemBase *it;
   foreach(QGraphicsItem *t,items())
     {
-    //  it=qgraphicsitem_cast<itemBase *>(t);
       if(t->type()==itemBase::TEXT)
         {
           itemText *itt=qgraphicsitem_cast<itemText *>(t);
-//          itt->setText(textConversion(itt->text()));
           itt->setText(mexp.convert(itt->text()));
         }
     }
 }
 
-//QString editorScene::textConversion(QString str)
-//{
-//  int i,j;
-//  QChar c;
-//  convertedText.clear();
-//  bool special=false;
-//  for (i=0;i<str.length();i++)
-//  {
-//    if (special)
-//      {
-//        special=false;
-//        c=str.at(i);
-//        if(c=='%')
-//        {
-//          convertedText.append('%');
-//          continue;
-//        }
-//        for (j=0;j<convertList.count();j++)
-//          {
-//            if(c==convertList.at(j).tag)
-//            {
-//              convertedText.append(convertList.at(j).replacement);
-//            }
-//          }
-//      }
-//    else
-//      {
-//        if(str.at(i)!='%') convertedText.append(str.at(i));
-//        else special=true;
-//      }
-//  }
-//  addToLog("converted text: "+convertedText,LOGEDIT);
-//  return convertedText;
-//}
-
 
 
 bool editorScene::save(QFile &f,bool templ)
 {
-    QImage im(border.width(),border.height(),QImage::Format_ARGB32_Premultiplied);
-    setSceneRect(border);
-    addToLog(QString("editorscene:save %1 x %2").arg(sceneRect().width()).arg(sceneRect().height()),LOGEDIT);
-    if(!templ)
+  QImage im(border.width(),border.height(),QImage::Format_ARGB32_Premultiplied);
+  im.fill(0);
+  setSceneRect(border);
+  clearSelection();
+  addToLog(QString("editorscene:save %1 x %2").arg(sceneRect().width()).arg(sceneRect().height()),LOGEDIT);
+  if(!templ)
     {
-        QPainter painter(&im);
-        painter.setRenderHint(QPainter::Antialiasing);
-        render(&painter);
-        im.save(&f,"PNG");
-        return true;
+      QPainter painter(&im);
+      painter.setRenderHint(QPainter::Antialiasing);
+      render(&painter);
+      im.save(&f,"PNG");
+      return true;
     }
-    if(!f.open(QIODevice::WriteOnly)) return false;
-    QDataStream str(&f);
-    str.setVersion(QDataStream::Qt_4_4);
-    // Header with a "magic number" and a version
-    str << (quint32) MAGICNUMBER;
-    str <<  CONFIGVERSION;
-    str << (quint16) QDataStream::Qt_4_4;
-    itemBase *it;
-    foreach(QGraphicsItem *t,items())
+  if(!f.open(QIODevice::WriteOnly)) return false;
+  QDataStream str(&f);
+  str.setVersion(QDataStream::Qt_4_4);
+  // Header with a "magic number" and a version
+  str << (quint32) MAGICNUMBER;
+  str <<  CONFIGVERSION;
+  str << (quint16) QDataStream::Qt_4_4;
+  itemBase *it;
+  foreach(QGraphicsItem *t,items())
     {
-        it=qgraphicsitem_cast<itemBase *>(t);
-        if(t->type()>itemBase::BASE)
+      it=qgraphicsitem_cast<itemBase *>(t);
+      if(t->type()>itemBase::BASE)
         {
-            it->save(str);
+          it->save(str);
         }
     }
-    f.close();
-    return true;
+  f.close();
+  return true;
 }
 
 void editorScene::setMode(eMode m)
 {
-    mode = m;
-		if(mode==INSERT) clearSelection () ;
+  mode = m;
+  if(mode==INSERT) clearSelection () ;
 }
 
 void editorScene::setItemType(itemBase::egraphType tp)
 {
-    itemType = tp;
+  itemType = tp;
 }
 
 void editorScene::apply(changeFlags cf)
 {
-	QPen p;
-	itemBase *it;
-	if(selectedItems().isEmpty()) return; // nothing to do 
-	foreach(QGraphicsItem *t,selectedItems())
-		{
-				it=qgraphicsitem_cast<itemBase *>(t);
+  QPen p;
+  itemBase *it;
+  if(selectedItems().isEmpty()) return; // nothing to do
+  foreach(QGraphicsItem *t,selectedItems())
+    {
+      it=qgraphicsitem_cast<itemBase *>(t);
       if(cf & DFILLCOLOR)
-				{
-				 	it->setBrush(fillColor);
-				}
+        {
+          it->setBrush(fillColor);
+        }
       if(cf & DLINECOLOR)
-				{
-					p=it->pen();
-					p.setColor(lineColor);
-				 it->setPen(p);
-				}
+        {
+          p=it->pen();
+          p.setColor(lineColor);
+          it->setPen(p);
+        }
       if(cf & DPEN)
-				{
-					p=it->pen();
-					p.setWidth(penWidth);
-					it->setPen(p);
-				}
+        {
+          p=it->pen();
+          p.setWidth(penWidth);
+          it->setPen(p);
+        }
       if(cf & DGRADIENT)
-				{
-					gradientDialog gd;
-					sgradientParam tmp;
-					tmp=gd.param();
-					it->setGradient(tmp);
-					it->update();
-				}
+        {
+          gradientDialog gd;
+          sgradientParam tmp;
+          tmp=gd.param();
+          it->setGradient(tmp);
+          it->update();
+        }
       if(cf & DTRANSFORM)
-				{
-					it->setTransform(rotate,hShear,vShear);
-				}
-			if(t->type()==itemBase::TEXT)
-				{
-					itemText *itt=qgraphicsitem_cast<itemText *>(t);
+        {
+          it->setTransform(rotate,hShear,vShear);
+        }
+      if(t->type()==itemBase::TEXT)
+        {
+          itemText *itt=qgraphicsitem_cast<itemText *>(t);
           if(cf & DFONT) itt->setFont(font);
           if(cf & DTEXT) itt->setText(text);
-				}
-			it->update();
-		}
+        }
+      it->update();
+    }
 }
 
 void editorScene::clearAll()
 {
-	foreach(QGraphicsItem *t,items())
-		{
+  foreach(QGraphicsItem *t,items())
+    {
       if((t->type()>itemBase::BASE) && (t->type()!=itemBase::SBORDER))
-				{
-					removeItem(t);
-					delete t;
-				}
-		}
+        {
+          removeItem(t);
+          delete t;
+        }
+    }
 }
 
 
 void editorScene::itemSetup(itemBase *item)
 {
-	QPen p;
-	gradientDialog gd;
-	sgradientParam tmp;
-	tmp=gd.param();
-	item->setGradient(tmp);
-	item->setTransform(rotate,hShear,vShear);
-	p=item->pen();
-	p.setColor(lineColor);
-	p.setWidth(penWidth);
-	item->setPen(p);
-	item->setBrush(fillColor);
-	item->setZValue(zMax);
-	zMax+=1;
-	addItem(item);
+  QPen p;
+  gradientDialog gd;
+  sgradientParam tmp;
+  tmp=gd.param();
+  item->setGradient(tmp);
+  item->setTransform(rotate,hShear,vShear);
+  p=item->pen();
+  p.setColor(lineColor);
+  p.setWidth(penWidth);
+  item->setPen(p);
+  item->setBrush(fillColor);
+  item->setZValue(zMax);
+  zMax+=1;
+  addItem(item);
 }
 
 void editorScene::setImage(QImage *im)
 {
-	itemBase *item;
-	item=new itemImage(contextMenu);
-	item->setImage(*im);
-	item->setRect(0,0,im->width(),im->height());
-	itemSetup(item);
-	item->setPos(QPointF(0,0));
-	item->setSelected(true);
-	emit changeSize(im->width(),im->height());
+  itemBase *item;
+  item=new itemImage(contextMenu);
+  item->setImage(*im);
+  item->setRect(0,0,im->width(),im->height());
+  itemSetup(item);
+  item->setPos(QPointF(0,0));
+  item->setSelected(true);
+  emit changeSize(im->width(),im->height());
 }
 
 void editorScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
 {
-	itemBase *item;
-	QImage im;
+  itemBase *item;
+  QImage im;
   if (mouseEvent->button() == Qt::LeftButton)
-		{
-			switch(mode)
-				{
-					case INSERT:
-						switch(itemType)
-							{
-								case itemBase::RECTANGLE:
-									item=new itemRectangle(contextMenu);
-									itemSetup(item);
-									item->setPos(mouseEvent->scenePos());
-								break;
-								case itemBase::LINE:
-									item=new itemLine(contextMenu);
-									itemSetup(item);
-									item->setPos(mouseEvent->scenePos());
-								break;
-								case itemBase::ELLIPSE:
-									item=new itemEllipse(contextMenu);
-									itemSetup(item);
-									item->setPos(mouseEvent->scenePos());
-								break;
-								case itemBase::TEXT:
-									if (!text.isEmpty())
-										{
-											item=new itemText(contextMenu);
-											item->setFont(font);
-											item->setText(text);
-											itemSetup(item);
-											item->setPos(mouseEvent->scenePos());
-										}
-								break;
-								case itemBase::IMAGE:
-									if(im.load(fl))
-										{
-											item=new itemImage(contextMenu);
-											item->setImage(im);	
-											itemSetup(item);
-											item->setPos(mouseEvent->scenePos());
-										}
-								break;
-								case itemBase::REPLAY:
-									item=new itemReplayImage(contextMenu);
-									itemSetup(item);
-									item->setPos(mouseEvent->scenePos());
-								break;
-                case itemBase::SBORDER:
-								case itemBase::BASE:
-								break;
-							}
-					break;
-					case MOVE:
-						if(!selectedItems().isEmpty())
-							{
-								item=qgraphicsitem_cast<itemBase *>(selectedItems().first());
-							}
-					break;
-          case PICK:
+    {
+      switch(mode)
+        {
+        case INSERT:
+          switch(itemType)
+            {
+            case itemBase::RECTANGLE:
+              item=new itemRectangle(contextMenu);
+              itemSetup(item);
+              item->setPos(mouseEvent->scenePos());
+              break;
+            case itemBase::LINE:
+              item=new itemLine(contextMenu);
+              itemSetup(item);
+              item->setPos(mouseEvent->scenePos());
+              break;
+            case itemBase::ELLIPSE:
+              item=new itemEllipse(contextMenu);
+              itemSetup(item);
+              item->setPos(mouseEvent->scenePos());
+              break;
+            case itemBase::TEXT:
+              if (!text.isEmpty())
+                {
+                  item=new itemText(contextMenu);
+                  item->setFont(font);
+                  item->setText(text);
+                  itemSetup(item);
+                  item->setPos(mouseEvent->scenePos());
+                }
+              break;
+            case itemBase::IMAGE:
+              if(im.load(fl))
+                {
+                  item=new itemImage(contextMenu);
+                  item->setImage(im);
+                  itemSetup(item);
+                  item->setPos(mouseEvent->scenePos());
+                }
+              break;
+            case itemBase::REPLAY:
+              item=new itemReplayImage(contextMenu);
+              itemSetup(item);
+              item->setPos(mouseEvent->scenePos());
+              break;
+            case itemBase::SBORDER:
+            case itemBase::BASE:
+              break;
+            }
+          break;
+        case MOVE:
+          if(!selectedItems().isEmpty())
+            {
+              item=qgraphicsitem_cast<itemBase *>(selectedItems().first());
+            }
+          break;
+        case PICK:
           break;
 
-				}
-			}
-		QGraphicsScene::mousePressEvent(mouseEvent);
+        }
+    }
+  QGraphicsScene::mousePressEvent(mouseEvent);
 }
 
 void editorScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
 {
- QGraphicsScene::mouseMoveEvent(mouseEvent);
+  QGraphicsScene::mouseMoveEvent(mouseEvent);
 
 }
 
 void editorScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent)
 {
-	itemBase *item;
-	if(mode==MOVE)
-		{
-			if(!selectedItems().isEmpty())
-				{
-					item=qgraphicsitem_cast<itemBase *>(selectedItems().first());
-					emit itemSelected(item);
-				}
-		}
-	else if(mode==PICK)
-		{
-			emit colorSelected(mouseEvent->scenePos());
-			((QGraphicsView *)parent())->setCursor(Qt::ArrowCursor);
-			
-		}
-	mode=MOVE;
-	QGraphicsScene::mouseReleaseEvent(mouseEvent);
+  itemBase *item;
+  if(mode==MOVE)
+    {
+      if(!selectedItems().isEmpty())
+        {
+          item=qgraphicsitem_cast<itemBase *>(selectedItems().first());
+          emit itemSelected(item);
+        }
+    }
+  else if(mode==PICK)
+    {
+      emit colorSelected(mouseEvent->scenePos());
+      ((QGraphicsView *)parent())->setCursor(Qt::ArrowCursor);
+
+    }
+  mode=MOVE;
+  QGraphicsScene::mouseReleaseEvent(mouseEvent);
 }
 
 
 void editorScene::slotCopy()
 {
-	itemBase *item;
-	if((!pasted) &&(copyItem!=NULL)) delete copyItem;
+  itemBase *item;
+  if((!pasted) &&(copyItem!=NULL)) delete copyItem;
   if(selectedItems().isEmpty()) return; // nothing to do
-	item=qgraphicsitem_cast<itemBase *>(selectedItems().first());
-	makeCopy(item);
+  item=qgraphicsitem_cast<itemBase *>(selectedItems().first());
+  makeCopy(item);
 }
 
 void editorScene::makeCopy(itemBase *it)
 {
-	itemBase *item=it;
-	itemBase::egraphType type=(itemBase::egraphType)item->type();
-	switch(type)
-		{
-			case itemBase::RECTANGLE:
-				copyItem=new itemRectangle(item->getParam().menu);
-			break;
-			case itemBase::LINE:
-				copyItem=new itemLine(item->getParam().menu);
-			break;
-			case itemBase::ELLIPSE:
-				copyItem=new itemEllipse(item->getParam().menu);
-			break;
-			case itemBase::TEXT:
-				copyItem=new itemText(item->getParam().menu);
-			break;
-			case itemBase::IMAGE:
-				copyItem=new itemImage(item->getParam().menu);
-			break;
+  itemBase *item=it;
+  itemBase::egraphType type=(itemBase::egraphType)item->type();
+  switch(type)
+    {
+    case itemBase::RECTANGLE:
+      copyItem=new itemRectangle(item->getParam().menu);
+      break;
+    case itemBase::LINE:
+      copyItem=new itemLine(item->getParam().menu);
+      break;
+    case itemBase::ELLIPSE:
+      copyItem=new itemEllipse(item->getParam().menu);
+      break;
+    case itemBase::TEXT:
+      copyItem=new itemText(item->getParam().menu);
+      break;
+    case itemBase::IMAGE:
+      copyItem=new itemImage(item->getParam().menu);
+      break;
     case itemBase::REPLAY:
       copyItem=new itemReplayImage(item->getParam().menu);
-    break;
-			default:
-				return;
-		}
-	copyItem->setParam(item->getParam());
-	copyItem->setPos(item->pos()+QPointF(10,10));
-	pasted=false;
+      break;
+    default:
+      return;
+    }
+  copyItem->setParam(item->getParam());
+  copyItem->setPos(item->pos()+QPointF(10,10));
+  pasted=false;
 }
 
 void editorScene::slotPaste()
 {
-		clearSelection();
-		copyItem->setZValue(zMax+1);
-		zMax+=1;
-		addItem(copyItem);
-		pasted=true,
-		makeCopy(copyItem);
-		clearSelection();
+  clearSelection();
+  copyItem->setZValue(zMax+1);
+  zMax+=1;
+  addItem(copyItem);
+  pasted=true,
+      makeCopy(copyItem);
+  clearSelection();
 }
 
 void editorScene::slotExpand()
 {
-	itemBase *it;
+  itemBase *it;
   if(selectedItems().isEmpty()) return; // nothing to do
-	foreach(QGraphicsItem *t,selectedItems())
-		{
-			it=qgraphicsitem_cast<itemBase *>(t);
+  foreach(QGraphicsItem *t,selectedItems())
+    {
+      it=qgraphicsitem_cast<itemBase *>(t);
       if(it->type()!=itemBase::TEXT)
-				{
-					it->setRect(border);
-					it->setPos(0,0);
-				}
-		}
+        {
+          it->setRect(border);
+          it->setPos(0,0);
+        }
+    }
 }
 
 void editorScene::slotChangeText()
 {
   if(selectedItems().isEmpty()) return; // nothing to do
-	itemText *item=qgraphicsitem_cast<itemText *>(selectedItems().first());
+  itemText *item=qgraphicsitem_cast<itemText *>(selectedItems().first());
   if(!item)
     {
       return;
     }
-	if(item->type()!=itemBase::TEXT) return;
-	QDialog d(0);
-	Ui::textForm t;
-	t.setupUi(&d);
-	t.lineEdit->setText(item->text());
-	if(d.exec()==QDialog::Accepted)
-		{
-			item->setText(t.lineEdit->text());
-		}
+  if(item->type()!=itemBase::TEXT) return;
+  QDialog d(0);
+  Ui::textForm t;
+  t.setupUi(&d);
+  t.plainTextEdit->setPlainText(item->text());
+  if(d.exec()==QDialog::Accepted)
+    {
+      item->setText(t.plainTextEdit->toPlainText());
+    }
 }
 
 
 void editorScene::slotDeleteItem()
 {
   if(selectedItems().isEmpty()) return; // nothing to do
-	foreach(QGraphicsItem *t,selectedItems())
-		{
-			removeItem(t);
-			delete t;
-		}
+  foreach(QGraphicsItem *t,selectedItems())
+    {
+
+      removeItem(t);
+      delete t;
+    }
 }
 
 
 void editorScene::slotLock()
 {
-	itemBase *it;
+  itemBase *it;
   if(selectedItems().isEmpty()) return; // nothing to do
-	foreach(QGraphicsItem *t,selectedItems())
-		{
-			it=qgraphicsitem_cast<itemBase *>(t);
-			it->setLocked(true);
-		}
+  foreach(QGraphicsItem *t,selectedItems())
+    {
+      it=qgraphicsitem_cast<itemBase *>(t);
+      it->setLocked(true);
+    }
 }
 
 void editorScene::slotUnlock()
 {
-	
-	 itemBase *it;
-   if(selectedItems().isEmpty()) return; // nothing to do
-	foreach(QGraphicsItem *t,selectedItems())
-		{
-			it=qgraphicsitem_cast<itemBase *>(t);
-			it->setLocked(false);
-		}
+
+  itemBase *it;
+  if(selectedItems().isEmpty()) return; // nothing to do
+  foreach(QGraphicsItem *t,selectedItems())
+    {
+      it=qgraphicsitem_cast<itemBase *>(t);
+      it->setLocked(false);
+    }
 }
 
 
 void editorScene::slotBringToFront()
 {
   if(selectedItems().isEmpty()) return; // nothing to do
-	foreach(QGraphicsItem *t,selectedItems())
-		{
-			zMax+=1;
-			t->setZValue(zMax);
+  foreach(QGraphicsItem *t,selectedItems())
+    {
+      zMax+=1;
+      t->setZValue(zMax);
     }
-	optimizeDepth();
+  optimizeDepth();
 }
 
 void editorScene::slotSendToBack()
 {
   if(selectedItems().isEmpty()) return; // nothing to do
-	foreach(QGraphicsItem *t,selectedItems())
-		{
-			t->setZValue(0.5);
-		}
-	optimizeDepth();
+  foreach(QGraphicsItem *t,selectedItems())
+    {
+      t->setZValue(0.5);
+    }
+  optimizeDepth();
 }
 
 
 void editorScene::slotSendBackward()
 {
   if(selectedItems().isEmpty()) return; // nothing to do
-	foreach(QGraphicsItem *t,selectedItems())
-		{
-			t->setZValue(t->zValue()-1.5);
-		}
-	optimizeDepth();
+  foreach(QGraphicsItem *t,selectedItems())
+    {
+      t->setZValue(t->zValue()-1.5);
+    }
+  optimizeDepth();
 }
 
 void editorScene::slotSendForward()
 {
   if(selectedItems().isEmpty()) return; // nothing to do
-	foreach(QGraphicsItem *t,selectedItems())
-		{
-			t->setZValue(t->zValue()+1.5);
-		}
-	optimizeDepth();
+  foreach(QGraphicsItem *t,selectedItems())
+    {
+      t->setZValue(t->zValue()+1.5);
+    }
+  optimizeDepth();
 }
 
 void editorScene::optimizeDepth()
 {
   itemBase *it;
-	zMax=items().count();
-	qreal i=0;
-	foreach(QGraphicsItem *t,items(itemsBoundingRect ()))
-		{
+  zMax=items().count();
+  qreal i=0;
+  foreach(QGraphicsItem *t,items(itemsBoundingRect ()))
+    {
       it=qgraphicsitem_cast<itemBase *>(t);
       if(it->type()==itemBase::SBORDER)
-       {
+        {
           it->setZValue(0.1);
         }
       else if(it->type()>itemBase::BASE)
-				{
+        {
           it->setZValue(zMax-i);
-					i+=1;
-				}
+          i+=1;
+        }
       addToLog(QString("optimize_1 type=%1 pos=%2,%3 resctPos=%4,%5").arg(it->getTypeStr()).arg(t->pos().x()).arg(t->pos().y()).arg(it->rect().x()).arg(it->rect().y()),LOGEDIT);
       addToLog(QString("Boundingrect t=%1 %2,%3 %4,%5").arg(it->getTypeStr()).arg(it->boundingRect().x()).arg(it->boundingRect().y()).arg(it->boundingRect().width()).arg(it->boundingRect().height()),LOGEDIT);
     }
@@ -701,8 +649,8 @@ void editorScene::addBorder(int w,int h)
   if (borderItemPtr==NULL)
     {
       borderItemPtr=new itemBorder(contextMenu);
+      itemSetup(borderItemPtr);
     }
-  itemSetup(borderItemPtr);
   borderItemPtr->setPos(0,0);
   borderItemPtr->setRect(0,0,w,h);
   border=QRectF(0,0,w,h);
@@ -712,29 +660,13 @@ void editorScene::addBorder(int w,int h)
 void editorScene::overlay(QImage *ima)
 {
   clearSelection();
-//  addToLog(QString("overlay: before number of items: %1").arg(items().count()),LOGEDIT);
-//  itemBase *item;
-//  item=new itemImage(contextMenu);
-//  item->setImage(*ima);
-//  itemSetup(item);
-//  item->setPos(0,0);
-//  item->setRect(0,0,ima->width(),ima->height());
-//  item->setSelected(true);
-//  slotSendToBack();
-//  clearSelection();
-//  addToLog(QString("overlay: after number of items: %1").arg(items().count()),LOGEDIT);
- // flattenImage(ima->width(),ima->height());
   setSceneRect(border);
-//  border=sceneRect();
   if (localImage!=NULL) delete localImage;
   localImage=new QImage(ima->copy());
-//  localImage=ima;
   convertText();
   convertReplayImage();
   QPainter painter(localImage);
   painter.setRenderHint(QPainter::Antialiasing);
-//  setSceneRect(0,0,localImage->width(),localImage->height());
-//  localImage->fill(0);
   render(&painter,QRectF(),QRectF(),Qt::IgnoreAspectRatio);
 }
 
diff --git a/qsstv/editor/editorview.cpp b/qsstv/editor/editorview.cpp
index a22c51e..87924fe 100644
--- a/qsstv/editor/editorview.cpp
+++ b/qsstv/editor/editorview.cpp
@@ -18,12 +18,13 @@
  *   Free Software Foundation, Inc.,                                       *
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
- 
+
 #include "editorview.h"
-#include "qsstvglobal.h"
-#include "utils/supportfunctions.h"
+#include "appglobal.h"
+#include "utils/dirdialog.h"
 #include "graphicitems.h"
 #include "gradientdialog.h"
+#include "canvassizeform.h"
 #include "ui_textform.h"
 
 
@@ -35,18 +36,18 @@
 
 static QColor defaultColors[NUMCOLORSELECTORS]= 
 {
-	qRgba(  0,  0,  0,255),
-	qRgba(255,255,255,255),
-	qRgba(255,  0,  0,255),
-	qRgba(  0,255,  0,255),
-	qRgba(  0,  0,255,255),
-	qRgba(128,128,128,255),
-	qRgba(255,  0,  0,128),
-	qRgba(  0,255,  0,128),
-	qRgba(  0,  0,255,128),
-	qRgba(255,255,  0,128),
-	qRgba(  0,255,255,128),
-	qRgba(255,  0,255,128)
+  qRgba(  0,  0,  0,255),
+  qRgba(255,255,255,255),
+  qRgba(255,  0,  0,255),
+  qRgba(  0,255,  0,255),
+  qRgba(  0,  0,255,255),
+  qRgba(128,128,128,255),
+  qRgba(255,  0,  0,128),
+  qRgba(  0,255,  0,128),
+  qRgba(  0,  0,255,128),
+  qRgba(255,255,  0,128),
+  qRgba(  0,255,255,128),
+  qRgba(255,  0,255,128)
 };
 
 
@@ -54,428 +55,446 @@ static QColor defaultColors[NUMCOLORSELECTORS]=
 
 struct sCanvasSize
 {
-	const QString s;
-	int width;
-	int height;
+  const QString s;
+  int width;
+  int height;
 };
-#define SIZES 7
+#define SIZES 8
 sCanvasSize canvasSizeArray[SIZES]=
 {
-	{"160x120",160,120},
-	{"320x240",320,240},
-	{"320x256",320,256},
-	{"500x400",500,400},
-	{"500x496",500,496},
-	{"640x496",640,496},
-	{"800x616",800,616}
+  {"160x120",160,120},
+  {"320x240",320,240},
+  {"320x256",320,256},
+  {"500x400",500,400},
+  {"500x496",500,496},
+  {"640x496",640,496},
+  {"800x616",800,616},
+  {"1024x800",1024,800}
 };
 
-int s;
+//int s;
 
 #define BORDER 4
 /** editorview */
 editorView::editorView(QWidget *parent):QWidget(parent), Ui::editorForm()
 {
-	setupUi(this);
+  setupUi(this);
   scene=new editorScene(canvas);
-	canvas->setScene(scene);
- // canvas->setFixedSize(800,700);;
-	pickMode=NOPICK;
+  canvas->setScene(scene);
+  // canvas->setFixedSize(800,700);;
+  pickMode=NOPICK;
   //border= new QGraphicsRectItem(0,0,320,256);
-//	scene->border=border->rect();
-//	scene->addItem(border);
-
-	scene->setMode(editorScene::MOVE);
-	scene->setItemType(itemBase::BASE);
-	for (int i=0; i<SIZES;i++) sizeComboBox->addItem(canvasSizeArray[i].s);
-	
-	readSettings();
-	sizeComboBox->setCurrentIndex(canvasSizeIndex);
-  scene->setSceneRect(0,0,canvasSizeArray[canvasSizeIndex].width,canvasSizeArray[canvasSizeIndex].height);
-	connect(scene,SIGNAL(itemSelected(itemBase*)),SLOT(slotItemSelected(itemBase*)));
-    connect(sizeComboBox, SIGNAL(activated(int)), SLOT(slotChangeCanvasSize(int)));
-	connect(arrowPushButton,SIGNAL(clicked()),SLOT(slotArrow()));
-	connect(rectanglePushButton,SIGNAL(clicked()),SLOT(slotRectangle()));
-	connect(circlePushButton,SIGNAL(clicked()),SLOT(slotCircle()));
-	connect(replayPushButton,SIGNAL(clicked()),SLOT(slotReplay()));
-	connect(imagePushButton,SIGNAL(clicked()),SLOT(slotImage()));
-	connect(linePushButton,SIGNAL(clicked()),SLOT(slotLine()));
-	connect(textPushButton,SIGNAL(clicked()),SLOT(slotText()));
-	rotateLCD->display( "  0'" );
+  //	scene->border=border->rect();
+  //	scene->addItem(border);
+
+  scene->setMode(editorScene::MOVE);
+  scene->setItemType(itemBase::BASE);
+  //  for (int i=0; i<SIZES;i++) sizeComboBox->addItem(canvasSizeArray[i].s);
+
+  connect(imageSizePushButton,SIGNAL(clicked()),SLOT(slotChangeCanvasSize()));
+
+  readSettings();
+  //  sizeComboBox->setCurrentIndex(canvasSizeIndex);
+//  scene->setSceneRect(0,0,canvasSizeArray[canvasSizeIndex].width,canvasSizeArray[canvasSizeIndex].height);
+  connect(scene,SIGNAL(itemSelected(itemBase*)),SLOT(slotItemSelected(itemBase*)));
+  //  connect(sizeComboBox, SIGNAL(activated(int)), SLOT(slotChangeCanvasSize(int)));
+  connect(arrowPushButton,SIGNAL(clicked()),SLOT(slotArrow()));
+  connect(rectanglePushButton,SIGNAL(clicked()),SLOT(slotRectangle()));
+  connect(circlePushButton,SIGNAL(clicked()),SLOT(slotCircle()));
+  connect(replayPushButton,SIGNAL(clicked()),SLOT(slotReplay()));
+  connect(imagePushButton,SIGNAL(clicked()),SLOT(slotImage()));
+  connect(linePushButton,SIGNAL(clicked()),SLOT(slotLine()));
+  connect(textPushButton,SIGNAL(clicked()),SLOT(slotText()));
+  rotateLCD->display( "  0'" );
   connect(rotateDial, SIGNAL(valueChanged(int)),SLOT(slotRotateChanged(int)) );
   hshearLCD->display( "0.00" );
-	vshearLCD->display( "0.00" );
-	connect(hshearSlider, SIGNAL(valueChanged(int)),SLOT(slotShearChanged(int)) );
+  vshearLCD->display( "0.00" );
+  connect(hshearSlider, SIGNAL(valueChanged(int)),SLOT(slotShearChanged(int)) );
   connect(vshearSlider, SIGNAL(valueChanged(int)),SLOT(slotShearChanged(int)) );
   //connect (scene,SIGNAL(changeSize(int,int)),SLOT(slotChangeCanvasSize(int,int)));
 
-//	connect(textLineEdit, SIGNAL(textChanged(const QString &)),SLOT(slotTextReturnPressed(const QString &)) );
-//	slotRotateChanged(0);
-//	slotShearChanged(0);
-	fontComboBox->setCurrentIndex(currentFontIndex);
-
-	connect(fontComboBox,SIGNAL(currentFontChanged(const QFont &)),SLOT(slotFontChanged(const QFont &)));
-
-	fontSizeSpinBox->setRange(6, 180);
-	fontSizeSpinBox->setValue(currentPointSize);
-	scene->font.setPointSize(fontSizeSpinBox->value());
-	connect(fontSizeSpinBox,SIGNAL( valueChanged (int)),SLOT(slotFontSizeChanged(int)));
-	
-	penWidthSpinBox->setRange(0,99);
-	penWidthSpinBox->setValue(currentPenWidth);
-	connect(penWidthSpinBox,SIGNAL( valueChanged (double)),SLOT(slotPenWidthChanged(double)));
-
-
-	boldButton->setChecked(scene->font.bold());
-	italicButton->setChecked(scene->font.italic());
-	underlineButton->setChecked(scene->font.underline());
-	connect(boldButton,SIGNAL( clicked(bool)),SLOT(slotBold(bool)));
-	connect(italicButton,SIGNAL( clicked(bool)),SLOT(slotItalic(bool)));
-	connect(underlineButton,SIGNAL( clicked(bool)),SLOT(slotUnderline(bool)));
-	
-
-	QAction *action;
-	action = new QAction("Color Picker", this);
-	action->setData(TBFILL);
+  //	connect(textLineEdit, SIGNAL(textChanged(const QString &)),SLOT(slotTextReturnPressed(const QString &)) );
+  //	slotRotateChanged(0);
+  //	slotShearChanged(0);
+  fontComboBox->setCurrentIndex(currentFontIndex);
+
+  connect(fontComboBox,SIGNAL(currentFontChanged(const QFont &)),SLOT(slotFontChanged(const QFont &)));
+
+  fontSizeSpinBox->setRange(6, 180);
+  fontSizeSpinBox->setValue(currentPointSize);
+  scene->font.setPointSize(fontSizeSpinBox->value());
+  connect(fontSizeSpinBox,SIGNAL( valueChanged (int)),SLOT(slotFontSizeChanged(int)));
+
+  penWidthSpinBox->setRange(0,99);
+  penWidthSpinBox->setValue(currentPenWidth);
+  connect(penWidthSpinBox,SIGNAL( valueChanged (double)),SLOT(slotPenWidthChanged(double)));
+
+
+  boldButton->setChecked(scene->font.bold());
+  italicButton->setChecked(scene->font.italic());
+  underlineButton->setChecked(scene->font.underline());
+  connect(boldButton,SIGNAL( clicked(bool)),SLOT(slotBold(bool)));
+  connect(italicButton,SIGNAL( clicked(bool)),SLOT(slotItalic(bool)));
+  connect(underlineButton,SIGNAL( clicked(bool)),SLOT(slotUnderline(bool)));
+
+
+  QAction *action;
+  action = new QAction("Color Picker", this);
+  action->setData(TBFILL);
   connect(action, SIGNAL(triggered()),this,SLOT(slotColorPicker()));
 
-	fillToolButton->setMenu(createColorMenu(SLOT(slotColorDialog()),TBFILL,"Select Color"));
+  fillToolButton->setMenu(createColorMenu(SLOT(slotColorDialog()),TBFILL,"Select Color"));
 
-	fillToolButton->menu()->addAction(action);
- // scene->fillColor=QColor(127,127,0);
-	fillToolButton->setIcon(createColorToolButtonIcon(":/icons/colorfill.png", scene->fillColor));
-	connect(fillToolButton, SIGNAL(clicked()),this, SLOT(slotButtonTriggered()));
+  fillToolButton->menu()->addAction(action);
+  // scene->fillColor=QColor(127,127,0);
+  fillToolButton->setIcon(createColorToolButtonIcon(":/icons/colorfill.png", scene->fillColor));
+  connect(fillToolButton, SIGNAL(clicked()),this, SLOT(slotButtonTriggered()));
 
-	action = new QAction("Color Picker", this);
-	action->setData(TBLINE);
+  action = new QAction("Color Picker", this);
+  action->setData(TBLINE);
   connect(action, SIGNAL(triggered()),this,SLOT(slotColorPicker()));
-	lineToolButton->setMenu(createColorMenu(SLOT(slotColorDialog()),TBLINE,"Select Color"));
-	lineToolButton->menu()->addAction(action);
+  lineToolButton->setMenu(createColorMenu(SLOT(slotColorDialog()),TBLINE,"Select Color"));
+  lineToolButton->menu()->addAction(action);
   lineToolButton->setIcon(createColorToolButtonIcon(":/icons/colorline.png", scene->lineColor));
-	connect(lineToolButton, SIGNAL(clicked()),this, SLOT(slotButtonTriggered()));
-	connect(scene,SIGNAL(colorSelected( const QPointF &)),this,SLOT(slotColorPicked(const QPointF &)));
-	
-	gradientToolButton->setMenu(createColorMenu(SLOT(slotGradientDialog()),TBGRAD,"Select Gradient"));
+  connect(lineToolButton, SIGNAL(clicked()),this, SLOT(slotButtonTriggered()));
+  connect(scene,SIGNAL(colorSelected( const QPointF &)),this,SLOT(slotColorPicked(const QPointF &)));
+
+  gradientToolButton->setMenu(createColorMenu(SLOT(slotGradientDialog()),TBGRAD,"Select Gradient"));
   gradientToolButton->setIcon(createColorToolButtonIcon(":/icons/gradient.png", scene->gradientColor));
-	connect(gradientToolButton, SIGNAL(clicked()),this, SLOT(slotButtonTriggered()));
-// setup the defaults
-	slotRotateChanged(0);
-	
-	setTransform();
-	slotFontChanged(fontComboBox->currentFont());
-	slotPenWidthChanged(currentPenWidth);
-	slotChangeCanvasSize(canvasSizeIndex);
-  slotDump();
+  connect(gradientToolButton, SIGNAL(clicked()),this, SLOT(slotButtonTriggered()));
+  // setup the defaults
+  slotRotateChanged(0);
+
+  setTransform();
+  slotFontChanged(fontComboBox->currentFont());
+  slotPenWidthChanged(currentPenWidth);
+  changeCanvasSize();
+#ifndef QT_NO_DEBUG
+  dump();
+#endif
+
   modified=false;
 }
 
 
 editorView::~editorView()
 {
-	writeSettings();
+  writeSettings();
 }
 
 /*! 
-	reads the settings (saved images for tx,rx,templates)
+  reads the settings (saved images for tx,rx,templates)
 */
 
 void editorView::readSettings()
 {
-	QSettings qSettings;
-	qSettings.beginGroup ("Editor");
-	canvasSizeIndex=qSettings.value("canvassizeindex", 2 ).toInt();
-	currentFontIndex=qSettings.value("currentfontindex", 2 ).toInt();
-	currentPointSize=qSettings.value("currentpointSize", 24).toInt();
-	currentPenWidth=qSettings.value("currentpenwidth", 1).toDouble();
-	scene->font = qSettings.value("fillcolor", qApp->font()).value<QFont>();
-    scene->fillColor = qSettings.value("fillcolor", QColor(Qt::white)).value<QColor>();
-    scene->lineColor = qSettings.value("linecolor", QColor(Qt::black )).value<QColor>();
-    scene->gradientColor = qSettings.value("gradientcolor",QColor( Qt::red )).value<QColor>();
-	qSettings.endGroup();
+  QSettings qSettings;
+  qSettings.beginGroup ("Editor");
+  canvasWidth=qSettings.value("canvasWidth", 800 ).toInt();
+  canvasHeight=qSettings.value("canvasHeight", 600 ).toInt();
+  currentFontIndex=qSettings.value("currentfontindex", 2 ).toInt();
+  currentPointSize=qSettings.value("currentpointSize", 24).toInt();
+  currentPenWidth=qSettings.value("currentpenwidth", 1).toDouble();
+  scene->font = qSettings.value("fillcolor", qApp->font()).value<QFont>();
+  scene->fillColor = qSettings.value("fillcolor", QColor(Qt::white)).value<QColor>();
+  scene->lineColor = qSettings.value("linecolor", QColor(Qt::black )).value<QColor>();
+  scene->gradientColor = qSettings.value("gradientcolor",QColor( Qt::red )).value<QColor>();
+  qSettings.endGroup();
 }
 
 /*! 
-	writes the settings (saved images for tx,rx,templates)
+  writes the settings (saved images for tx,rx,templates)
 */
 void editorView::writeSettings()
 {
-	QSettings qSettings;
-	qSettings.beginGroup ("Editor" );
-	qSettings.setValue ("canvassizeindex", sizeComboBox->currentIndex());
-	qSettings.setValue ("currentfontindex", fontComboBox->currentIndex());
-	qSettings.setValue ("currentpenwidth", penWidthSpinBox->value());
-	qSettings.setValue ("currentpointsize",fontSizeSpinBox->value());
-	qSettings.setValue ("fillcolor", scene->fillColor);
-	qSettings.setValue ("linecolor", scene->lineColor);
-	qSettings.setValue ("gradientcolor", scene->gradientColor);
-	qSettings.endGroup();
+  QSettings qSettings;
+  qSettings.beginGroup ("Editor" );
+//  qSettings.setValue ("canvassizeindex", sizeComboBox->currentIndex());
+  qSettings.setValue ("currentfontindex", fontComboBox->currentIndex());
+  qSettings.setValue ("currentpenwidth", penWidthSpinBox->value());
+  qSettings.setValue ("currentpointsize",fontSizeSpinBox->value());
+  qSettings.setValue ("fillcolor", scene->fillColor);
+  qSettings.setValue ("linecolor", scene->lineColor);
+  qSettings.setValue ("gradientcolor", scene->gradientColor);
+  qSettings.setValue ("canvasWidth",canvasWidth);
+  qSettings.setValue ("canvasHeight",canvasHeight);
+  qSettings.endGroup();
 }
 
 
 
 void editorView::slotArrow()
 {
-	
+
 }
 
 void editorView::slotRectangle()
 {
-	scene->setMode(editorScene::INSERT);
-	scene->setItemType(itemBase::RECTANGLE);
-	modified=true;
+  scene->setMode(editorScene::INSERT);
+  scene->setItemType(itemBase::RECTANGLE);
+  modified=true;
 }
 
 
 void editorView::slotCircle()
 {
-	scene->setMode(editorScene::INSERT);
-	scene->setItemType(itemBase::ELLIPSE);
-	modified=true;
+  scene->setMode(editorScene::INSERT);
+  scene->setItemType(itemBase::ELLIPSE);
+  modified=true;
 }
 
 void editorView::slotText()
 {
-	QDialog d(this);
-	Ui::textForm t;
-	t.setupUi(&d);
-	t.lineEdit->setText(txt);
-	if(d.exec()==QDialog::Accepted)
-		{
-			scene->setMode(editorScene::INSERT);
-			scene->setItemType(itemBase::TEXT);
-			scene->text=t.lineEdit->text();
-			txt=t.lineEdit->text();
+  QDialog d(this);
+  Ui::textForm t;
+  t.setupUi(&d);
+  t.plainTextEdit->setPlainText(txt);
+  if(d.exec()==QDialog::Accepted)
+    {
+      scene->setMode(editorScene::INSERT);
+      scene->setItemType(itemBase::TEXT);
+      scene->text=t.plainTextEdit->toPlainText();
+      txt=t.plainTextEdit->toPlainText();
       scene->apply(editorScene::DTEXT);
-		}
-	modified=true;
+    }
+  modified=true;
 }
 
 void editorView::slotLine()
 {
-	scene->setMode(editorScene::INSERT);
-	scene->setItemType(itemBase::LINE);
-	modified=true;
+  scene->setMode(editorScene::INSERT);
+  scene->setItemType(itemBase::LINE);
+  modified=true;
 }
 
 void editorView::slotColorPicker()
 {
-	int tp;
+  int tp;
   colorPickImage=scene->renderImage(0,0);
   addToLog(QString("colorpicker triggered size %1 x %2").arg(colorPickImage->width()).arg(colorPickImage->height()),LOGEDIT);
-	QAction *act;
-	act=qobject_cast<QAction *>(sender());
-	tp=act->data().toInt();
-	if (tp==TBFILL)
-			{
-				pickMode=PICKFILLCOLOR;
-				
-			}
-	else if (tp==TBLINE)
-			{
-				pickMode=PICKLINECOLOR;
-			}
-	scene->setMode(editorScene::PICK);
-	//setCursor(Qt::ArrowCursor);
+  QAction *act;
+  act=qobject_cast<QAction *>(sender());
+  tp=act->data().toInt();
+  if (tp==TBFILL)
+    {
+      pickMode=PICKFILLCOLOR;
+
+    }
+  else if (tp==TBLINE)
+    {
+      pickMode=PICKLINECOLOR;
+    }
+  scene->setMode(editorScene::PICK);
+  //setCursor(Qt::ArrowCursor);
 }
 
 void editorView::slotColorPicked(const QPointF &p)
 {
-	QRgb c=colorPickImage->pixel(p.x(),p.y());
+  QRgb c=colorPickImage->pixel(p.x(),p.y());
   addToLog(QString("Picked color r=%1,g=%2,b=%3 alpha=%4").arg(qRed(c)).arg(qGreen(c)).arg(qBlue(c)).arg(qAlpha(c)),LOGEDIT);
-	if(pickMode==PICKFILLCOLOR)
-		{
-			scene->fillColor.setRgba(c);
-			fillToolButton->setIcon(createColorToolButtonIcon(":/icons/colorfill.png",scene->fillColor));
-		}
-	else
-		{
-			scene->lineColor.setRgba(c);
-			lineToolButton->setIcon(createColorToolButtonIcon(":/icons/colorline.png",scene->lineColor));
-		}
-	canvas->setCursor(Qt::ArrowCursor);
+  if(pickMode==PICKFILLCOLOR)
+    {
+      scene->fillColor.setRgba(c);
+      fillToolButton->setIcon(createColorToolButtonIcon(":/icons/colorfill.png",scene->fillColor));
+    }
+  else
+    {
+      scene->lineColor.setRgba(c);
+      lineToolButton->setIcon(createColorToolButtonIcon(":/icons/colorline.png",scene->lineColor));
+    }
+  canvas->setCursor(Qt::ArrowCursor);
 }
 
 
 void editorView::slotImage()
 {
-	QString fileName;
-    dirDialog dd((QWidget *)this,"editor");
-	scene->fl=dd.openFileName(QString());
-	scene->setMode(editorScene::INSERT);
-	scene->setItemType(itemBase::IMAGE);
-	modified=true;
+  QString fileName;
+  dirDialog dd((QWidget *)this,"editor");
+  scene->fl=dd.openFileName(QString());
+  scene->setMode(editorScene::INSERT);
+  scene->setItemType(itemBase::IMAGE);
+  modified=true;
 }
 
 void editorView::slotReplay()
 {
-	scene->setMode(editorScene::INSERT);
-	scene->setItemType(itemBase::REPLAY);
-	modified=true;
+  scene->setMode(editorScene::INSERT);
+  scene->setItemType(itemBase::REPLAY);
+  modified=true;
 }
 
-//void editorView::slotChangeCanvasSize(int w,int h)
-//{
-
-//	canvas->setSceneRect(0,0,w,h);
-//	border->setRect(0,0,w,h);
-//	scene->border=border->rect();
-//	modified=true;
-//}
-
-
-void editorView::slotChangeCanvasSize(int index)
+void editorView::changeCanvasSize()
 {
   rotateDial->setValue(0);
   hshearSlider->setValue(0);
   vshearSlider->setValue(0);
   setTransform();
-  scene->addBorder(canvasSizeArray[index].width,canvasSizeArray[index].height);
-  canvas->setSceneRect(0,0,canvasSizeArray[index].width,canvasSizeArray[index].height);
+  scene->addBorder(canvasWidth,canvasHeight);
+  canvas->setSceneRect(0,0,canvasWidth,canvasHeight);
   modified=true;
 }
 
+
+void editorView::slotChangeCanvasSize()
+{
+  QRect r;
+  canvasSizeForm csize;
+  csize.setSize(canvasWidth,canvasHeight);
+  if(csize.exec()==QDialog::Accepted)
+    {
+      r=csize.getSize();
+      canvasWidth=r.width();
+      canvasHeight=r.height();
+      changeCanvasSize();
+    }
+}
+
 void editorView::slotFontChanged(const QFont &f)
 {
-	scene->font=f;
-	scene->font.setPointSize(fontSizeSpinBox->value());
-	scene->font.setBold(boldButton->isChecked());
-	scene->font.setItalic(italicButton->isChecked());
-	scene->font.setUnderline(underlineButton->isChecked());
+  scene->font=f;
+  scene->font.setPointSize(fontSizeSpinBox->value());
+  scene->font.setBold(boldButton->isChecked());
+  scene->font.setItalic(italicButton->isChecked());
+  scene->font.setUnderline(underlineButton->isChecked());
   scene->apply(editorScene::DFONT);
-	modified=true;
+  modified=true;
 }
 
 void editorView::slotFontSizeChanged(int sz)
 {
-	scene->font.setPointSize(sz);
+  scene->font.setPointSize(sz);
   scene->apply(editorScene::DFONT);
-	modified=true;
+  modified=true;
 }
 
 void editorView::slotPenWidthChanged(double pw)
 {
-	scene->penWidth=pw;
+  scene->penWidth=pw;
   scene->apply(editorScene::DPEN);
-	modified=true;
+  modified=true;
 }
 void editorView::slotBold(bool b)
 {
-	scene->font.setBold(b);
+  scene->font.setBold(b);
   scene->apply(editorScene::DFONT);
-	modified=true;
+  modified=true;
 }
 void editorView::slotItalic(bool b)
 {
-	scene->font.setItalic(b);
+  scene->font.setItalic(b);
   scene->apply(editorScene::DFONT);
-	modified=true;
+  modified=true;
 }
 void editorView::slotUnderline(bool b)
 {
-	scene->font.setUnderline(b);
+  scene->font.setUnderline(b);
   scene->apply(editorScene::DFONT);
-	modified=true;
+  modified=true;
 }
 
 /*! \todo image insert
-		check if this is used 
+    check if this is used
 */
 void editorView::setImage(QImage *)
 {
-	
-	scene->setMode(editorScene::INSERT);
-	scene->setItemType(itemBase::IMAGE);
-	modified=true;
+
+  scene->setMode(editorScene::INSERT);
+  scene->setItemType(itemBase::IMAGE);
+  modified=true;
 }
 
 
 void editorView::slotClearAll()
 {
-	scene->clearAll();
+  scene->clearAll();
 }
 
 
 void editorView::slotButtonTriggered()
 {
-	QToolButton *act;
-	act=qobject_cast<QToolButton *>(sender());
-		if (act==fillToolButton)
-			{
-        scene->apply(editorScene::DFILLCOLOR);
-			}
-		else if (act==lineToolButton)
-			{
-        scene->apply(editorScene::DLINECOLOR);
-			}
-		else if (act==gradientToolButton)
-			{
-        scene->apply(editorScene::DGRADIENT);
-			}
-		else
-			{
-				return;
-			}
+  QToolButton *act;
+  act=qobject_cast<QToolButton *>(sender());
+  if (act==fillToolButton)
+    {
+      scene->apply(editorScene::DFILLCOLOR);
+    }
+  else if (act==lineToolButton)
+    {
+      scene->apply(editorScene::DLINECOLOR);
+    }
+  else if (act==gradientToolButton)
+    {
+      scene->apply(editorScene::DGRADIENT);
+    }
+  else
+    {
+      return;
+    }
 }
 
 void editorView::slotColorDialog()
 {
   int tp;
-	QAction *act;
-	QColor c;
+  QAction *act;
+  QColor c;
   act=qobject_cast<QAction *>(sender());
-	tp=act->data().toInt();
-	switch(tp)
-		{
-			case TBFILL:
-        c=QColorDialog::getColor(scene->fillColor,this,"",QColorDialog::ShowAlphaChannel);
-        if (c.isValid())
-          {
-            scene->fillColor=c;
-            fillToolButton->setIcon(createColorToolButtonIcon(":/icons/colorfill.png",scene->fillColor));
-					}
-				break;
-				case TBLINE:
-        c=QColorDialog::getColor(scene->lineColor,this,"",QColorDialog::ShowAlphaChannel);
-        if (c.isValid())
-          {
-            scene->lineColor=c;
-            lineToolButton->setIcon(createColorToolButtonIcon(":/icons/colorline.png",scene->lineColor));
-          }
-				break;
-				default:
-					qDebug() << "Error in slotColorDialog";
-				break;
-		}
+  tp=act->data().toInt();
+  switch(tp)
+    {
+    case TBFILL:
+      c=QColorDialog::getColor(scene->fillColor,this,"",QColorDialog::ShowAlphaChannel);
+      if (c.isValid())
+        {
+          scene->fillColor=c;
+          fillToolButton->setIcon(createColorToolButtonIcon(":/icons/colorfill.png",scene->fillColor));
+        }
+    break;
+    case TBLINE:
+      c=QColorDialog::getColor(scene->lineColor,this,"",QColorDialog::ShowAlphaChannel);
+      if (c.isValid())
+        {
+          scene->lineColor=c;
+          lineToolButton->setIcon(createColorToolButtonIcon(":/icons/colorline.png",scene->lineColor));
+        }
+    break;
+    default:
+    break;
+    }
 }
 
 void editorView::slotGradientDialog()
 {
-	gradientDialog gDiag(this);
-	gDiag.selectGradient();
+  gradientDialog gDiag(this);
+  gDiag.selectGradient();
 }
 
 void editorView::save(QFile &f,bool templ)
 {
-	scene->save(f,templ);
+  scene->save(f,templ);
   modified=false;
 }
 
 bool editorView::open(QFile &f)
 {
-	if(!scene->load(f)) return false;
-  slotDump();
-	return true;
+  if(!scene->load(f)) return false;
+  canvasWidth=scene->border.width();
+  canvasHeight=scene->border.height();
+  changeCanvasSize();
+#ifndef QT_NO_DEBUG
+  dump();
+#endif
+  return true;
 }
 
 
 void editorView::setTransform()
 {
-//	int r=450-rotateDial->value();
-//	if ( r >= 360 )	r-=360;
-	int r=rotateDial->value();
-	scene->rotate=r;
-	scene->hShear=(double)hshearSlider->value()/10.;
-	scene->vShear=(double)vshearSlider->value()/10.;
+  //	int r=450-rotateDial->value();
+  //	if ( r >= 360 )	r-=360;
+  int r=rotateDial->value();
+  scene->rotate=r;
+  scene->hShear=(double)hshearSlider->value()/10.;
+  scene->vShear=(double)vshearSlider->value()/10.;
   scene->apply(editorScene::DTRANSFORM);
 }
 
@@ -483,48 +502,48 @@ void editorView::setTransform()
 */
 void editorView::slotTextReturnPressed(const QString &)
 {
-	
+
 }
 
 
 void editorView::slotRotateChanged(int)
 {
-	QString tmp;
-//	int r=450-rotateDial->value();
-//	if ( r >= 360 )	r-=360;
-	int r=rotateDial->value();
-	tmp.sprintf( "%3i'", r );
-	rotateLCD->display( tmp );
-	setTransform();
+  QString tmp;
+  //	int r=450-rotateDial->value();
+  //	if ( r >= 360 )	r-=360;
+  int r=rotateDial->value();
+  tmp.sprintf( "%3i'", r );
+  rotateLCD->display( tmp );
+  setTransform();
 }
 
 void editorView::slotShearChanged(int)
 {
-	QString tmp;
-	double shearVal;
-	QSlider *sl;
-	sl=qobject_cast<QSlider *>(sender());
-	shearVal=((double)sl->value())/10;
-	tmp.sprintf( "%1.3f", shearVal  );
-	if ( shearVal >= 0 )
-	tmp.insert( 0, " " );
-	if(sl==hshearSlider)
-		{
-			hshearLCD->display( tmp );
-		}
-	else
-		{
-			vshearLCD->display( tmp );
-		}
-	setTransform();
+  QString tmp;
+  double shearVal;
+  QSlider *sl;
+  sl=qobject_cast<QSlider *>(sender());
+  shearVal=((double)sl->value())/10;
+  tmp.sprintf( "%1.3f", shearVal  );
+  if ( shearVal >= 0 )
+    tmp.insert( 0, " " );
+  if(sl==hshearSlider)
+    {
+      hshearLCD->display( tmp );
+    }
+  else
+    {
+      vshearLCD->display( tmp );
+    }
+  setTransform();
 }
 
 QIcon editorView::createColorToolButtonIcon(const QString &imageFile, QColor color)
 {
-	QPixmap pixmap(22, 30);
-	pixmap.fill(Qt::transparent);
-	QPainter painter(&pixmap);
-	QPixmap image(imageFile);
+  QPixmap pixmap(22, 30);
+  pixmap.fill(Qt::transparent);
+  QPainter painter(&pixmap);
+  QPixmap image(imageFile);
   QRect target(0, 0, 22, 22);
   QRect source(0, 0, 22, 22);
   painter.fillRect(QRect(0, 22, 22, 8), color);
@@ -534,79 +553,79 @@ QIcon editorView::createColorToolButtonIcon(const QString &imageFile, QColor col
 
 QMenu *editorView::createColorMenu(const char * slot,int type,QString text)
 {
-    QMenu *colorMenu = new QMenu;
-		QAction *action = new QAction(text, this);
-		action->setData(type);
-    connect(action, SIGNAL(triggered()),this,slot);
-		colorMenu->addAction(action);
-    return colorMenu;
+  QMenu *colorMenu = new QMenu;
+  QAction *action = new QAction(text, this);
+  action->setData(type);
+  connect(action, SIGNAL(triggered()),this,slot);
+  colorMenu->addAction(action);
+  return colorMenu;
 }
 
 void editorView::slotItemSelected(itemBase* ib)
 {
-	sitemParam p;
-	p=ib->getParam();
-	if(p.type==itemBase::TEXT)
-		{
-			fontComboBox->setCurrentFont(p.font);
-			fontSizeSpinBox->setValue(p.font.pointSize());
-			boldButton->setChecked(p.font.bold());
-			underlineButton->setChecked(p.font.underline());
-			italicButton->setChecked(p.font.italic());
-		}
-	penWidthSpinBox->setValue(p.pen.widthF());
-//	int rot=p.rotation-450;
-//	if ( rot <0)
-//	rot+= 360;
-	int rot=p.rotation;
-	rotateDial->setValue(rot);
-	hshearSlider->setValue((int)(p.hShear*10));
-	vshearSlider->setValue((int)(p.vShear*10));
-}
-
-void editorView::slotDump()
-{
-	QString t;
-	int i;
-	QList<QGraphicsItem *> l=scene->items();
-	itemBase *b;
+  sitemParam p;
+  p=ib->getParam();
+  if(p.type==itemBase::TEXT)
+    {
+      boldButton->setChecked(p.font.bold());
+      underlineButton->setChecked(p.font.underline());
+      italicButton->setChecked(p.font.italic());
+      fontComboBox->setCurrentFont(p.font);
+      fontSizeSpinBox->setValue(p.font.pointSize());
+    }
+  penWidthSpinBox->setValue(p.pen.widthF());
+  int rot=p.rotation;
+  rotateDial->setValue(rot);
+  hshearSlider->setValue((int)(p.hShear*10));
+  vshearSlider->setValue((int)(p.vShear*10));
+}
+
+
+#ifndef QT_NO_DEBUG
+void editorView::dump()
+{
+  QString t;
+  int i;
+  QList<QGraphicsItem *> l=scene->items();
+  itemBase *b;
   addToLog(QString("dump editorView of items: %1").arg(l.count()),LOGEDIT); //exclude border
-	for(i=0;i<l.count();i++)
-		{
-//      if(l.at(i)->type()>=itemBase::BASE)
-				{
-					b=qgraphicsitem_cast<itemBase *>(l.at(i));
-					switch((int)b->type())
-						{
-							case itemBase::TEXT:
-									t="Text:";
-							break;
-							case itemBase::LINE:
-								t="Line:";
-							break;
-							case itemBase::IMAGE:
-									t="Image:";
-							break;
-							case itemBase::RECTANGLE:
-                t="Rectangle:";
-							break;
-							case itemBase::ELLIPSE:
-                t="Ellipse:";
-							break;
-              case itemBase::SBORDER:
-                t="Border:";
-              break;
-							default:
-                t=QString("Ill: %1").arg(l.at(i)->type());
-							break;
-						}
-          addToLog(QString("editorViewItems %1 pos=%2,%3 rectxy=%4,%5 size=%6x%7 depth=%8")
-                       .arg(t)
-                       .arg(b->pos().x()).arg(b->pos().y())
-                       .arg(b->rect().x()).arg(b->rect().y())
-                       .arg(b->rect().width()).arg(b->rect().height())
-                       .arg(b->zValue()),LOGEDIT);
-        }
+  for(i=0;i<l.count();i++)
+    {
+      //      if(l.at(i)->type()>=itemBase::BASE)
+      {
+        b=qgraphicsitem_cast<itemBase *>(l.at(i));
+        switch((int)b->type())
+          {
+          case itemBase::TEXT:
+            t="Text:";
+          break;
+          case itemBase::LINE:
+            t="Line:";
+          break;
+          case itemBase::IMAGE:
+            t="Image:";
+          break;
+          case itemBase::RECTANGLE:
+            t="Rectangle:";
+          break;
+          case itemBase::ELLIPSE:
+            t="Ellipse:";
+          break;
+          case itemBase::SBORDER:
+            t="Border:";
+          break;
+          default:
+            t=QString("Ill: %1").arg(l.at(i)->type());
+          break;
+          }
+        addToLog(QString("editorViewItems %1 pos=%2,%3 rectxy=%4,%5 size=%6x%7 depth=%8")
+                 .arg(t)
+                 .arg(b->pos().x()).arg(b->pos().y())
+                 .arg(b->rect().x()).arg(b->rect().y())
+                 .arg(b->rect().width()).arg(b->rect().height())
+                 .arg(b->zValue()),LOGEDIT);
       }
-		
+    }
+
 }
+#endif
diff --git a/qsstv/editor/editorview.h b/qsstv/editor/editorview.h
index 1dfaebf..46ab452 100644
--- a/qsstv/editor/editorview.h
+++ b/qsstv/editor/editorview.h
@@ -53,9 +53,7 @@ public:
 	editorScene *getScene() {return scene;}
 
 public slots:
-	void slotChangeCanvasSize(int);
-//	void slotChangeCanvasSize(int w,int h);
-// paint actions
+  void slotChangeCanvasSize();
 	void slotArrow();
 	void slotRectangle();
 	void slotCircle();
@@ -87,7 +85,7 @@ public slots:
 //item feedback
 	void slotItemSelected(itemBase*);
 //Debug
-	void slotDump();
+
 	void slotTextReturnPressed(const QString &);
 private:
 	editorScene *scene;
@@ -103,6 +101,10 @@ private:
 	QString txt;
 	QImage *colorPickImage;
 	ePickMode pickMode;
+  int canvasWidth;
+  int canvasHeight;
+  void changeCanvasSize();
+  void dump();
 };
 
 #endif
diff --git a/qsstv/editor/gradientdialog.cpp b/qsstv/editor/gradientdialog.cpp
index 9466d0c..232da9e 100644
--- a/qsstv/editor/gradientdialog.cpp
+++ b/qsstv/editor/gradientdialog.cpp
@@ -19,7 +19,7 @@
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 #include "gradientdialog.h"
-#include "qsstvdefs.h"
+#include "appdefs.h"
 #include <QColorDialog>
 
 
diff --git a/qsstv/editor/graphicitems.cpp b/qsstv/editor/graphicitems.cpp
index 01ef871..f0f64f2 100644
--- a/qsstv/editor/graphicitems.cpp
+++ b/qsstv/editor/graphicitems.cpp
@@ -19,130 +19,132 @@
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 #include "graphicitems.h"
-#include "qsstvglobal.h"
+#include "appglobal.h"
 #include "editorscene.h"
 
 /*!
-	
+
 */
 static QPainterPath qt_graphicsItem_shapeFromPath(const QPainterPath &path, const QPen &pen)
 {
-    // We unfortunately need this hack as QPainterPathStroker will set a width of 1.0
-    // if we pass a value of 0.0 to QPainterPathStroker::setWidth()
-    const qreal penWidthZero = qreal(0.00000001);
-
-    if (path == QPainterPath()) return path;
-    QPainterPathStroker ps;
-    ps.setCapStyle(pen.capStyle());
-    if (pen.widthF() <= 0.0) ps.setWidth(penWidthZero);
-    else  ps.setWidth(pen.widthF());
-    ps.setJoinStyle(pen.joinStyle());
-    ps.setMiterLimit(pen.miterLimit());
-    QPainterPath p = ps.createStroke(path);
-    p.addPath(path);
-    return p;
+  // We unfortunately need this hack as QPainterPathStroker will set a width of 1.0
+  // if we pass a value of 0.0 to QPainterPathStroker::setWidth()
+  const qreal penWidthZero = qreal(0.00000001);
+
+  if (path == QPainterPath()) return path;
+  QPainterPathStroker ps;
+  ps.setCapStyle(pen.capStyle());
+  if (pen.widthF() <= 0.0) ps.setWidth(penWidthZero);
+  else  ps.setWidth(pen.widthF());
+  ps.setJoinStyle(pen.joinStyle());
+  ps.setMiterLimit(pen.miterLimit());
+  QPainterPath p = ps.createStroke(path);
+  p.addPath(path);
+  return p;
 }
 
 
 itemBase::itemBase(QMenu *cntxtMenu)
 {
-	setFlags(QGraphicsItem::ItemIsSelectable|QGraphicsItem::ItemIsMovable);
-	setAcceptHoverEvents (true);
-	param.locked=false;
-	param.modified=true;
-	param.menu=cntxtMenu;
+  setFlags(QGraphicsItem::ItemIsSelectable|QGraphicsItem::ItemIsMovable);
+  setAcceptHoverEvents (true);
+  param.locked=false;
+  param.modified=true;
+  param.menu=cntxtMenu;
 }
 
 void itemBase::highlightSelected(QPainter *painter,const QStyleOptionGraphicsItem *option)
 {
 
-///	qreal itemPenWidth = pen().widthF();
-//		const qreal pad = itemPenWidth / 2;
-//	const qreal pad = itemPenWidth;
-	const qreal penWidth = 0; // cosmetic pen
-	const QColor fgcolor = option->palette.windowText().color();
-	const QColor bgcolor( // ensure good contrast against fgcolor
-		fgcolor.red()   > 127 ? 0 : 255,
-		fgcolor.green() > 127 ? 0 : 255,
-		fgcolor.blue()  > 127 ? 0 : 255);
-	painter->setPen(QPen(bgcolor, penWidth, Qt::SolidLine));
-	painter->setPen(QPen(option->palette.windowText(), 0, Qt::DashLine));
-	painter->setBrush(Qt::NoBrush);
-	painter->drawRect(boundingRect());
-//	painter->drawRect(boundingRect().adjusted(pad, pad, -pad, -pad));
+  ///	qreal itemPenWidth = pen().widthF();
+  //		const qreal pad = itemPenWidth / 2;
+  //	const qreal pad = itemPenWidth;
+  const qreal penWidth = 0; // cosmetic pen
+  const QColor fgcolor = option->palette.windowText().color();
+  const QColor bgcolor( // ensure good contrast against fgcolor
+                        fgcolor.red()   > 127 ? 0 : 255,
+                        fgcolor.green() > 127 ? 0 : 255,
+                        fgcolor.blue()  > 127 ? 0 : 255);
+  painter->setPen(QPen(bgcolor, penWidth, Qt::SolidLine));
+  painter->setPen(QPen(option->palette.windowText(), 0, Qt::DashLine));
+  painter->setBrush(Qt::NoBrush);
+  painter->drawRect(boundingRect());
+  //	painter->drawRect(boundingRect().adjusted(pad, pad, -pad, -pad));
 }
 
 QPainterPath itemBase::shape() const
 {
-	QPainterPath path;
-	path.addRect(param.rct);
-	return qt_graphicsItem_shapeFromPath(path,pen());
+  QPainterPath path;
+  path.addRect(param.rct);
+  return qt_graphicsItem_shapeFromPath(path,pen());
 }
 
 void itemBase::setBrush(QColor c)
 {
-	param.fillColor=c;
-	QAbstractGraphicsShapeItem::setBrush(param.fillColor);
+  param.fillColor=c;
+  QAbstractGraphicsShapeItem::setBrush(param.fillColor);
 }
 
 void itemBase::load(QDataStream &str)
 {
-//	str << type(); this item is already read by the loader
-	QTransform f;
-	QPointF p;
-	QRectF r;
-	QColor c;
-	QPen pn;
-	QBrush br;
-	QString t;
-	QFont fnt;
-	qreal z;
-	str >> param.rotation;
-	str >> param.hShear,
-	str >> param.vShear;
-	str >> z;
-	setZValue(z);
+  //	str << type(); this item is already read by the loader
+  QTransform f;
+  QPointF p;
+  QRectF r;
+  QColor c;
+  QPen pn;
+  QBrush br;
+  QString t;
+  QFont fnt;
+  qreal z;
+  str >> param.rotation;
+  str >> param.hShear;
+  str >> param.vShear;
+  str >> z;
+  setZValue(z);
   param.zValue=z;
-	str >> p;
-	setPos(p);
-	str >> r;
-	setRect(r);
-	str >> c;
-	param.fillColor=c;
-	setBrush(c);
-	str >> pn;
-	setPen(pn);
-	str >> br;
-	QAbstractGraphicsShapeItem::setBrush(br);
-	str >> param.locked;
-	str >>param.im;
-	str >>t;
-	setText(t);
-	str >>fnt;
-	setFont(fnt);
-	str >> param.line;
-	param.gradient.load(str);
+  str >> p;
+  setPos(p);
+  param.position=p;
+  str >> r;
+  setRect(r);
+  str >> c;
+  param.fillColor=c;
+  setBrush(c);
+  str >> pn;
+  setPen(pn);
+  str >> br;
+  QAbstractGraphicsShapeItem::setBrush(br);
+  str >> param.locked;
+  str >>param.im;
+  str >>t;
+  setText(t);
+  str >>fnt;
+  setFont(fnt);
+  str >> param.line;
+  param.gradient.load(str);
   setTransform ();
- }
+}
 
 void itemBase::save(QDataStream &str)
 {
-	str << type();
-	str << param.rotation;
-	str << param.hShear,
-	str << param.vShear;
-	str	<< zValue();
-	str << pos();
-	str << rect();
-	str << param.fillColor;
-	str << pen();
-	str << brush();
-	str << param.locked;
-	str << param.im;
-	str << param.txt;
-	str << param.font;
-	str << param.line;
-	param.gradient.save(str);
+  str << type();
+  str << param.rotation;
+  str << param.hShear;
+  str << param.vShear;
+  str	<< zValue();
+  str << pos();
+  str << rect();
+  str << param.fillColor;
+  str << pen();
+  str << brush();
+  str << param.locked;
+  str << param.im;
+  str << param.txt;
+  str << param.font;
+  str << param.line;
+  param.gradient.save(str);
+
 
 }
 
@@ -161,46 +163,48 @@ void itemBase::setTransform ( int rot,double hs,double vs)
 {
   param.rotation=rot;
   param.hShear=hs;
-	param.vShear=vs;
+  param.vShear=vs;
   setTransform ();
 }
 
 void itemBase::hoverMoveEvent ( QGraphicsSceneHoverEvent * event )
 {
-	if(((editorScene*)scene())->mode==editorScene::PICK)
-		{
-			setCursor(*cpCursor);
- 			return;
-		}
-	if(((editorScene*)scene())->mode==editorScene::INSERT)
-		{
-			setCursor(Qt::ArrowCursor);
- 			return;
-		}
-
-
-	if(param.locked)
-		{
-			grab = NO;
-		 	setCursor(Qt::ForbiddenCursor);
-		}
-	else if(type()!=LINE)
-		{
-			grab = getCorner(event->pos());
-			if(type()==TEXT) grab=NO;
-			if ((grab == CUL)|| (grab == CDR)) setCursor(Qt::SizeFDiagCursor);
-			if ((grab == CUR)|| (grab == CDL)) setCursor(Qt::SizeBDiagCursor);
-			if ((grab == HU) || (grab == HD))  setCursor(Qt::SizeVerCursor);
-			if ((grab == VL) || (grab == VR))  setCursor(Qt::SizeHorCursor);
-			if (grab == NO) setCursor(Qt::OpenHandCursor);
-		}
-	else
-		{
-				grab=NO;
-				setCursor(Qt::CrossCursor);
-		}
-	//QAbstractGraphicsShapeItem::hoverEnterEvent(event);
-	QAbstractGraphicsShapeItem::hoverMoveEvent(event);
+  if(((editorScene*)scene())->mode==editorScene::PICK)
+    {
+      QPixmap pm(":/icons/colorpicker.png");
+      QCursor cpCursor(pm,0,pm.height()-1);
+      setCursor(cpCursor);
+      return;
+    }
+  if(((editorScene*)scene())->mode==editorScene::INSERT)
+    {
+      setCursor(Qt::ArrowCursor);
+      return;
+    }
+
+
+  if(param.locked)
+    {
+      grab = NO;
+      setCursor(Qt::ForbiddenCursor);
+    }
+  else if(type()!=LINE)
+    {
+      grab = getCorner(event->pos());
+      if(type()==TEXT) grab=NO;
+      if ((grab == CUL)|| (grab == CDR)) setCursor(Qt::SizeFDiagCursor);
+      if ((grab == CUR)|| (grab == CDL)) setCursor(Qt::SizeBDiagCursor);
+      if ((grab == HU) || (grab == HD))  setCursor(Qt::SizeVerCursor);
+      if ((grab == VL) || (grab == VR))  setCursor(Qt::SizeHorCursor);
+      if (grab == NO) setCursor(Qt::OpenHandCursor);
+    }
+  else
+    {
+      grab=NO;
+      setCursor(Qt::CrossCursor);
+    }
+  //QAbstractGraphicsShapeItem::hoverEnterEvent(event);
+  QAbstractGraphicsShapeItem::hoverMoveEvent(event);
 }
 
 
@@ -208,112 +212,112 @@ void itemBase::hoverMoveEvent ( QGraphicsSceneHoverEvent * event )
 
 itemBase::corner itemBase::getCorner( QPointF mouse)
 {
-	double x = rect().x();
-	double y = rect().y();
-	double h = rect().height();
-	double w = rect().width();
-
-	double diff;
-	diff=w; if (diff>h) diff=h;
-	diff/=10;
-	if (diff>10) diff=10;
-	else if (diff<1) diff=1;
-
-	QRectF cul (x,y, diff,diff);
-	QRectF cur (x+w-diff,y, diff,diff);
-	QRectF cdl (x,y+h-diff,diff,diff);
-	QRectF cdr (x+w-diff,y+h-diff,diff,diff);
-
-	QRectF hu (x+diff,y,w-(2*diff),diff);
-	QRectF hd (x+diff,y+h-diff,w-(2*diff),diff);
-	QRectF vl (x,y+diff,diff,h-(2*diff));
-	QRectF vr (x+w-diff,y+diff,diff,h-(2*diff));
-
-	if ( cul.contains(mouse) ) return CUL;
-	if ( cur.contains(mouse) ) return CUR;
-	if ( cdl.contains(mouse) ) return CDL;
-	if ( cdr.contains(mouse) ) return CDR;
-	if ( hu.contains(mouse) ) return HU;
-	if ( hd.contains(mouse) ) return HD;
-	if ( vl.contains(mouse) ) return VL;
-	if ( vr.contains(mouse) ) return VR;
-
-return NO;
+  double x = rect().x();
+  double y = rect().y();
+  double h = rect().height();
+  double w = rect().width();
+
+  double diff;
+  diff=w; if (diff>h) diff=h;
+  diff/=10;
+  if (diff>10) diff=10;
+  else if (diff<1) diff=1;
+
+  QRectF cul (x,y, diff,diff);
+  QRectF cur (x+w-diff,y, diff,diff);
+  QRectF cdl (x,y+h-diff,diff,diff);
+  QRectF cdr (x+w-diff,y+h-diff,diff,diff);
+
+  QRectF hu (x+diff,y,w-(2*diff),diff);
+  QRectF hd (x+diff,y+h-diff,w-(2*diff),diff);
+  QRectF vl (x,y+diff,diff,h-(2*diff));
+  QRectF vr (x+w-diff,y+diff,diff,h-(2*diff));
+
+  if ( cul.contains(mouse) ) return CUL;
+  if ( cur.contains(mouse) ) return CUR;
+  if ( cdl.contains(mouse) ) return CDL;
+  if ( cdr.contains(mouse) ) return CDR;
+  if ( hu.contains(mouse) ) return HU;
+  if ( hd.contains(mouse) ) return HD;
+  if ( vl.contains(mouse) ) return VL;
+  if ( vr.contains(mouse) ) return VR;
+
+  return NO;
 }
 
 
 void itemBase::mouseMoveEvent ( QGraphicsSceneMouseEvent * event )
 {
-	if(((editorScene*)scene())->mode==editorScene::PICK) return;
-	if(((editorScene*)scene())->mode==editorScene::INSERT) return;
-	if(param.locked) return;
-	QPointF mouse = event->pos();
-//resize!
-	prepareGeometryChange();
-	param.modified=true;
-	switch ( grab)
-		{
-			case NO : QAbstractGraphicsShapeItem::mouseMoveEvent(event);
-	  	break;
-			case HD :
-				if(mouse.y()-rect().y()>1)
-				setRect(rect().x(),rect().y(),rect().width(),mouse.y()-rect().y());
-		  break;
-			case HU :
-				if(rect().height()+(rect().y()-mouse.y())>0)
-				 setRect(rect().x(),mouse.y(),rect().width(),rect().height()+(rect().y()-mouse.y()));
-			break;
-			case VR :
-				if(mouse.x()-rect().x()>1)
-				setRect(rect().x(),rect().y(),mouse.x()-rect().x(),rect().height());
-			break;
-			case VL :
-				if(rect().width()+(rect().x()-mouse.x())>1)
- 				setRect(mouse.x(),rect().y(),rect().width()+(rect().x()-mouse.x()),rect().height());
-			break;
-			case CDR :
-				if(((mouse.x()-rect().x())>1)&&((mouse.y()-rect().y())>1))
-				setRect(rect().x(),rect().y(),mouse.x()-rect().x(),mouse.y()-rect().y());
-			break; 
-			case CUR :
-				if(((mouse.x()-rect().x())>1)&&((rect().height()+(rect().y()-mouse.y()))>1))
-				setRect(rect().x(),mouse.y(),mouse.x()-rect().x(),rect().height()+(rect().y()-mouse.y()));
-			break;
-			case CDL :
-				if(((rect().width()+(rect().x()-mouse.x()))>1)&&((mouse.y()-rect().y())>1))
-				setRect(mouse.x(),rect().y(),rect().width()+(rect().x()-mouse.x()),mouse.y()-rect().y());
-			break; 
-			case CUL :
-				if(((rect().width()+(rect().x()-mouse.x()))>1)&&((rect().height()+(rect().y()-mouse.y()))>1))
-				setRect(mouse.x(),mouse.y(),rect().width()+(rect().x()-mouse.x()),rect().height()+(rect().y()-mouse.y()));
-			break; 
-		}
-	update();
-}
-
- QString itemBase::getTypeStr()
- {
-   QString tp;
-   switch(type())
+  if(((editorScene*)scene())->mode==editorScene::PICK) return;
+  if(((editorScene*)scene())->mode==editorScene::INSERT) return;
+  if(param.locked) return;
+  QPointF mouse = event->pos();
+  //resize!
+  prepareGeometryChange();
+  param.modified=true;
+  switch ( grab)
+    {
+    case NO : QAbstractGraphicsShapeItem::mouseMoveEvent(event);
+    break;
+    case HD :
+      if(mouse.y()-rect().y()>1)
+        setRect(rect().x(),rect().y(),rect().width(),mouse.y()-rect().y());
+    break;
+    case HU :
+      if(rect().height()+(rect().y()-mouse.y())>0)
+        setRect(rect().x(),mouse.y(),rect().width(),rect().height()+(rect().y()-mouse.y()));
+    break;
+    case VR :
+      if(mouse.x()-rect().x()>1)
+        setRect(rect().x(),rect().y(),mouse.x()-rect().x(),rect().height());
+    break;
+    case VL :
+      if(rect().width()+(rect().x()-mouse.x())>1)
+        setRect(mouse.x(),rect().y(),rect().width()+(rect().x()-mouse.x()),rect().height());
+    break;
+    case CDR :
+      if(((mouse.x()-rect().x())>1)&&((mouse.y()-rect().y())>1))
+        setRect(rect().x(),rect().y(),mouse.x()-rect().x(),mouse.y()-rect().y());
+    break;
+    case CUR :
+      if(((mouse.x()-rect().x())>1)&&((rect().height()+(rect().y()-mouse.y()))>1))
+        setRect(rect().x(),mouse.y(),mouse.x()-rect().x(),rect().height()+(rect().y()-mouse.y()));
+    break;
+    case CDL :
+      if(((rect().width()+(rect().x()-mouse.x()))>1)&&((mouse.y()-rect().y())>1))
+        setRect(mouse.x(),rect().y(),rect().width()+(rect().x()-mouse.x()),mouse.y()-rect().y());
+    break;
+    case CUL :
+      if(((rect().width()+(rect().x()-mouse.x()))>1)&&((rect().height()+(rect().y()-mouse.y()))>1))
+        setRect(mouse.x(),mouse.y(),rect().width()+(rect().x()-mouse.x()),rect().height()+(rect().y()-mouse.y()));
+    break;
+    }
+  update();
+}
+
+QString itemBase::getTypeStr()
+{
+  QString tp;
+  switch(type())
     {
-      case BASE: tp="Base"; break;
-      case RECTANGLE: tp="Rectangle";  break;
-      case ELLIPSE: tp="Ellipse"; break;
-      case IMAGE: tp="Image";  break;
-      case LINE: tp="Line";  break;
-      case TEXT: tp="Text"; break;
-      case REPLAY: tp="Replay";  break;
-      case SBORDER: tp="SBorder";  break;
+    case BASE: tp="Base"; break;
+    case RECTANGLE: tp="Rectangle";  break;
+    case ELLIPSE: tp="Ellipse"; break;
+    case IMAGE: tp="Image";  break;
+    case LINE: tp="Line";  break;
+    case TEXT: tp="Text"; break;
+    case REPLAY: tp="Replay";  break;
+    case SBORDER: tp="SBorder";  break;
     }
-   return tp;
- }
+  return tp;
+}
 
 
 void itemBase::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
 {
-	if(((editorScene*)scene())->mode==editorScene::PICK) return;
-	setSelected(true);
-	param.menu->exec(event->screenPos());
+  if(((editorScene*)scene())->mode==editorScene::PICK) return;
+  setSelected(true);
+  param.menu->exec(event->screenPos());
 }
 
 
@@ -321,11 +325,11 @@ void itemBase::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
 
 itemText::itemText(QMenu *cntxtMenu): itemBase(cntxtMenu)
 {
-	  param.font.setFamily("Times");
-		param.font.setPointSize(24);
-    param.font.setStyleStrategy(QFont::ForceOutline);
-		setFlags(QGraphicsItem::ItemIsSelectable|QGraphicsItem::ItemIsMovable);
-		setAcceptHoverEvents (true);
+  param.font.setFamily("Times");
+  param.font.setPointSize(24);
+  param.font.setStyleStrategy(QFont::ForceOutline);
+  setFlags(QGraphicsItem::ItemIsSelectable|QGraphicsItem::ItemIsMovable);
+  setAcceptHoverEvents (true);
 }
 
 itemText::~itemText()
@@ -335,116 +339,150 @@ itemText::~itemText()
 
 void itemText::setText(const QString &t)
 {
-	QPainterPath tt;
-	prepareGeometryChange();
-	param.modified=true;
-	param.txt=t;
-	tt.addText(0, 0, param.font, param.txt);
-	param.rct=tt.controlPointRect();
-	update();
+  //  QPainterPath tt;
+  //  prepareGeometryChange();
+  param.modified=true;
+  param.txt=t;
+  //  tt.addText(0, 0, param.font, param.txt);
+  //  param.rct=tt.controlPointRect();
+  update();
 }
 
 void itemText::setFont(QFont f)
 {
-	QPainterPath tt;
-	prepareGeometryChange();
-	param.modified=true;
-	param.font=f;
-	param.font.setStyleStrategy(QFont::ForceOutline);
-	tt.addText(0, 0, param.font, param.txt);
-	param.rct=tt.controlPointRect();
-	update();
+  //  QPainterPath tt;
+  //  prepareGeometryChange();
+  param.modified=true;
+  param.font=f;
+  param.font.setStyleStrategy(QFont::ForceOutline);
+  //  tt.addText(0, 0, param.font, param.txt);
+  //  param.rct=tt.controlPointRect();
+  update();
 }
 
-//QRectF itemText::boundingRect() const
-//{
-//	qreal d=pen().widthF();
-//	QPainterPath tt;
-//	tt.addText(0, 0, param.font, param.txt);
-//	return tt.controlPointRect().adjusted(-d/2,-d/2,d/2,d/2);
-//}
+
+static QRectF setupTextLayout(QTextLayout *layout)
+{
+  layout->setCacheEnabled(true);
+  layout->beginLayout();
+  while (layout->createLine().isValid())
+    ;
+  layout->endLayout();
+  qreal maxWidth = 0;
+  qreal y = 0;
+  for (int i = 0; i < layout->lineCount(); ++i) {
+      QTextLine line = layout->lineAt(i);
+      maxWidth = qMax(maxWidth, line.naturalTextWidth());
+      line.setPosition(QPointF(0, y));
+      y += line.height();
+    }
+  return QRectF(0, 0, maxWidth, y);
+}
 
 void itemText::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *)
 {
-	QPainterPath tt;
-	tt.addText(0, 0, param.font, param.txt);
-	if (param.modified)
-		{
-			param.modified=false;
-			if(param.gradient.type!=sgradientParam::NONE) 
-				{
-					QAbstractGraphicsShapeItem::setBrush(buildGradient(param.gradient,rect()));
-				}
-			else
-				{
-					QAbstractGraphicsShapeItem::setBrush(param.fillColor);
-				}
-		}
-	painter->setPen(pen());
-	painter->setBrush(brush());
-	painter->setFont(param.font);
-	painter->drawPath(tt);
-	if (option->state & QStyle::State_Selected)  highlightSelected(painter,option);
+  QPainterPath tt;
+  QString tmp=param.txt;
+  tmp.replace(QLatin1Char('\n'), QChar::LineSeparator);
+  QTextLayout layout(tmp, param.font);
+
+  QPen p;
+  if (param.modified)
+    {
+      param.modified=false;
+      if(param.gradient.type!=sgradientParam::NONE)
+        {
+          QAbstractGraphicsShapeItem::setBrush(buildGradient(param.gradient,rect()));
+        }
+      else
+        {
+          QAbstractGraphicsShapeItem::setBrush(param.fillColor);
+        }
+    }
+  p.setBrush(brush());
+  painter->setPen(p);
+  QTextLayout::FormatRange range;
+  range.start = 0;
+  range.length = layout.text().length();
+  range.format.setTextOutline(pen());
+  QList<QTextLayout::FormatRange> formats;
+  formats.append(range);
+  layout.setAdditionalFormats(formats);
+  param.rct=setupTextLayout(&layout);
+  layout.draw(painter, QPointF(0, 0));
+  if (option->state & QStyle::State_Selected)  highlightSelected(painter,option);
 }
 
 
+
+
+
+
+
+
+
+
+
+
+
+
 itemRectangle::itemRectangle(QMenu *cntxtMenu): itemBase(cntxtMenu)
 {
-	setRect(0,0,100,100);
-	setFlags(QGraphicsItem::ItemIsSelectable|QGraphicsItem::ItemIsMovable);
+  setRect(0,0,100,100);
+  setFlags(QGraphicsItem::ItemIsSelectable|QGraphicsItem::ItemIsMovable);
 }
 
 
 
 void itemRectangle::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *)
 {
-//	if (resized ) prepareGeometryChange();
-	if (param.modified)
-		{
-			param.modified=false;
-			if(param.gradient.type!=sgradientParam::NONE) 
-				{
-					QAbstractGraphicsShapeItem::setBrush(buildGradient(param.gradient,rect()));
-				}
-			else
-				{
-					QAbstractGraphicsShapeItem::setBrush(param.fillColor);
-				}
-		}
-	painter->setPen(pen());
-	painter->setBrush(brush());
-	painter->drawRect(param.rct);
-	if (option->state & QStyle::State_Selected)  highlightSelected(painter,option);
+  //	if (resized ) prepareGeometryChange();
+  if (param.modified)
+    {
+      param.modified=false;
+      if(param.gradient.type!=sgradientParam::NONE)
+        {
+          QAbstractGraphicsShapeItem::setBrush(buildGradient(param.gradient,rect()));
+        }
+      else
+        {
+          QAbstractGraphicsShapeItem::setBrush(param.fillColor);
+        }
+    }
+  painter->setPen(pen());
+  painter->setBrush(brush());
+  painter->drawRect(param.rct);
+  if (option->state & QStyle::State_Selected)  highlightSelected(painter,option);
 }
 
 
 itemEllipse::itemEllipse(QMenu *cntxtMenu): itemBase(cntxtMenu)
 {
-	setRect(0,0,100,100);
-	setFlags(QGraphicsItem::ItemIsSelectable|QGraphicsItem::ItemIsMovable);
+  setRect(0,0,100,100);
+  setFlags(QGraphicsItem::ItemIsSelectable|QGraphicsItem::ItemIsMovable);
 }
 
 
 
 void itemEllipse::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *)
 {
-//	if(resized) prepareGeometryChange();
-		if (param.modified)
-		{
-			param.modified=false;
-			if(param.gradient.type!=sgradientParam::NONE) 
-				{
-					QAbstractGraphicsShapeItem::setBrush(buildGradient(param.gradient,rect()));
-				}
-			else
-				{
-					QAbstractGraphicsShapeItem::setBrush(param.fillColor);
-				}
-		}
-	painter->setPen(pen());
-	painter->setBrush(brush());
-	painter->drawEllipse(param.rct);
-	if (option->state & QStyle::State_Selected)  highlightSelected(painter,option);
+  //	if(resized) prepareGeometryChange();
+  if (param.modified)
+    {
+      param.modified=false;
+      if(param.gradient.type!=sgradientParam::NONE)
+        {
+          QAbstractGraphicsShapeItem::setBrush(buildGradient(param.gradient,rect()));
+        }
+      else
+        {
+          QAbstractGraphicsShapeItem::setBrush(param.fillColor);
+        }
+    }
+  painter->setPen(pen());
+  painter->setBrush(brush());
+  painter->drawEllipse(param.rct);
+  if (option->state & QStyle::State_Selected)  highlightSelected(painter,option);
 }
 
 
@@ -452,8 +490,8 @@ void itemEllipse::paint(QPainter *painter, const QStyleOptionGraphicsItem *optio
 
 itemImage::itemImage(QMenu *cntxtMenu): itemBase(cntxtMenu)
 {
-	setRect(0,0,100,100);
-	setFlags(QGraphicsItem::ItemIsSelectable|QGraphicsItem::ItemIsMovable);
+  setRect(0,0,100,100);
+  setFlags(QGraphicsItem::ItemIsSelectable|QGraphicsItem::ItemIsMovable);
 }
 
 
@@ -462,79 +500,79 @@ void itemImage::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
 {
   QImage tim;
   tim=param.im.scaled(param.rct.width(),param.rct.height(),Qt::IgnoreAspectRatio,Qt::SmoothTransformation);
-	qreal pad=pen().widthF()/2;
+  qreal pad=pen().widthF()/2;
   painter->drawImage(param.rct.adjusted(pad,pad,-pad,-pad),tim);
-	painter->setBrush(Qt::NoBrush);
-	painter->setPen(pen());
+  painter->setBrush(Qt::NoBrush);
+  painter->setPen(pen());
   //painter->drawRect(param.rct);
-	if (option->state & QStyle::State_Selected)  highlightSelected(painter,option);
+  if (option->state & QStyle::State_Selected)  highlightSelected(painter,option);
 }
 
 
 itemLine::itemLine(QMenu *cntxtMenu): itemBase(cntxtMenu)
 {
-//	setRect(0,0,100,100);
-	
-	param.line.setPoints(QPoint(0,0),QPoint(100,0));
-	setFlags(QGraphicsItem::ItemIsSelectable|QGraphicsItem::ItemIsMovable);
+  //	setRect(0,0,100,100);
+
+  param.line.setPoints(QPoint(0,0),QPoint(100,0));
+  setFlags(QGraphicsItem::ItemIsSelectable|QGraphicsItem::ItemIsMovable);
 }
 
 QPainterPath itemLine::shape() const
 
 {
-	QPainterPath path;
-	if (param.line.isNull()) return path;
+  QPainterPath path;
+  if (param.line.isNull()) return path;
   path.moveTo(param.line.p1());
   path.lineTo(param.line.p2());
-	return qt_graphicsItem_shapeFromPath(path,pen());
+  return qt_graphicsItem_shapeFromPath(path,pen());
 }
 
 
 QRectF itemLine::boundingRect() const
 {
-	if (pen().widthF() == 0.0)
-		{
-        const qreal x1 = param.line.p1().x();
-        const qreal x2 = param.line.p2().x();
-        const qreal y1 = param.line.p1().y();
-        const qreal y2 = param.line.p2().y();
-        qreal lx = qMin(x1, x2);
-        qreal rx = qMax(x1, x2);
-        qreal ty = qMin(y1, y2);
-        qreal by = qMax(y1, y2);
-        return QRectF(lx, ty, rx - lx, by - ty);
+  if (pen().widthF() == 0.0)
+    {
+      const qreal x1 = param.line.p1().x();
+      const qreal x2 = param.line.p2().x();
+      const qreal y1 = param.line.p1().y();
+      const qreal y2 = param.line.p2().y();
+      qreal lx = qMin(x1, x2);
+      qreal rx = qMax(x1, x2);
+      qreal ty = qMin(y1, y2);
+      qreal by = qMax(y1, y2);
+      return QRectF(lx, ty, rx - lx, by - ty);
     }
-	return shape().controlPointRect();
+  return shape().controlPointRect();
 }
 
 void itemLine::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *)
 {
-//	if (resized ) prepareGeometryChange();
-	painter->setPen(pen());
-	painter->setBrush(brush());
-	painter->drawLine(param.line);
-	if (option->state & QStyle::State_Selected)
-//  highlightSelected(painter,option);
-	{
-		const qreal penWidth = 0; // cosmetic pen 
-		const QColor fgcolor = option->palette.windowText().color();
-		const QColor bgcolor( // ensure good contrast against fgcolor
-			fgcolor.red()   > 127 ? 0 : 255,
-			fgcolor.green() > 127 ? 0 : 255,
-			fgcolor.blue()  > 127 ? 0 : 255);
-		painter->setPen(QPen(bgcolor, penWidth, Qt::SolidLine));
-		painter->setBrush(Qt::NoBrush);
-		painter->strokePath(shape(),QPen(bgcolor, penWidth, Qt::SolidLine));
-		painter->setPen(QPen(option->palette.windowText(), 0, Qt::DashLine));
-		painter->setBrush(Qt::NoBrush);
-		painter->strokePath(shape(),QPen(option->palette.windowText(), 0, Qt::DashLine));
-	}
+  //	if (resized ) prepareGeometryChange();
+  painter->setPen(pen());
+  painter->setBrush(brush());
+  painter->drawLine(param.line);
+  if (option->state & QStyle::State_Selected)
+    //  highlightSelected(painter,option);
+    {
+      const qreal penWidth = 0; // cosmetic pen
+      const QColor fgcolor = option->palette.windowText().color();
+      const QColor bgcolor( // ensure good contrast against fgcolor
+                            fgcolor.red()   > 127 ? 0 : 255,
+                            fgcolor.green() > 127 ? 0 : 255,
+                            fgcolor.blue()  > 127 ? 0 : 255);
+      painter->setPen(QPen(bgcolor, penWidth, Qt::SolidLine));
+      painter->setBrush(Qt::NoBrush);
+      painter->strokePath(shape(),QPen(bgcolor, penWidth, Qt::SolidLine));
+      painter->setPen(QPen(option->palette.windowText(), 0, Qt::DashLine));
+      painter->setBrush(Qt::NoBrush);
+      painter->strokePath(shape(),QPen(option->palette.windowText(), 0, Qt::DashLine));
+    }
 }
 
 itemReplayImage::itemReplayImage(QMenu *cntxtMenu): itemBase(cntxtMenu)
 {
-	setRect(0,0,100,100);
-	setFlags(QGraphicsItem::ItemIsSelectable|QGraphicsItem::ItemIsMovable);
+  setRect(0,0,100,100);
+  setFlags(QGraphicsItem::ItemIsSelectable|QGraphicsItem::ItemIsMovable);
 }
 
 
@@ -552,13 +590,13 @@ void itemReplayImage::paint(QPainter *painter, const QStyleOptionGraphicsItem *o
   else
     {
       tim=param.im.scaled(param.rct.width(),param.rct.height(),Qt::IgnoreAspectRatio,Qt::SmoothTransformation);
-    qreal pad=pen().widthF()/2;
-//    painter->drawImage(param.rct.adjusted(pad,pad,-pad,-pad), param.im, param.im.rect());
-    painter->drawImage(param.rct.adjusted(pad,pad,-pad,-pad), tim);
-    painter->setBrush(Qt::NoBrush);
-    painter->setPen(pen());
+      qreal pad=pen().widthF()/2;
+      //    painter->drawImage(param.rct.adjusted(pad,pad,-pad,-pad), param.im, param.im.rect());
+      painter->drawImage(param.rct.adjusted(pad,pad,-pad,-pad), tim);
+      painter->setBrush(Qt::NoBrush);
+      painter->setPen(pen());
     }
-	if (option->state & QStyle::State_Selected)  highlightSelected(painter,option);
+  if (option->state & QStyle::State_Selected)  highlightSelected(painter,option);
 }
 
 
@@ -572,7 +610,7 @@ itemBorder::itemBorder(QMenu *cntxtMenu): itemBase(cntxtMenu)
 
 void itemBorder::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *)
 {
-//	if (resized ) prepareGeometryChange();
+  //	if (resized ) prepareGeometryChange();
   if (param.modified)
     {
       param.modified=false;
diff --git a/qsstv/editor/graphicitems.h b/qsstv/editor/graphicitems.h
index 9777504..14d6ff9 100644
--- a/qsstv/editor/graphicitems.h
+++ b/qsstv/editor/graphicitems.h
@@ -24,9 +24,9 @@
 #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
 #include <QtWidgets>
 #endif
-
+#include "appdefs.h"
 #include "gradientdialog.h"
-#include "qsstvdefs.h"
+
 
 
 struct sitemParam
@@ -135,6 +135,10 @@ private:
 	corner grab;
 };
 
+
+
+
+
 class itemText : public itemBase
 {
 public:
@@ -145,7 +149,7 @@ public:
 	void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget);
   //QRectF boundingRect() const;
 	int type() const {return  TEXT;}
-  void hover(){;}
+//  void hover(){;}
 };
 
 
diff --git a/qsstv/editor/textform.ui b/qsstv/editor/textform.ui
index 958089f..b44a476 100644
--- a/qsstv/editor/textform.ui
+++ b/qsstv/editor/textform.ui
@@ -1,7 +1,8 @@
-<ui version="4.0" >
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
  <class>textForm</class>
- <widget class="QDialog" name="textForm" >
-  <property name="geometry" >
+ <widget class="QDialog" name="textForm">
+  <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
@@ -9,31 +10,31 @@
     <height>103</height>
    </rect>
   </property>
-  <property name="windowTitle" >
+  <property name="windowTitle">
    <string>Enter text</string>
   </property>
-  <layout class="QVBoxLayout" name="verticalLayout" >
+  <layout class="QVBoxLayout" name="verticalLayout">
    <item>
-    <widget class="QLineEdit" name="lineEdit" />
+    <widget class="QPlainTextEdit" name="plainTextEdit"/>
    </item>
    <item>
-    <layout class="QHBoxLayout" name="horizontalLayout" >
+    <layout class="QHBoxLayout" name="horizontalLayout">
      <item>
-      <widget class="QDialogButtonBox" name="buttonBox" >
-       <property name="orientation" >
+      <widget class="QDialogButtonBox" name="buttonBox">
+       <property name="orientation">
         <enum>Qt::Horizontal</enum>
        </property>
-       <property name="standardButtons" >
+       <property name="standardButtons">
         <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
        </property>
       </widget>
      </item>
      <item>
-      <spacer name="horizontalSpacer" >
-       <property name="orientation" >
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
         <enum>Qt::Horizontal</enum>
        </property>
-       <property name="sizeHint" stdset="0" >
+       <property name="sizeHint" stdset="0">
         <size>
          <width>40</width>
          <height>20</height>
@@ -44,11 +45,11 @@
     </layout>
    </item>
    <item>
-    <spacer name="verticalSpacer" >
-     <property name="orientation" >
+    <spacer name="verticalSpacer">
+     <property name="orientation">
       <enum>Qt::Vertical</enum>
      </property>
-     <property name="sizeHint" stdset="0" >
+     <property name="sizeHint" stdset="0">
       <size>
        <width>20</width>
        <height>19</height>
@@ -66,11 +67,11 @@
    <receiver>textForm</receiver>
    <slot>accept()</slot>
    <hints>
-    <hint type="sourcelabel" >
+    <hint type="sourcelabel">
      <x>248</x>
      <y>254</y>
     </hint>
-    <hint type="destinationlabel" >
+    <hint type="destinationlabel">
      <x>157</x>
      <y>274</y>
     </hint>
@@ -82,11 +83,11 @@
    <receiver>textForm</receiver>
    <slot>reject()</slot>
    <hints>
-    <hint type="sourcelabel" >
+    <hint type="sourcelabel">
      <x>316</x>
      <y>260</y>
     </hint>
-    <hint type="destinationlabel" >
+    <hint type="destinationlabel">
      <x>286</x>
      <y>274</y>
     </hint>
diff --git a/qsstv/gallerywidget.cpp b/qsstv/gallerywidget.cpp
deleted file mode 100644
index 7d7dac8..0000000
--- a/qsstv/gallerywidget.cpp
+++ /dev/null
@@ -1,320 +0,0 @@
-#include "gallerywidget.h"
-#include "ui_gallerywidget.h"
-#include "utils/logging.h"
-#include "qsstvglobal.h"
-#include <QSplashScreen>
-#include "dispatcher.h"
-#include <QFileInfo>
-#include <QStatusBar>
-#include "txwidget.h"
-
-galleryWidget *galleryWidgetPtr;
-
-galleryWidget::galleryWidget(QWidget *parent) :
-    QWidget(parent),
-    ui(new Ui::galleryWidget)
-{
-    ui->setupUi(this);
-    ui->tabWidget->setCurrentIndex(0);
-}
-
-galleryWidget::~galleryWidget()
-{
-  writeSettings(false);
-  addToLog ("deleting galleryWidget",LOGGALLERY);
-    delete ui;
-  addToLog ("ui deleted: galleryWidget",LOGGALLERY);
-}
-
-
-
-
-void galleryWidget::init()
-{
-  initView();
-  readSettings();
-}
-
-/*!
-  reads the settings (saved images for tx,rx,templates)
-*/
-
-void galleryWidget::readSettings()
-{
-  int i;
-  QSettings qSettings;
-  qSettings.beginGroup ("Gallery");
-  rxIndex=qSettings.value( "rxIndex",0 ).toInt();
-  qSettings.endGroup();
-  splashStr+=QString( "Loading RX images" ).rightJustified(25,' ')+"\n";
-  splashPtr->showMessage ( splashStr ,Qt::AlignLeft,Qt::white);
-  qApp->processEvents();
-  for ( i=0;i<NUMTHUMBS;i++ )
-  {
-    rxThumbsArray[i]->readThumbSettings ( &qSettings );
-  }
-  splashStr+=QString( "Loading TX images" ).rightJustified(25,' ')+"\n";
-  splashPtr->showMessage ( splashStr ,Qt::AlignLeft,Qt::white);
-  qApp->processEvents();
-  for ( i=0;i<NUMTHUMBS;i++ )
-  {
-    txThumbsArray[i]->readThumbSettings ( &qSettings );
-  }
-  splashStr+=QString( "Loading Templates" ).rightJustified(25,' ')+"\n";
-  splashPtr->showMessage ( splashStr ,Qt::AlignLeft,Qt::white);
-  qApp->processEvents();
-  for ( i=0;i<NUMTHUMBS;i++ )
-  {
-    qApp->processEvents();
-    templateThumbsArray[i]->readThumbSettings ( &qSettings );
-  }
-  slotLayoutChanged();
-}
-
-/*!
-  writes the settings (saved images for tx,rx,templates)
-*/
-void galleryWidget::writeSettings(bool onlyRx)
-{
-    int i;
-    QSettings qSettings;
-    qSettings.beginGroup ( "Gallery" );
-    qSettings.setValue ( "rxIndex",rxIndex );
-    qSettings.endGroup();
-    for ( i=0;i<NUMTHUMBS;i++ )
-    {
-        rxThumbsArray[i]->writeThumbSettings ( &qSettings );
-        if(!onlyRx)
-        {
-            txThumbsArray[i]->writeThumbSettings ( &qSettings );
-            templateThumbsArray[i]->writeThumbSettings ( &qSettings );
-        }
-    }
-}
-
-/*!
-  setup of the user interface
-*/
-
-void galleryWidget::initView()
-{
-  #define MINCOLSIZE 32
-  #define MINROWSIZE 26
-  #define MAXCOLSIZE 64
-  #define MAXROWSIZE 52
-  int i;
-  rxThumbsArray[0]= ui->rximage1;
-  rxThumbsArray[1]= ui->rximage2;
-  rxThumbsArray[2]= ui->rximage3;
-  rxThumbsArray[3]= ui->rximage4;
-  rxThumbsArray[4]= ui->rximage5;
-  rxThumbsArray[5]= ui->rximage6;
-  rxThumbsArray[6]= ui->rximage7;
-  rxThumbsArray[7]= ui->rximage8;
-  rxThumbsArray[8]= ui->rximage9;
-  rxThumbsArray[9]= ui->rximage10;
-  rxThumbsArray[10]=ui->rximage11;
-  rxThumbsArray[11]=ui->rximage12;
-
-  txThumbsArray[0]= ui->tximage1;
-  txThumbsArray[1]= ui->tximage2;
-  txThumbsArray[2]= ui->tximage3;
-  txThumbsArray[3]= ui->tximage4;
-  txThumbsArray[4]= ui->tximage5;
-  txThumbsArray[5]= ui->tximage6;
-  txThumbsArray[6]= ui->tximage7;
-  txThumbsArray[7]= ui->tximage8;
-  txThumbsArray[8]= ui->tximage9;
-  txThumbsArray[9]= ui->tximage10;
-  txThumbsArray[10]=ui->tximage11;
-  txThumbsArray[11]=ui->tximage12;
-
-  templateThumbsArray[0]= ui->tmpimage1;
-  templateThumbsArray[1]= ui->tmpimage2;
-  templateThumbsArray[2]= ui->tmpimage3;
-  templateThumbsArray[3]= ui->tmpimage4;
-  templateThumbsArray[4]= ui->tmpimage5;
-  templateThumbsArray[5]= ui->tmpimage6;
-  templateThumbsArray[6]= ui->tmpimage7;
-  templateThumbsArray[7]= ui->tmpimage8;
-  templateThumbsArray[8]= ui->tmpimage9;
-  templateThumbsArray[9]= ui->tmpimage10;
-  templateThumbsArray[10]=ui->tmpimage11;
-  templateThumbsArray[11]=ui->tmpimage12;
-  for ( i=0;i<NUMTHUMBS;i++ )
-  {
-    rxThumbsArray[i]->setType ( imageViewer::RXTHUMB );
-    txThumbsArray[i]->setType ( imageViewer::TXTHUMB );
-    templateThumbsArray[i]->setType ( imageViewer::TEMPLATETHUMB );
-    connect( rxThumbsArray[i],SIGNAL(layoutChanged()),SLOT(slotLayoutChanged()));
-    connect( txThumbsArray[i],SIGNAL(layoutChanged()),SLOT(slotLayoutChanged()));
-    connect( templateThumbsArray[i],SIGNAL(layoutChanged()),SLOT(slotLayoutChanged()));
-  }
-  for (i=0;i<4;i++)
-    {
-      ui->gridLayout1->setColumnMinimumWidth(i,MINCOLSIZE);
-      ui->gridLayout1->setColumnStretch(i,1);
-      ui->gridLayout2->setColumnMinimumWidth(i,MINCOLSIZE);
-      ui->gridLayout2->setColumnStretch(i,1);
-      ui->gridLayout3->setColumnMinimumWidth(i,MINCOLSIZE);
-      ui->gridLayout3->setColumnStretch(i,1);
-    }
-  for (i=0;i<3;i++)
-    {
-      ui->gridLayout1->setRowMinimumHeight(i,MINROWSIZE);
-      ui->gridLayout1->setRowStretch(i,0);
-      ui->gridLayout2->setRowMinimumHeight(i,MINROWSIZE);
-      ui->gridLayout2->setRowStretch(i,0);
-      ui->gridLayout3->setRowMinimumHeight(i,MINROWSIZE);
-      ui->gridLayout3->setRowStretch(i,0);
-    }
-}
-
-/*!
-  closeEvent signals the dispatcher to initiate  program exit.
-*/
-
-
-/*!
-  get the filename of a template
-
-  \param[in] tm index of template
-  \return QString containing filename, check with QString.isNull for validity
-*/
-
-QString galleryWidget::getTemplateFileName ( int tm )
-{
-  if ( tm<NUMTHUMBS )
-  {
-    return templateThumbsArray[tm]->getFilename();
-  }
-  return QString();
-}
-
- const QStringList &galleryWidget::getFilenames()
- {
-   QString str;
-   sl.clear();
-
-   int i;
-   for(i=0;i<NUMTHUMBS;i++)
-   {
-     str=getTemplateFileName (i);
-     if(!str.isEmpty())
-      {
-        QFileInfo fi(str);
-        sl.append(fi.baseName());
-      }
-     else
-     {
-       sl.append("Empty");
-     }
-   }
-   return sl;
- }
-
-/*!
-  loads an image in the rximages gallery in a new position
-
-  \param[in] fn the filename
-
-*/
-
-void galleryWidget::putRxImage ( QString fn )
-{
-  statusBarPtr->showMessage ( "Saved: "+fn );
-  shuffle(rxThumbsArray,rxIndex);
-//  cleanup(rxThumbsArray,imageViewer::RXTHUMB);
-  rxThumbsArray[rxIndex]->openImage(fn,false,false);
-  addToLog (QString("adding item %1 fn: %2").arg(rxIndex).arg(fn),LOGGALLERY);
-  if(rxIndex<NUMTHUMBS-1) rxIndex++;
-  writeSettings(true);
-}
-
-/*!
-  loads an image in the rximages gallery in a new position
-
-  \return QString containing filename, check with QString.isEmpty for validity
-
-*/
-QString galleryWidget::getLastRxImage()
-{
-  //rxIndex points to the first empty location;
-  int tmpIdx;
-  tmpIdx=rxIndex;
-  if(tmpIdx!=NUMTHUMBS-1) tmpIdx-=1;
-  if(tmpIdx<0) return QString::Null();
-  return rxThumbsArray[tmpIdx]->getFilename();
-}
-
-
-void galleryWidget::cleanup(imageViewer *array[],imageViewer::thumbType tp)
-{
-  int i,j;
-  bool found;
-  for(i=0;i<NUMTHUMBS-1;i++)
-    {
-      found=false;
-      if(array[i]->getFilename().isEmpty())
-        {
-           addToLog (QString("empty item %1").arg(i),LOGGALLERY);
-          array[i]->init(tp);
-
-          for(j=i+1;j<NUMTHUMBS;j++)
-            {
-              if(!array[j]->getFilename().isEmpty())
-                {
-                  array[i]->copy(array[j]);
-                  array[j]->init(tp);
-                  found=true;
-                  break;
-                }
-            }
-          if(!found) break;
-         }
-      else
-      {
-          addToLog (QString("item %1 fn: %2").arg(i).arg(array[i]->getFilename()),LOGGALLERY);
-      }
-    }
- }
-
-
-void galleryWidget::slotLayoutChanged()
-{
-  int i;
-  cleanup(rxThumbsArray,imageViewer::RXTHUMB);
-  cleanup(txThumbsArray,imageViewer::TXTHUMB);
-  cleanup(templateThumbsArray,imageViewer::TEMPLATETHUMB);
-  rxIndex=NUMTHUMBS-1;
-  for(i=0;i<NUMTHUMBS;i++)
-    {
-      if(rxThumbsArray[i]->getFilename().isEmpty())
-        {
-          rxIndex=i;
-          break;
-        }
-    }
-  txWidgetPtr->setupTemplatesComboBox();
-}
-
-void galleryWidget::shuffle(imageViewer *ar[],int index)
-{
-  int i,j;
-  if(ar[rxIndex]->getFilename().isEmpty()) return;
-  if(index>=NUMTHUMBS-1)
-    {
-      for(i=0,j=1;(i<(NUMTHUMBS-1))&&(j<NUMTHUMBS);j++)
-        {
-          if(!ar[j]->getFilename().isEmpty())
-          {
-            addToLog (QString("shuffling %1 fn: %2 to %3").arg(j).arg(ar[j]->getFilename()).arg(i),LOGGALLERY);
-            ar[i]->copy(ar[j]);
-            i++;
-          }
-        }
-      ar[j-1]->clear();
-    }
-
-
-}
diff --git a/qsstv/gallerywidget.ui b/qsstv/gallerywidget.ui
deleted file mode 100644
index 418b671..0000000
--- a/qsstv/gallerywidget.ui
+++ /dev/null
@@ -1,215 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>galleryWidget</class>
- <widget class="QWidget" name="galleryWidget">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>562</width>
-    <height>376</height>
-   </rect>
-  </property>
-  <property name="windowTitle">
-   <string>Form</string>
-  </property>
-  <layout class="QVBoxLayout" name="verticalLayout">
-   <property name="spacing">
-    <number>1</number>
-   </property>
-   <property name="margin">
-    <number>0</number>
-   </property>
-   <item>
-    <widget class="QTabWidget" name="tabWidget">
-     <property name="minimumSize">
-      <size>
-       <width>0</width>
-       <height>0</height>
-      </size>
-     </property>
-     <property name="font">
-      <font>
-       <pointsize>8</pointsize>
-      </font>
-     </property>
-     <property name="currentIndex">
-      <number>0</number>
-     </property>
-     <widget class="QWidget" name="rxtab">
-      <attribute name="title">
-       <string>RX</string>
-      </attribute>
-      <layout class="QHBoxLayout" name="horizontalLayout_3">
-       <property name="spacing">
-        <number>1</number>
-       </property>
-       <property name="margin">
-        <number>1</number>
-       </property>
-       <item>
-        <layout class="QGridLayout" name="gridLayout1" rowstretch="1,1,1" columnstretch="1,1,1,1">
-         <property name="sizeConstraint">
-          <enum>QLayout::SetNoConstraint</enum>
-         </property>
-         <item row="0" column="0">
-          <widget class="imageViewer" name="rximage1" native="true"/>
-         </item>
-         <item row="0" column="1">
-          <widget class="imageViewer" name="rximage2" native="true"/>
-         </item>
-         <item row="0" column="2">
-          <widget class="imageViewer" name="rximage3" native="true"/>
-         </item>
-         <item row="0" column="3">
-          <widget class="imageViewer" name="rximage4" native="true"/>
-         </item>
-         <item row="1" column="0">
-          <widget class="imageViewer" name="rximage5" native="true"/>
-         </item>
-         <item row="1" column="1">
-          <widget class="imageViewer" name="rximage6" native="true"/>
-         </item>
-         <item row="1" column="2">
-          <widget class="imageViewer" name="rximage7" native="true"/>
-         </item>
-         <item row="1" column="3">
-          <widget class="imageViewer" name="rximage8" native="true"/>
-         </item>
-         <item row="2" column="0">
-          <widget class="imageViewer" name="rximage9" native="true"/>
-         </item>
-         <item row="2" column="1">
-          <widget class="imageViewer" name="rximage10" native="true"/>
-         </item>
-         <item row="2" column="2">
-          <widget class="imageViewer" name="rximage11" native="true"/>
-         </item>
-         <item row="2" column="3">
-          <widget class="imageViewer" name="rximage12" native="true"/>
-         </item>
-        </layout>
-       </item>
-      </layout>
-     </widget>
-     <widget class="QWidget" name="txtab">
-      <attribute name="title">
-       <string>TX</string>
-      </attribute>
-      <layout class="QHBoxLayout" name="horizontalLayout_2">
-       <property name="spacing">
-        <number>1</number>
-       </property>
-       <property name="margin">
-        <number>1</number>
-       </property>
-       <item>
-        <layout class="QGridLayout" name="gridLayout2">
-         <item row="0" column="0">
-          <widget class="imageViewer" name="tximage1" native="true"/>
-         </item>
-         <item row="0" column="1">
-          <widget class="imageViewer" name="tximage2" native="true"/>
-         </item>
-         <item row="0" column="2">
-          <widget class="imageViewer" name="tximage3" native="true"/>
-         </item>
-         <item row="0" column="3">
-          <widget class="imageViewer" name="tximage4" native="true"/>
-         </item>
-         <item row="1" column="0">
-          <widget class="imageViewer" name="tximage5" native="true"/>
-         </item>
-         <item row="1" column="1">
-          <widget class="imageViewer" name="tximage6" native="true"/>
-         </item>
-         <item row="1" column="2">
-          <widget class="imageViewer" name="tximage7" native="true"/>
-         </item>
-         <item row="1" column="3">
-          <widget class="imageViewer" name="tximage8" native="true"/>
-         </item>
-         <item row="2" column="0">
-          <widget class="imageViewer" name="tximage9" native="true"/>
-         </item>
-         <item row="2" column="1">
-          <widget class="imageViewer" name="tximage10" native="true"/>
-         </item>
-         <item row="2" column="2">
-          <widget class="imageViewer" name="tximage11" native="true"/>
-         </item>
-         <item row="2" column="3">
-          <widget class="imageViewer" name="tximage12" native="true"/>
-         </item>
-        </layout>
-       </item>
-      </layout>
-     </widget>
-     <widget class="QWidget" name="templatetab">
-      <attribute name="title">
-       <string>Templates</string>
-      </attribute>
-      <layout class="QHBoxLayout" name="horizontalLayout">
-       <property name="spacing">
-        <number>1</number>
-       </property>
-       <property name="margin">
-        <number>1</number>
-       </property>
-       <item>
-        <layout class="QGridLayout" name="gridLayout3">
-         <item row="0" column="0">
-          <widget class="imageViewer" name="tmpimage1" native="true"/>
-         </item>
-         <item row="0" column="1">
-          <widget class="imageViewer" name="tmpimage2" native="true"/>
-         </item>
-         <item row="0" column="2">
-          <widget class="imageViewer" name="tmpimage3" native="true"/>
-         </item>
-         <item row="0" column="3">
-          <widget class="imageViewer" name="tmpimage4" native="true"/>
-         </item>
-         <item row="1" column="0">
-          <widget class="imageViewer" name="tmpimage5" native="true"/>
-         </item>
-         <item row="1" column="1">
-          <widget class="imageViewer" name="tmpimage6" native="true"/>
-         </item>
-         <item row="1" column="2">
-          <widget class="imageViewer" name="tmpimage7" native="true"/>
-         </item>
-         <item row="1" column="3">
-          <widget class="imageViewer" name="tmpimage8" native="true"/>
-         </item>
-         <item row="2" column="0">
-          <widget class="imageViewer" name="tmpimage9" native="true"/>
-         </item>
-         <item row="2" column="1">
-          <widget class="imageViewer" name="tmpimage10" native="true"/>
-         </item>
-         <item row="2" column="2">
-          <widget class="imageViewer" name="tmpimage11" native="true"/>
-         </item>
-         <item row="2" column="3">
-          <widget class="imageViewer" name="tmpimage12" native="true"/>
-         </item>
-        </layout>
-       </item>
-      </layout>
-     </widget>
-    </widget>
-   </item>
-  </layout>
- </widget>
- <customwidgets>
-  <customwidget>
-   <class>imageViewer</class>
-   <extends>QWidget</extends>
-   <header>widgets/imageviewer.h</header>
-   <container>1</container>
-  </customwidget>
- </customwidgets>
- <resources/>
- <connections/>
-</ui>
diff --git a/qsstv/icons/binary.png b/qsstv/icons/binary.png
new file mode 100644
index 0000000..eae4e50
Binary files /dev/null and b/qsstv/icons/binary.png differ
diff --git a/qsstv/icons/doubleleft.png b/qsstv/icons/doubleleft.png
new file mode 100644
index 0000000..c4162fe
Binary files /dev/null and b/qsstv/icons/doubleleft.png differ
diff --git a/qsstv/icons/doubleright.png b/qsstv/icons/doubleright.png
new file mode 100644
index 0000000..f57b483
Binary files /dev/null and b/qsstv/icons/doubleright.png differ
diff --git a/qsstv/icons/down.png b/qsstv/icons/down.png
new file mode 100644
index 0000000..ea9c00c
Binary files /dev/null and b/qsstv/icons/down.png differ
diff --git a/qsstv/icons/left.png b/qsstv/icons/left.png
new file mode 100644
index 0000000..ebb6521
Binary files /dev/null and b/qsstv/icons/left.png differ
diff --git a/qsstv/icons/up.png b/qsstv/icons/up.png
new file mode 100644
index 0000000..d6c2b99
Binary files /dev/null and b/qsstv/icons/up.png differ
diff --git a/qsstv/logbook/logbook.cpp b/qsstv/logbook/logbook.cpp
index 5c5c60f..dd14f86 100644
--- a/qsstv/logbook/logbook.cpp
+++ b/qsstv/logbook/logbook.cpp
@@ -1,5 +1,5 @@
 #include "logbook.h"
-#include "qsstvglobal.h"
+#include "appglobal.h"
 #include "xmlrpc/xmlinterface.h"
 #include "xmlrpc/ipcmessage.h"
 #include "configparams.h"
@@ -10,7 +10,7 @@
 
 slogParam logParamArray[NUMLOGPARAMS]=
 {
-  {"program","QSSTV 8"},
+    {"program","QSSTV 8"},
     {"version", "1"},
     {"date","" },
     {"time",""  },
@@ -47,7 +47,7 @@ logBook::logBook()
 }
 
 
-void logBook::logQSO(QString call,QString comment)
+void logBook::logQSO(QString call,QString mode,QString comment)
 {
   int i;
   QDateTime dt(QDateTime::currentDateTimeUtc());
@@ -60,10 +60,8 @@ void logBook::logQSO(QString call,QString comment)
   setParam(LDATE,tmp);
   tmp=QString::number(dt.time().hour()*100+dt.time().minute()).rightJustified(4,'0');
   setParam(LTIME,tmp);
-
- setParam(LENDTIME,tmp);
-//  setParam(LENDTIME,"");
-  setParam(LMODE,"SSTV");
+  setParam(LENDTIME,tmp);
+  setParam(LMODE,mode);
   setParam(LNOTES,comment);
   tmp.clear();
   for(i=0;i<NUMLOGPARAMS;i++)
@@ -79,18 +77,21 @@ void logBook::logQSO(QString call,QString comment)
 
 void logBook::getFrequency()
 {
+  frequency=-1;
 
-  if(rigController->params()->enableXMLRPC) // we get the frequency from flrig or alike
+  if(rigControllerPtr->params()->enableXMLRPC) // we get the frequency from flrig or alike
     {
       frequency=xmlIntfPtr->getFrequency();
     }
-  else if(rigController->params()->enableCAT) // we get the frequency from hamlib
+  else if(rigControllerPtr->params()->enableCAT) // we get the frequency from hamlib
     {
-      if(!rigController->getFrequency(frequency))
+      if(!rigControllerPtr->getFrequency(frequency))
         {
           frequency=-1;
         }
     }
+
+
 }
 
 void logBook::setParam(eIndex tag,QString value)
diff --git a/qsstv/logbook/logbook.h b/qsstv/logbook/logbook.h
index eba79f1..ca9d163 100644
--- a/qsstv/logbook/logbook.h
+++ b/qsstv/logbook/logbook.h
@@ -20,13 +20,12 @@ class logBook
 public:
   enum eIndex {LPROG,LVER,LDATE,LTIME,LENDTIME,LCALL,LFREQ,LMODE,LTX,LRX,LNAME,LQTH,LSTATE,LPROV,LCNTRY,LLOC,LSO,LSI,LFREE,LNOTES,LPWR};
   logBook();
-  void logQSO(QString call,QString comment);
+  void logQSO(QString call, QString mode, QString comment);
 private:
   void getFrequency();
   double frequency;
   void setParam(eIndex tag,QString value);
   ipcMessage *ipcQueue;
-
 };
 
 #endif // LOGBOOK_H
diff --git a/qsstv/main.cpp b/qsstv/main.cpp
index ace263f..779cae3 100644
--- a/qsstv/main.cpp
+++ b/qsstv/main.cpp
@@ -22,45 +22,43 @@
 #include <QApplication>
 
 #include <QtGui>
-//#include <QCDEStyle>
-#include "qsstvglobal.h"
+#include "appglobal.h"
 #include "mainwindow.h"
-#include "dsp/filterparam.h"
-#include "dsp/filter.h"
 #include <QPixmap>
 #include <QSplashScreen>
 #include <QTimer>
-
-QSplashScreen *splash;
+#include "dispatcher.h"
 
 
+QSplashScreen *splash;
 
 int main( int argc, char ** argv )
 {
-  int result=true;
+
+  int result;
   QTimer tm;
   tm.setSingleShot(true);
   QApplication::setColorSpec( QApplication::ManyColor );
-  QApplication app( argc, argv );
+
   QCoreApplication::setOrganizationName(ORGANIZATION);
   QCoreApplication::setApplicationName(APPLICATION);
+  QApplication app( argc, argv );
   QPixmap pixmap(":/icons/qsstvsplash.png");
   QSplashScreen splash(pixmap,Qt::WindowStaysOnTopHint);
-  splashPtr=&splash;
 
+  splashPtr=&splash;
+  splash.show();
   QFont f;
   f.setBold(true);
-  f.setPixelSize(18);
+  f.setPixelSize(20);
   splashPtr->setFont(f);
-  splash.show();
   splashStr="\n\n\n";
   splashStr+=QString( "Starting %1").arg(qsstvVersion).rightJustified(25,' ')+"\n";
   splash.showMessage (splashStr,Qt::AlignLeft,Qt::white);
-  tm.start(500);
+  tm.start(100);
   globalInit();
   mainWindowPtr=new mainWindow;
   mainWindowPtr->setWindowIcon(QPixmap(":/icons/qsstv.png"));
-
   while(1)
   {
     app.processEvents();
@@ -68,7 +66,7 @@ int main( int argc, char ** argv )
    }
   mainWindowPtr->init(); // this must follow show() because window has to be drawn first to determine fftframe window size
   mainWindowPtr->hide();
-  tm.start(3000);
+  tm.start(100);
   while(1)
   {
     app.processEvents();
@@ -76,7 +74,7 @@ int main( int argc, char ** argv )
    }
   splash.finish(mainWindowPtr);
   mainWindowPtr->show();
-  mainWindowPtr->startReceiving();
+  mainWindowPtr->startRunning();
   result=app.exec();
   globalEnd();
   return result;
diff --git a/qsstv/mainwidgets/gallerywidget.cpp b/qsstv/mainwidgets/gallerywidget.cpp
new file mode 100644
index 0000000..ba92472
--- /dev/null
+++ b/qsstv/mainwidgets/gallerywidget.cpp
@@ -0,0 +1,221 @@
+#include "gallerywidget.h"
+#include "ui_gallerywidget.h"
+#include "configparams.h"
+#include "utils/logging.h"
+#include "appglobal.h"
+#include <QSplashScreen>
+#include "dispatch/dispatcher.h"
+#include <QFileInfo>
+#include <QStatusBar>
+#include "txwidget.h"
+
+
+
+galleryWidget::galleryWidget(QWidget *parent) :
+  QWidget(parent),
+  ui(new Ui::galleryWidget)
+{
+  ui->setupUi(this);
+  ui->tabWidget->setCurrentIndex(0);
+  ui->templateMatrix->setSortFlag(QDir::Name);
+
+}
+
+galleryWidget::~galleryWidget()
+{
+  writeSettings();
+  delete ui;
+
+}
+
+
+
+
+void galleryWidget::init()
+{
+  readSettings();
+}
+
+
+void galleryWidget::changedMatrix()
+{
+  changedMatrix(imageViewer::RXSSTVTHUMB);
+  changedMatrix(imageViewer::RXDRMTHUMB);
+  changedMatrix(imageViewer::TXSSTVTHUMB);
+  changedMatrix(imageViewer::TXDRMTHUMB);
+  changedMatrix(imageViewer::TXSTOCKTHUMB);
+  changedMatrix(imageViewer::TEMPLATETHUMB);
+}
+
+
+void galleryWidget::changedMatrix(imageViewer::thumbType itype)
+{
+  switch(itype)
+    {
+    case imageViewer::RXSSTVTHUMB:
+      ui->rxSSTVMatrix->init(galleryRows,galleryColumns,rxSSTVImagesPath,imageViewer::RXSSTVTHUMB);
+      break;
+    case imageViewer::RXDRMTHUMB:
+      ui->rxDRMMatrix->init(galleryRows,galleryColumns,rxDRMImagesPath,imageViewer::RXDRMTHUMB);
+      break;
+    case imageViewer::TXSSTVTHUMB:
+      ui->txSSTVMatrix->init(galleryRows,galleryColumns,txSSTVImagesPath,imageViewer::TXSSTVTHUMB);
+      break;
+    case imageViewer::TXDRMTHUMB:
+      ui->txDRMMatrix->init(galleryRows,galleryColumns,txDRMImagesPath,imageViewer::TXDRMTHUMB);
+      break;
+    case imageViewer::TXSTOCKTHUMB:
+      ui->txStockMatrix->init(galleryRows,galleryColumns,txStockImagesPath,imageViewer::TXSTOCKTHUMB);
+      break;
+    case imageViewer::TEMPLATETHUMB:
+      ui->templateMatrix->init(galleryRows,galleryColumns,templatesPath,imageViewer::TEMPLATETHUMB);
+      break;
+    default:
+      break;
+    }
+}
+
+
+
+/*!
+  reads the settings (saved images for tx,rx,templates)
+*/
+
+void galleryWidget::readSettings()
+{
+  QSettings qSettings;
+  qSettings.beginGroup ("Gallery");
+
+  splashStr+=QString( "Loading RX images" ).rightJustified(25,' ')+"\n";
+  splashPtr->showMessage ( splashStr ,Qt::AlignLeft,Qt::white);
+  qApp->processEvents();
+  ui->rxSSTVMatrix->init(galleryRows,galleryColumns,rxSSTVImagesPath,imageViewer::RXSSTVTHUMB);
+  ui->rxDRMMatrix->init(galleryRows,galleryColumns,rxDRMImagesPath,imageViewer::RXDRMTHUMB);
+
+  splashStr+=QString( "Loading TX images" ).rightJustified(25,' ')+"\n";
+  splashPtr->showMessage ( splashStr ,Qt::AlignLeft,Qt::white);
+  qApp->processEvents();
+  ui->txSSTVMatrix->init(galleryRows,galleryColumns,txSSTVImagesPath,imageViewer::TXSSTVTHUMB);
+  ui->txDRMMatrix->init(galleryRows,galleryColumns,txDRMImagesPath,imageViewer::TXDRMTHUMB);
+  ui->txStockMatrix->init(galleryRows,galleryColumns,txStockImagesPath,imageViewer::TXSTOCKTHUMB);
+
+  splashStr+=QString( "Loading Templates" ).rightJustified(25,' ')+"\n";
+  splashPtr->showMessage ( splashStr ,Qt::AlignLeft,Qt::white);
+  ui->templateMatrix->init(galleryRows,galleryColumns,templatesPath,imageViewer::TEMPLATETHUMB);
+}
+
+/*!
+  writes the settings (saved images for tx,rx,templates)
+*/
+void galleryWidget::writeSettings()
+{
+  QSettings qSettings;
+  qSettings.beginGroup ( "Gallery" );
+  qSettings.endGroup();
+}
+
+/*!
+  setup of the user interface
+*/
+
+
+
+/*!
+  closeEvent signals the dispatcher to initiate  program exit.
+*/
+
+
+/*!
+  get the filename of a template
+
+  \param[in] tm index of template
+  \return QString containing filename, check with QString.isNull for validity
+*/
+
+QString galleryWidget::getTemplateFileName ( int tm )
+{
+  int i;
+  QString str;
+  QStringList slTemp;
+  if(tm>=0)
+    {
+      for(i=0;i<ui->templateMatrix->getFileList().count();i++)
+        {
+          str=ui->templateMatrix->getFileList().at(i).absoluteFilePath();
+          slTemp.append(str);
+        }
+      slTemp.sort();
+      return slTemp.at(tm);
+    }
+  else return QString();
+}
+
+const QStringList &galleryWidget::getFilenames()
+{
+  QString str;
+  sl.clear();
+  int i;
+  for(i=0;i<ui->templateMatrix->getFileList().count();i++)
+    {
+      str=getTemplateFileName (i);
+      QFileInfo fi(str);
+      sl.append(fi.baseName());
+    }
+  return sl;
+}
+
+/*!
+  loads an image in the rximages gallery in a new position
+
+  \param[in] fn the filename
+
+*/
+
+void galleryWidget::putRxImage ( QString fn )
+{
+  if(transmissionModeIndex==TRXSSTV)
+    {
+      statusBarPtr->showMessage ( "Saved: "+fn );
+      ui->rxSSTVMatrix->changed();
+    }
+  else
+    {
+      statusBarPtr->showMessage ( "Saved: "+fn+QString("  (%1dB)").arg(lastAvgSNR,0,'f',0) );
+      ui->rxDRMMatrix->changed();
+    }
+}
+
+void galleryWidget::txImageChanged()
+{
+  if(transmissionModeIndex==TRXSSTV)
+    {
+      ui->txSSTVMatrix->changed();
+    }
+  else
+    {
+      ui->txDRMMatrix->changed();
+    }
+}
+
+void galleryWidget::txStockImageChanged()
+{
+  ui->txStockMatrix->changed();
+}
+
+
+/*!
+  loads an image in the rximages gallery in a new position
+
+  \return QString containing filename, check with QString.isEmpty for validity
+
+*/
+QString galleryWidget::getLastRxImage()
+{
+  return ui->rxDRMMatrix->getLastFile();
+}
+
+
+
+
+
+
diff --git a/qsstv/gallerywidget.h b/qsstv/mainwidgets/gallerywidget.h
similarity index 60%
rename from qsstv/gallerywidget.h
rename to qsstv/mainwidgets/gallerywidget.h
index db1baa0..cd8bc5f 100644
--- a/qsstv/gallerywidget.h
+++ b/qsstv/mainwidgets/gallerywidget.h
@@ -2,7 +2,7 @@
 #define GALLERYWIDGET_H
 
 #include <QWidget>
-#include "widgets/imageviewer.h"
+#include "imageviewer.h"
 
 
 #define NUMTHUMBS 12
@@ -20,26 +20,23 @@ public:
     ~galleryWidget();
 
   void init();
-  void writeSettings(bool onlyRx);
+  void writeSettings();
   void readSettings();
+  void changedMatrix();
+  void changedMatrix(imageViewer::thumbType itype);
   void putRxImage(QString fn);
+  void txImageChanged ();
+  void txStockImageChanged();
   QString getTemplateFileName(int);
   const QStringList &getFilenames();
   QString getLastRxImage();
 
 public slots:
-    void slotLayoutChanged();
+
 
 
 private:
     Ui::galleryWidget *ui;
-    void initView();
-    void cleanup(imageViewer *array[], imageViewer::thumbType tp);
-    void shuffle(imageViewer *ar[], int idx);
-    imageViewer *rxThumbsArray[NUMTHUMBS];
-    imageViewer *txThumbsArray[NUMTHUMBS];
-    imageViewer *templateThumbsArray[NUMTHUMBS];
-    int rxIndex;
     QStringList sl;
 };
 
diff --git a/qsstv/mainwidgets/gallerywidget.ui b/qsstv/mainwidgets/gallerywidget.ui
new file mode 100644
index 0000000..8a1f84f
--- /dev/null
+++ b/qsstv/mainwidgets/gallerywidget.ui
@@ -0,0 +1,152 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>galleryWidget</class>
+ <widget class="QWidget" name="galleryWidget">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>516</width>
+    <height>364</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <property name="spacing">
+    <number>1</number>
+   </property>
+   <property name="leftMargin">
+    <number>1</number>
+   </property>
+   <property name="topMargin">
+    <number>1</number>
+   </property>
+   <property name="rightMargin">
+    <number>1</number>
+   </property>
+   <property name="bottomMargin">
+    <number>1</number>
+   </property>
+   <item>
+    <widget class="QTabWidget" name="tabWidget">
+     <property name="minimumSize">
+      <size>
+       <width>0</width>
+       <height>0</height>
+      </size>
+     </property>
+     <property name="font">
+      <font>
+       <pointsize>8</pointsize>
+      </font>
+     </property>
+     <property name="currentIndex">
+      <number>4</number>
+     </property>
+     <widget class="QWidget" name="rxSSTVtab">
+      <attribute name="title">
+       <string>RX SSTV</string>
+      </attribute>
+      <widget class="imageMatrix" name="rxSSTVMatrix" native="true">
+       <property name="geometry">
+        <rect>
+         <x>30</x>
+         <y>40</y>
+         <width>441</width>
+         <height>261</height>
+        </rect>
+       </property>
+      </widget>
+     </widget>
+     <widget class="QWidget" name="rxDRMtab">
+      <attribute name="title">
+       <string>RX DRM</string>
+      </attribute>
+      <widget class="imageMatrix" name="rxDRMMatrix" native="true">
+       <property name="geometry">
+        <rect>
+         <x>9</x>
+         <y>9</y>
+         <width>492</width>
+         <height>314</height>
+        </rect>
+       </property>
+      </widget>
+     </widget>
+     <widget class="QWidget" name="txtab">
+      <attribute name="title">
+       <string>TX SSTV</string>
+      </attribute>
+      <widget class="imageMatrix" name="txSSTVMatrix" native="true">
+       <property name="geometry">
+        <rect>
+         <x>20</x>
+         <y>20</y>
+         <width>451</width>
+         <height>301</height>
+        </rect>
+       </property>
+      </widget>
+     </widget>
+     <widget class="QWidget" name="tab">
+      <attribute name="title">
+       <string>TX DRM</string>
+      </attribute>
+      <widget class="imageMatrix" name="txDRMMatrix" native="true">
+       <property name="geometry">
+        <rect>
+         <x>110</x>
+         <y>90</y>
+         <width>120</width>
+         <height>80</height>
+        </rect>
+       </property>
+      </widget>
+     </widget>
+     <widget class="QWidget" name="tab_2">
+      <attribute name="title">
+       <string>TX Stock</string>
+      </attribute>
+      <widget class="imageMatrix" name="txStockMatrix" native="true">
+       <property name="geometry">
+        <rect>
+         <x>150</x>
+         <y>120</y>
+         <width>120</width>
+         <height>80</height>
+        </rect>
+       </property>
+      </widget>
+     </widget>
+     <widget class="QWidget" name="templatetab">
+      <attribute name="title">
+       <string>Templates</string>
+      </attribute>
+      <widget class="imageMatrix" name="templateMatrix" native="true">
+       <property name="geometry">
+        <rect>
+         <x>9</x>
+         <y>9</y>
+         <width>492</width>
+         <height>314</height>
+        </rect>
+       </property>
+      </widget>
+     </widget>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>imageMatrix</class>
+   <extends>QWidget</extends>
+   <header>imagematrix.h</header>
+   <container>1</container>
+  </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/qsstv/mainwidgets/rxfunctions.cpp b/qsstv/mainwidgets/rxfunctions.cpp
new file mode 100644
index 0000000..39aed5f
--- /dev/null
+++ b/qsstv/mainwidgets/rxfunctions.cpp
@@ -0,0 +1,189 @@
+#include "rxfunctions.h"
+#include "appglobal.h"
+#include "configparams.h"
+#include "drmrx.h"
+#include "soundbase.h"
+#include "dispatcher.h"
+#include "rxwidget.h"
+#include "sstvrx.h"
+
+#include <QApplication>
+
+
+
+const QString rxStateStr[rxFunctions::RXINIT+1]=
+{
+  "IDLE",
+  "RUNNING",
+  "RESTART",
+  "INIT"
+};
+
+rxFunctions::rxFunctions(QObject *parent) : QThread(parent)
+{
+  rxState=RXIDLE;
+  sstvRxPtr=new sstvRx;
+  drmRxPtr=new drmRx;
+  rxBytes=0;
+  setObjectName("rx-thread");
+}
+
+rxFunctions::~rxFunctions()
+{
+  delete sstvRxPtr;
+  delete drmRxPtr;
+}
+
+//static DSPFLOAT dummyBuf[RXSTRIPE];
+
+void rxFunctions::run()
+{
+  int count;
+  DSPFLOAT tempBuf[RXSTRIPE];
+  unsigned int volBuf[RXSTRIPE];
+  abort=false;
+  while(!abort)
+    {
+      switch(rxState)
+        {
+        case RXIDLE:
+          msleep(200);
+          break;
+        case RXRUNNING:
+          if((count=soundIOPtr->rxBuffer.count())<RXSTRIPE)
+            {
+              msleep((250*RXSTRIPE)/rxClock);
+              if(!soundIOPtr->isCapturing())
+                {
+                  switchRxState(RXINIT);
+                }
+            }
+          else
+            {
+              //              addToLog("Load new buf",LOGPERFORM);
+              rxBytes+=RXSTRIPE;
+              //              addToLog(QString("rxBytes=%1").arg(rxBytes),LOGRXFUNC);
+              soundIOPtr->rxBuffer.copyNoCheck(tempBuf,RXSTRIPE);
+              soundIOPtr->rxVolumeBuffer.copyNoCheck(volBuf,RXSTRIPE);
+              displayFFTEvent* ce = new displayFFTEvent(tempBuf);
+//              addToLog("fft display start",LOGPERFORM);
+//              ce->waitFor(&done);
+              QApplication::postEvent(dispatcherPtr, ce);
+//              while(!done) {usleep(100);}
+              addToLog("fft display done",LOGPERFORM);
+              switch (transmissionModeIndex)
+                {
+                case TRXDRM:
+                  addToLog("drmRxPtr->run",LOGPERFORM);
+                  drmRxPtr->run(tempBuf);
+                  break;
+                case TRXSSTV:
+                  sstvRxPtr->run(tempBuf,volBuf);
+                  break;
+                case TRXNOMODE:
+                  switchRxState(RXIDLE);
+                  break;
+                }
+            }
+          break;
+        case RXINIT:
+          forceInit();
+          switchRxState(RXIDLE);
+          break;
+        case RXRESTART:
+          {
+            init();
+            switchRxState(RXRUNNING);
+          }
+          break;
+        }
+    }
+  abort=false;
+  rxState=RXIDLE;
+
+}
+
+void rxFunctions::stopThread()
+{
+  abort=true;
+  if(!isRunning()) return;
+  while(abort)
+    {
+      qApp->processEvents();
+    }
+}
+
+void rxFunctions::init()
+{
+  switchRxState(RXINIT);
+}
+
+void rxFunctions::forceInit()
+{
+
+  if(transmissionModeIndex==TRXDRM)
+    {
+
+      drmRxPtr->init();
+    }
+  else
+    {
+      sstvRxPtr->init();
+    }
+}
+
+
+void rxFunctions::stopAndWait()
+{
+  soundIOPtr->idleRX();
+  switchRxState(RXINIT);
+  if(!isRunning())
+    {
+      return;
+    }
+  while((rxState!=RXIDLE) && (isRunning()))
+    {
+      qApp->processEvents();
+    }
+}
+
+void rxFunctions::restartRX()
+{
+  switchRxState(RXRESTART);
+}
+
+void rxFunctions::startRX()
+{
+  switchRxState(RXRUNNING);
+}
+
+void rxFunctions::eraseImage()
+{
+  if(isRunning())
+    {
+      if(transmissionModeIndex==TRXDRM)
+        {
+          drmRxPtr->eraseImage();
+        }
+      else
+        {
+          sstvRxPtr->eraseImage();
+        }
+    }
+}
+
+void rxFunctions::switchRxState(erxState newState)
+{
+  addToLog(QString("%1 to %2").arg(rxStateStr[rxState]).arg(rxStateStr[newState]),LOGRXFUNC);
+  rxState=newState;
+}
+
+
+
+
+#ifndef QT_NO_DEBUG
+unsigned int rxFunctions::setOffset(unsigned int offset,bool ask)
+{
+  return sstvRxPtr->setOffset(offset,ask);
+}
+#endif
diff --git a/qsstv/mainwidgets/rxfunctions.h b/qsstv/mainwidgets/rxfunctions.h
new file mode 100644
index 0000000..3a33510
--- /dev/null
+++ b/qsstv/mainwidgets/rxfunctions.h
@@ -0,0 +1,53 @@
+#ifndef RXFUNCTIONS_H
+#define RXFUNCTIONS_H
+
+#include <QThread>
+#include "appdefs.h"
+#include "sstv/syncprocessor.h"
+#include "utils/buffermanag.h"
+
+
+
+
+class downsampleFilter;
+class iirFilter;
+class modeBase;
+class sstvRx;
+class drmRx;
+
+class rxFunctions : public QThread
+{
+
+  Q_OBJECT
+public:
+  enum erxState {RXIDLE,RXRUNNING,RXRESTART,RXINIT};
+  explicit rxFunctions(QObject *parent = 0);
+  ~rxFunctions();
+  void run();
+  void init();
+  void stopAndWait();
+  void startRX();
+  void restartRX();
+  void eraseImage();
+  QString getModeStr();
+  sstvRx  *sstvRxPtr;
+  void stopThread();
+
+
+
+
+#ifndef QT_NO_DEBUG
+  unsigned int setOffset(unsigned int offset,bool ask);
+#endif
+private:
+
+  drmRx *drmRxPtr;
+  bool abort;
+  erxState rxState;
+  void switchRxState(erxState newState);
+  uint rxBytes;
+  void forceInit();
+
+};
+
+#endif // RXFUNCTIONS_H
diff --git a/qsstv/mainwidgets/rxwidget.cpp b/qsstv/mainwidgets/rxwidget.cpp
new file mode 100644
index 0000000..abd132e
--- /dev/null
+++ b/qsstv/mainwidgets/rxwidget.cpp
@@ -0,0 +1,306 @@
+#include "rxwidget.h"
+#include "appglobal.h"
+#include "dispatcher.h"
+#include "dirdialog.h"
+#include "rxfunctions.h"
+#include "imageviewer.h"
+#include "sstvparam.h"
+#include "filterparam.h"
+#include "mainwindow.h"
+#include "soundbase.h"
+#include "vumeter.h"
+#include "sstvrx.h"
+#include "guiconfig.h"
+#include "mainwindow.h"
+#include "configparams.h"
+
+
+
+rxWidget::rxWidget(QWidget *parent):QWidget(parent),ui(new Ui::rxWidget)
+{
+  int i;
+  ui->setupUi(this);
+  rxFunctionsPtr=new rxFunctions();
+  ui->syncWidget->setHorizontal(false);
+  ui->syncWidget->setLabelText("S");
+
+  ui->vuWidget->setHorizontal(true);
+  ui->vuWidget->setLabelText("V");
+  imageViewerPtr=ui->imageFrame;
+
+
+  ui->sstvModeComboBox->addItem("Auto");
+  for(i=0;i<NUMSSTVMODES-1;i++)
+    {
+      ui->sstvModeComboBox->addItem(getSSTVModeNameLong((esstvMode)i));
+    }
+  foreach (QByteArray format, QImageWriter::supportedImageFormats())
+    {
+      QString text = tr("%1").arg(QString(format));
+      ui->defaultImageFormatComboBox->addItem(text);
+    }
+  connect(&rxFunctionsPtr->sstvRxPtr->syncWideProc,SIGNAL(callReceived(QString)),SLOT(slotNewCall(QString)));
+  connect(rxFunctionsPtr->sstvRxPtr,SIGNAL(resetCall()),SLOT(slotResetCall()));
+  connect(ui->logPushButton,SIGNAL(clicked()),SLOT(slotLogCall()));
+}
+
+rxWidget::~rxWidget()
+{
+  writeSettings();
+  rxFunctionsPtr->terminate();
+  delete rxFunctionsPtr;
+}
+
+void rxWidget::init()
+{
+  splashStr+=QString( "Setting up RX" ).rightJustified(25,' ')+"\n";
+  splashPtr->showMessage ( splashStr ,Qt::AlignLeft,Qt::white);
+
+  qApp->processEvents();
+  readSettings();
+  //  imageViewerPtr->createImage(QSize(320,256),QColor(0,0,128),imageStretch);
+  imageViewerPtr->createImage(QSize(320,256),imageBackGroundColor,imageStretch);
+  imageViewerPtr->setType(imageViewer::RXIMG);
+  setSettingsTab();
+
+  rxFunctionsPtr->init();
+
+
+  // make connections after initialization
+  connect(ui->startToolButton, SIGNAL(clicked()),SLOT(slotStart()));
+  connect(ui->stopToolButton, SIGNAL(clicked()),SLOT(slotStop()));
+  connect(ui->resyncToolButton,SIGNAL(clicked()),SLOT(slotResync()));
+  connect(ui->autoSlantAdjustCheckBox,SIGNAL(clicked()),SLOT(slotGetParams()));
+  connect(ui->squelchComboBox,SIGNAL(currentIndexChanged(int)),SLOT(slotGetParams()));
+  connect(ui->settingsTableWidget,SIGNAL(currentChanged(int)),this, SLOT(slotTransmissionMode(int)));
+  connect(ui->eraseToolButton, SIGNAL(clicked()),SLOT(slotErase()));
+  connect(ui->saveToolButton, SIGNAL(clicked()),SLOT(slotSave()));
+  if(slowCPU)
+    {
+      ui->drmFACLabel->hide();
+      ui->drmMSCLabel->hide();
+      ui->drmMSCWidget->hide();
+      ui->drmFACWidget->hide();
+    }
+}
+
+void rxWidget::readSettings()
+{
+  QSettings qSettings;
+  qSettings.beginGroup("RX");
+  useVIS=qSettings.value("useVIS",false).toBool();
+  autoSlantAdjust=qSettings.value("autoSlantAdjust",false).toBool();
+  autoSave=qSettings.value("autoSave",true).toBool();
+  squelch=qSettings.value("squelch",1).toInt();
+  //  filterIndex=qSettings.value("filterIndex",0).toInt();
+  sstvModeIndexRx=(esstvMode)qSettings.value("sstvModeIndexRx",0).toInt();
+  defaultImageFormat=qSettings.value("defaultImageFormat","png").toString();
+  minCompletion=qSettings.value("minCompletion",25).toInt();
+  setParams();
+  qSettings.endGroup();
+
+}
+
+void rxWidget::writeSettings()
+{
+  QSettings qSettings;
+  qSettings.beginGroup("RX");
+  getParams();
+  qSettings.setValue("useVIS",useVIS);
+  qSettings.setValue("autoSlantAdjust",autoSlantAdjust);
+  qSettings.setValue("autoSave",autoSave);
+  qSettings.setValue("squelch",squelch);
+  qSettings.setValue("sstvModeIndexRx",sstvModeIndexRx);
+  qSettings.setValue("defaultImageFormat",defaultImageFormat);
+  qSettings.setValue("minCompletion",minCompletion);
+  qSettings.endGroup();
+}
+
+void rxWidget::getParams()
+{
+  int temp;
+  getValue(useVIS,ui->useVISCheckBox);
+  getValue(autoSlantAdjust,ui->autoSlantAdjustCheckBox);
+  getValue(autoSave,ui->autoSaveCheckBox);
+  getIndex(squelch,ui->squelchComboBox);
+  getIndex(temp,ui->sstvModeComboBox);
+  sstvModeIndexRx=(esstvMode)temp;
+  getValue(defaultImageFormat,ui->defaultImageFormatComboBox);
+  getValue(minCompletion,ui->completeSpinBox);
+}
+
+void rxWidget::setParams()
+{
+  setValue(useVIS,ui->useVISCheckBox);
+  setValue(autoSlantAdjust,ui->autoSlantAdjustCheckBox);
+  setValue(autoSave,ui->autoSaveCheckBox);
+  setIndex(squelch,ui->squelchComboBox);
+  setIndex(sstvModeIndexRx,ui->sstvModeComboBox);
+  setValue(defaultImageFormat,ui->defaultImageFormatComboBox);
+  setValue(minCompletion,ui->completeSpinBox);
+}
+
+void rxWidget::slotGetParams()
+{
+  getParams();
+}
+
+
+void rxWidget::slotStart()
+{
+  getParams();
+  dispatcherPtr->startRX();
+}
+
+void rxWidget::slotStop()
+{
+  getParams();
+  dispatcherPtr->idleAll();
+}
+
+void rxWidget::slotResync()
+{
+  rxFunctionsPtr->restartRX();
+}
+
+void rxWidget::slotTransmissionMode(int rxtxMode)
+{
+  emit modeSwitch(rxtxMode);
+}
+
+
+void rxWidget::changeTransmissionMode(int rxtxMode)
+{
+  transmissionModeIndex=(etransmissionMode)rxtxMode;
+  dispatcherPtr->idleAll();
+  setSettingsTab();
+  switch(transmissionModeIndex)
+    {
+    case TRXSSTV:
+      mainWindowPtr->setSSTVDRMPushButton(false);
+      ui->resyncToolButton->setEnabled(true);
+      break;
+    case TRXDRM:
+      mainWindowPtr->setSSTVDRMPushButton(true);
+      ui->resyncToolButton->setEnabled(false);
+      break;
+    default:
+      break;
+    }
+  dispatcherPtr->startRX();
+}
+
+void rxWidget::slotLogCall()
+{
+  QString call;
+  call=ui->callLineEdit->text().toUpper();
+  dispatcherPtr->logSSTV(call,false);
+}
+
+void rxWidget::slotNewCall(QString call)
+{
+  ui->callLineEdit->setText(call);
+  dispatcherPtr->logSSTV(call,true);
+}
+
+void rxWidget::slotResetCall()
+{
+  ui->callLineEdit->clear();
+}
+
+void rxWidget::slotErase()
+{
+  rxFunctionsPtr->eraseImage();
+  imageViewerPtr->createImage(QSize(320,256),imageBackGroundColor,imageStretch);
+}
+
+
+void rxWidget::slotSave()
+{
+  QDateTime dt(QDateTime::currentDateTime().toUTC()); //this is compatible with QT 4.6
+  QString path;
+  dirDialog d(this);
+  if(transmissionModeIndex==TRXSSTV)
+  {
+    path=rxSSTVImagesPath;
+
+  }
+  else
+  {
+    QMessageBox::information(this,"Saving image","Not available in DRM mode");
+    return;
+  }
+
+  QString fileName=d.saveFileName(path,"*","png");
+  if (fileName==QString::null) return ;
+  getImageViewerPtr()->save(fileName,defaultImageFormat,true,false);
+  dispatcherPtr->saveImage(fileName);
+}
+
+
+void rxWidget::setSettingsTab()
+{
+
+  int i;
+  if((transmissionModeIndex>=0)&&(transmissionModeIndex<TRXNOMODE))
+    {
+      for(i=0;i<TRXNOMODE;i++)
+        {
+          if(i!=transmissionModeIndex) ui->settingsTableWidget->widget(i)->setEnabled(false);
+        }
+      ui->settingsTableWidget->widget(transmissionModeIndex)->setEnabled(true);
+      ui->settingsTableWidget->setCurrentIndex(transmissionModeIndex);
+    }
+  ui->vuWidget->setMaximum(100);
+  ui->vuWidget->setMinimum(0);
+  ui->vuWidget->setValue(-15);
+  if(transmissionModeIndex==TRXDRM)
+    {
+      ui->syncWidget->setColors(QColor(0,90,0),QColor(0,190,0),Qt::green);
+      ui->syncWidget->setMaximum(25.);
+      ui->syncWidget->setMinimum(5.);
+      ui->syncWidget->setValue(0.);
+      ui->vuWidget->setColors(QColor(255,50,0),Qt::green,Qt::red);
+      mainWindowPtr->spectrumFramePtr->displaySettings(true);
+    }
+  else
+    {
+      ui->syncWidget->setColors(Qt::red,QColor(255,165,0),Qt::green);
+      ui->syncWidget->setMaximum(10.);
+      ui->syncWidget->setMinimum(0.);
+      ui->syncWidget->setValue(0.);
+      ui->vuWidget->setColors(QColor(255,50,0),Qt::green,Qt::red);
+      mainWindowPtr->spectrumFramePtr->displaySettings(false);
+    }
+}
+
+void rxWidget::startRX(bool st)
+{
+  if(st)
+    {
+      getParams();
+      dispatcherPtr->startRX();
+      addToLog("starting rxfunction run",LOGRXMAIN);
+    }
+  else
+    {
+      dispatcherPtr->idleAll();
+    }
+}
+
+void rxWidget::setSSTVStatusText(QString txt)
+{
+  ui->sstvStatusLineEdit->setText(txt);
+}
+
+
+vuMeter *rxWidget::vMeterPtr()
+{
+  return ui->vuWidget;
+}
+
+vuMeter *rxWidget::sMeterPtr()
+{
+  return ui->syncWidget;
+}
+
diff --git a/qsstv/rxwidget.h b/qsstv/mainwidgets/rxwidget.h
similarity index 60%
rename from qsstv/rxwidget.h
rename to qsstv/mainwidgets/rxwidget.h
index 35727f8..932031b 100644
--- a/qsstv/rxwidget.h
+++ b/qsstv/mainwidgets/rxwidget.h
@@ -3,18 +3,18 @@
 
 #include <QWidget>
 #include <QFrame>
-#include "rxfunctions.h"
+#include "spectrumwidget.h"
 #include "ui_rxwidget.h"
 
-
+class rxFunctions;
 class imageViewer;
 class spectrumWidget;
 class vuMeter;
 
 
 namespace Ui {
-  class rxWidget;
-  }
+class rxWidget;
+}
 
 class rxWidget : public QWidget
 {
@@ -23,40 +23,56 @@ class rxWidget : public QWidget
 public:
   explicit rxWidget(QWidget *parent = 0);
   ~rxWidget();
-  void init();
-  void start(bool st);
   void readSettings();
   void writeSettings();
-  void setFilterIndex(int index);
-  int getFilterIndex();
-  void setSettingsTab();
+  void startRX(bool st);
   rxFunctions *functionsPtr() {return rxFunctionsPtr;}
   imageViewer *getImageViewerPtr(){ return imageViewerPtr;}
-  spectrumWidget *fftDisplayPtr();
+//  spectrumWidget *fftDisplayPtr() ;
   vuMeter *vMeterPtr();
   vuMeter *sMeterPtr();
-  void setSSTVStatusText(QString txt);
-  void setDRMStatusText(QString txt);
-//  drmPSDFrame *psdWdg() {return ui->drmPSDWidget;}
   drmConstellationFrame *mscWdg() {return ui->drmMSCWidget;}
   drmConstellationFrame *facWdg() {return ui->drmFACWidget;}
+  void setDRMStatusText(QString txt) {
+    ui->drmStatusLineEdit->clear();
+    ui->drmStatusLineEdit->appendPlainText(txt);
+  }
+  void setDRMNotifyText(QString txt) {
+    //ui->rxNotificationList->clear();
+    ui->rxNotificationList->setPlainText(txt);
+  }
+  void appendDRMNotifyText(QString txt) {
+    ui->rxNotificationList->appendPlainText(txt);
+  }
 //  drmPSDFrame *psdWdg() {return ui->drmPSDWidget;}
   drmStatusFrame *statusWdg() {return ui->drmStatusWidget;}
+//  int getFilterIndex();
+  void init();
+  void setSSTVStatusText(QString txt);
+  void setSettingsTab();
+  void changeTransmissionMode(int rxtxMode);
 
 private slots:
   void slotStart();
   void slotStop();
+  void slotResync();
   void slotGetParams();
   void slotTransmissionMode(int rxtxMode);
-  void slotSaveImage();
+  void slotNewCall(QString);
+  void slotResetCall();
+  void slotLogCall();
+  void slotErase();
+  void slotSave();
+
+signals:
+  void modeSwitch(int);
+
 
 private:
   Ui::rxWidget *ui;
-  void getParams();
-  void setParams();
   rxFunctions *rxFunctionsPtr;
   imageViewer *imageViewerPtr;
+  void getParams();
+  void setParams();
 };
-
-extern rxWidget *rxWidgetPtr;
 #endif // RXWIDGET_H
diff --git a/qsstv/mainwidgets/rxwidget.ui b/qsstv/mainwidgets/rxwidget.ui
new file mode 100644
index 0000000..39322e7
--- /dev/null
+++ b/qsstv/mainwidgets/rxwidget.ui
@@ -0,0 +1,975 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>rxWidget</class>
+ <widget class="QWidget" name="rxWidget">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>926</width>
+    <height>862</height>
+   </rect>
+  </property>
+  <property name="sizePolicy">
+   <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+    <horstretch>0</horstretch>
+    <verstretch>0</verstretch>
+   </sizepolicy>
+  </property>
+  <property name="minimumSize">
+   <size>
+    <width>0</width>
+    <height>20</height>
+   </size>
+  </property>
+  <property name="font">
+   <font>
+    <family>Ubuntu Mono</family>
+    <pointsize>9</pointsize>
+    <weight>50</weight>
+    <italic>false</italic>
+    <bold>false</bold>
+   </font>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout_3">
+   <property name="spacing">
+    <number>1</number>
+   </property>
+   <property name="leftMargin">
+    <number>1</number>
+   </property>
+   <property name="topMargin">
+    <number>1</number>
+   </property>
+   <property name="rightMargin">
+    <number>1</number>
+   </property>
+   <property name="bottomMargin">
+    <number>1</number>
+   </property>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout_4" stretch="2,0,0">
+     <property name="spacing">
+      <number>1</number>
+     </property>
+     <item>
+      <layout class="QVBoxLayout" name="verticalLayout_4" stretch="0,0">
+       <item>
+        <layout class="QHBoxLayout" name="horizontalLayout_3">
+         <item>
+          <widget class="QToolButton" name="startToolButton">
+           <property name="toolTip">
+            <string>Start receiver</string>
+           </property>
+           <property name="statusTip">
+            <string>Status Start receiver</string>
+           </property>
+           <property name="text">
+            <string>...</string>
+           </property>
+           <property name="icon">
+            <iconset resource="../qsstv.qrc">
+             <normaloff>:/icons/start.png</normaloff>:/icons/start.png</iconset>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QToolButton" name="stopToolButton">
+           <property name="toolTip">
+            <string>Stop receiver</string>
+           </property>
+           <property name="statusTip">
+            <string>Stop receiver</string>
+           </property>
+           <property name="text">
+            <string>...</string>
+           </property>
+           <property name="icon">
+            <iconset resource="../qsstv.qrc">
+             <normaloff>:/icons/stop.png</normaloff>:/icons/stop.png</iconset>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QToolButton" name="resyncToolButton">
+           <property name="toolTip">
+            <string>Restart receiver</string>
+           </property>
+           <property name="statusTip">
+            <string>Restart receiver</string>
+           </property>
+           <property name="text">
+            <string>...</string>
+           </property>
+           <property name="icon">
+            <iconset resource="../qsstv.qrc">
+             <normaloff>:/icons/replay.png</normaloff>:/icons/replay.png</iconset>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QToolButton" name="saveToolButton">
+           <property name="toolTip">
+            <string>Save image</string>
+           </property>
+           <property name="statusTip">
+            <string>Save Image</string>
+           </property>
+           <property name="text">
+            <string>...</string>
+           </property>
+           <property name="icon">
+            <iconset resource="../qsstv.qrc">
+             <normaloff>:/icons/filesave.png</normaloff>:/icons/filesave.png</iconset>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QToolButton" name="eraseToolButton">
+           <property name="text">
+            <string>...</string>
+           </property>
+           <property name="icon">
+            <iconset resource="../qsstv.qrc">
+             <normaloff>:/icons/eraser.png</normaloff>:/icons/eraser.png</iconset>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <spacer name="horizontalSpacer">
+           <property name="orientation">
+            <enum>Qt::Horizontal</enum>
+           </property>
+           <property name="sizeHint" stdset="0">
+            <size>
+             <width>40</width>
+             <height>20</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <widget class="imageViewer" name="imageFrame" native="true">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+           <horstretch>1</horstretch>
+           <verstretch>1</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="minimumSize">
+          <size>
+           <width>320</width>
+           <height>256</height>
+          </size>
+         </property>
+         <property name="maximumSize">
+          <size>
+           <width>16777215</width>
+           <height>16777215</height>
+          </size>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </item>
+     <item>
+      <layout class="QVBoxLayout" name="verticalLayout_5">
+       <property name="spacing">
+        <number>2</number>
+       </property>
+       <item>
+        <widget class="vuMeter" name="syncWidget" native="true">
+         <property name="minimumSize">
+          <size>
+           <width>18</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="maximumSize">
+          <size>
+           <width>18</width>
+           <height>16777215</height>
+          </size>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="vuMeter" name="vuWidget" native="true">
+         <property name="minimumSize">
+          <size>
+           <width>18</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="maximumSize">
+          <size>
+           <width>18</width>
+           <height>16777215</height>
+          </size>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </item>
+     <item>
+      <widget class="QTabWidget" name="settingsTableWidget">
+       <property name="enabled">
+        <bool>true</bool>
+       </property>
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Expanding">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>0</width>
+         <height>0</height>
+        </size>
+       </property>
+       <property name="maximumSize">
+        <size>
+         <width>16777215</width>
+         <height>16777215</height>
+        </size>
+       </property>
+       <property name="currentIndex">
+        <number>1</number>
+       </property>
+       <widget class="QWidget" name="sstvTab">
+        <attribute name="title">
+         <string>SSTV</string>
+        </attribute>
+        <layout class="QVBoxLayout" name="verticalLayout_2">
+         <property name="spacing">
+          <number>1</number>
+         </property>
+         <property name="leftMargin">
+          <number>0</number>
+         </property>
+         <property name="topMargin">
+          <number>0</number>
+         </property>
+         <property name="rightMargin">
+          <number>0</number>
+         </property>
+         <property name="bottomMargin">
+          <number>0</number>
+         </property>
+         <item>
+          <layout class="QGridLayout" name="gridLayout_2">
+           <property name="spacing">
+            <number>1</number>
+           </property>
+           <item row="5" column="2">
+            <widget class="QComboBox" name="defaultImageFormatComboBox"/>
+           </item>
+           <item row="3" column="0">
+            <widget class="QLabel" name="squelchLabel">
+             <property name="toolTip">
+              <string>Sensitivity - Higher is more sensitive</string>
+             </property>
+             <property name="statusTip">
+              <string>Sensitivity - Higher is more sensitive</string>
+             </property>
+             <property name="text">
+              <string>Signals</string>
+             </property>
+             <property name="alignment">
+              <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+             </property>
+            </widget>
+           </item>
+           <item row="5" column="0">
+            <widget class="QLabel" name="imageFormatLabel">
+             <property name="text">
+              <string>Default Image format</string>
+             </property>
+             <property name="alignment">
+              <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+             </property>
+            </widget>
+           </item>
+           <item row="4" column="0">
+            <widget class="QLabel" name="modeLabel">
+             <property name="text">
+              <string>Mode</string>
+             </property>
+             <property name="alignment">
+              <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+             </property>
+            </widget>
+           </item>
+           <item row="2" column="0">
+            <widget class="QCheckBox" name="autoSaveCheckBox">
+             <property name="toolTip">
+              <string>Save image when complete</string>
+             </property>
+             <property name="statusTip">
+              <string>Save image when complete</string>
+             </property>
+             <property name="layoutDirection">
+              <enum>Qt::RightToLeft</enum>
+             </property>
+             <property name="text">
+              <string>Autosave</string>
+             </property>
+            </widget>
+           </item>
+           <item row="4" column="2">
+            <widget class="QComboBox" name="sstvModeComboBox"/>
+           </item>
+           <item row="0" column="0">
+            <widget class="QCheckBox" name="useVISCheckBox">
+             <property name="toolTip">
+              <string>Use VIS Code to start</string>
+             </property>
+             <property name="statusTip">
+              <string>Use VIS Code to start</string>
+             </property>
+             <property name="layoutDirection">
+              <enum>Qt::RightToLeft</enum>
+             </property>
+             <property name="text">
+              <string>Use VIS</string>
+             </property>
+            </widget>
+           </item>
+           <item row="3" column="2">
+            <widget class="QComboBox" name="squelchComboBox">
+             <item>
+              <property name="text">
+               <string>Normal</string>
+              </property>
+             </item>
+             <item>
+              <property name="text">
+               <string>DX</string>
+              </property>
+             </item>
+            </widget>
+           </item>
+           <item row="1" column="0">
+            <widget class="QCheckBox" name="autoSlantAdjustCheckBox">
+             <property name="toolTip">
+              <string>Correct slant automatically</string>
+             </property>
+             <property name="statusTip">
+              <string>Correct slant automatically</string>
+             </property>
+             <property name="layoutDirection">
+              <enum>Qt::RightToLeft</enum>
+             </property>
+             <property name="text">
+              <string>Auto Slant</string>
+             </property>
+            </widget>
+           </item>
+           <item row="6" column="0">
+            <widget class="QLabel" name="saveLabel">
+             <property name="text">
+              <string>Save if Complete (%)</string>
+             </property>
+             <property name="alignment">
+              <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+             </property>
+            </widget>
+           </item>
+           <item row="6" column="2">
+            <widget class="QSpinBox" name="completeSpinBox"/>
+           </item>
+          </layout>
+         </item>
+         <item>
+          <layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0,0">
+           <item>
+            <widget class="QLabel" name="callLabel">
+             <property name="text">
+              <string>Call:</string>
+             </property>
+            </widget>
+           </item>
+           <item>
+            <widget class="QLineEdit" name="callLineEdit"/>
+           </item>
+           <item>
+            <widget class="QPushButton" name="logPushButton">
+             <property name="text">
+              <string>LOG QSO</string>
+             </property>
+            </widget>
+           </item>
+          </layout>
+         </item>
+         <item>
+          <widget class="QLabel" name="sstvStatusLineEdit">
+           <property name="minimumSize">
+            <size>
+             <width>0</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="frameShape">
+            <enum>QFrame::Panel</enum>
+           </property>
+           <property name="frameShadow">
+            <enum>QFrame::Sunken</enum>
+           </property>
+           <property name="lineWidth">
+            <number>2</number>
+           </property>
+           <property name="text">
+            <string/>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <spacer name="verticalSpacer">
+           <property name="orientation">
+            <enum>Qt::Vertical</enum>
+           </property>
+           <property name="sizeHint" stdset="0">
+            <size>
+             <width>17</width>
+             <height>0</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+        </layout>
+       </widget>
+       <widget class="QWidget" name="drmTab">
+        <attribute name="title">
+         <string>DRM</string>
+        </attribute>
+        <layout class="QVBoxLayout" name="verticalLayout" stretch="0,0,0,0,0">
+         <property name="spacing">
+          <number>0</number>
+         </property>
+         <property name="leftMargin">
+          <number>0</number>
+         </property>
+         <property name="topMargin">
+          <number>0</number>
+         </property>
+         <property name="rightMargin">
+          <number>0</number>
+         </property>
+         <item>
+          <layout class="QVBoxLayout" name="drmLayout1" stretch="1">
+           <property name="spacing">
+            <number>1</number>
+           </property>
+           <item>
+            <widget class="drmStatusFrame" name="drmStatusWidget">
+             <property name="frameShape">
+              <enum>QFrame::StyledPanel</enum>
+             </property>
+             <property name="frameShadow">
+              <enum>QFrame::Raised</enum>
+             </property>
+            </widget>
+           </item>
+          </layout>
+         </item>
+         <item>
+          <widget class="QPlainTextEdit" name="drmStatusLineEdit">
+           <property name="minimumSize">
+            <size>
+             <width>0</width>
+             <height>55</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>16777215</width>
+             <height>50</height>
+            </size>
+           </property>
+           <property name="readOnly">
+            <bool>true</bool>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <layout class="QVBoxLayout" name="drmLayout4" stretch="0,1">
+           <property name="spacing">
+            <number>1</number>
+           </property>
+           <item>
+            <widget class="QLabel" name="drmFACLabel">
+             <property name="text">
+              <string>FAC</string>
+             </property>
+             <property name="alignment">
+              <set>Qt::AlignCenter</set>
+             </property>
+            </widget>
+           </item>
+           <item>
+            <widget class="drmConstellationFrame" name="drmFACWidget">
+             <property name="minimumSize">
+              <size>
+               <width>0</width>
+               <height>80</height>
+              </size>
+             </property>
+             <property name="maximumSize">
+              <size>
+               <width>16777215</width>
+               <height>120</height>
+              </size>
+             </property>
+             <property name="palette">
+              <palette>
+               <active>
+                <colorrole role="WindowText">
+                 <brush brushstyle="SolidPattern">
+                  <color alpha="255">
+                   <red>76</red>
+                   <green>76</green>
+                   <blue>76</blue>
+                  </color>
+                 </brush>
+                </colorrole>
+                <colorrole role="Light">
+                 <brush brushstyle="SolidPattern">
+                  <color alpha="255">
+                   <red>197</red>
+                   <green>197</green>
+                   <blue>197</blue>
+                  </color>
+                 </brush>
+                </colorrole>
+                <colorrole role="Dark">
+                 <brush brushstyle="SolidPattern">
+                  <color alpha="255">
+                   <red>0</red>
+                   <green>0</green>
+                   <blue>0</blue>
+                  </color>
+                 </brush>
+                </colorrole>
+                <colorrole role="Text">
+                 <brush brushstyle="SolidPattern">
+                  <color alpha="255">
+                   <red>60</red>
+                   <green>60</green>
+                   <blue>60</blue>
+                  </color>
+                 </brush>
+                </colorrole>
+                <colorrole role="ButtonText">
+                 <brush brushstyle="SolidPattern">
+                  <color alpha="255">
+                   <red>76</red>
+                   <green>76</green>
+                   <blue>76</blue>
+                  </color>
+                 </brush>
+                </colorrole>
+               </active>
+               <inactive>
+                <colorrole role="WindowText">
+                 <brush brushstyle="SolidPattern">
+                  <color alpha="255">
+                   <red>76</red>
+                   <green>76</green>
+                   <blue>76</blue>
+                  </color>
+                 </brush>
+                </colorrole>
+                <colorrole role="Light">
+                 <brush brushstyle="SolidPattern">
+                  <color alpha="255">
+                   <red>197</red>
+                   <green>197</green>
+                   <blue>197</blue>
+                  </color>
+                 </brush>
+                </colorrole>
+                <colorrole role="Dark">
+                 <brush brushstyle="SolidPattern">
+                  <color alpha="255">
+                   <red>0</red>
+                   <green>0</green>
+                   <blue>0</blue>
+                  </color>
+                 </brush>
+                </colorrole>
+                <colorrole role="Text">
+                 <brush brushstyle="SolidPattern">
+                  <color alpha="255">
+                   <red>60</red>
+                   <green>60</green>
+                   <blue>60</blue>
+                  </color>
+                 </brush>
+                </colorrole>
+                <colorrole role="ButtonText">
+                 <brush brushstyle="SolidPattern">
+                  <color alpha="255">
+                   <red>76</red>
+                   <green>76</green>
+                   <blue>76</blue>
+                  </color>
+                 </brush>
+                </colorrole>
+               </inactive>
+               <disabled>
+                <colorrole role="WindowText">
+                 <brush brushstyle="SolidPattern">
+                  <color alpha="255">
+                   <red>0</red>
+                   <green>0</green>
+                   <blue>0</blue>
+                  </color>
+                 </brush>
+                </colorrole>
+                <colorrole role="Light">
+                 <brush brushstyle="SolidPattern">
+                  <color alpha="255">
+                   <red>197</red>
+                   <green>197</green>
+                   <blue>197</blue>
+                  </color>
+                 </brush>
+                </colorrole>
+                <colorrole role="Dark">
+                 <brush brushstyle="SolidPattern">
+                  <color alpha="255">
+                   <red>0</red>
+                   <green>0</green>
+                   <blue>0</blue>
+                  </color>
+                 </brush>
+                </colorrole>
+                <colorrole role="Text">
+                 <brush brushstyle="SolidPattern">
+                  <color alpha="255">
+                   <red>0</red>
+                   <green>0</green>
+                   <blue>0</blue>
+                  </color>
+                 </brush>
+                </colorrole>
+                <colorrole role="ButtonText">
+                 <brush brushstyle="SolidPattern">
+                  <color alpha="255">
+                   <red>0</red>
+                   <green>0</green>
+                   <blue>0</blue>
+                  </color>
+                 </brush>
+                </colorrole>
+               </disabled>
+              </palette>
+             </property>
+             <property name="frameShape">
+              <enum>QFrame::Panel</enum>
+             </property>
+             <property name="frameShadow">
+              <enum>QFrame::Sunken</enum>
+             </property>
+             <property name="lineWidth">
+              <number>3</number>
+             </property>
+            </widget>
+           </item>
+          </layout>
+         </item>
+         <item>
+          <layout class="QVBoxLayout" name="drmLayout3" stretch="0,1,0">
+           <property name="spacing">
+            <number>1</number>
+           </property>
+           <item>
+            <widget class="QLabel" name="drmMSCLabel">
+             <property name="text">
+              <string>MSC</string>
+             </property>
+             <property name="alignment">
+              <set>Qt::AlignCenter</set>
+             </property>
+            </widget>
+           </item>
+           <item>
+            <widget class="drmConstellationFrame" name="drmMSCWidget">
+             <property name="minimumSize">
+              <size>
+               <width>0</width>
+               <height>80</height>
+              </size>
+             </property>
+             <property name="maximumSize">
+              <size>
+               <width>16777215</width>
+               <height>120</height>
+              </size>
+             </property>
+             <property name="palette">
+              <palette>
+               <active>
+                <colorrole role="WindowText">
+                 <brush brushstyle="SolidPattern">
+                  <color alpha="255">
+                   <red>76</red>
+                   <green>76</green>
+                   <blue>76</blue>
+                  </color>
+                 </brush>
+                </colorrole>
+                <colorrole role="Light">
+                 <brush brushstyle="SolidPattern">
+                  <color alpha="255">
+                   <red>197</red>
+                   <green>197</green>
+                   <blue>197</blue>
+                  </color>
+                 </brush>
+                </colorrole>
+                <colorrole role="Dark">
+                 <brush brushstyle="SolidPattern">
+                  <color alpha="255">
+                   <red>0</red>
+                   <green>0</green>
+                   <blue>0</blue>
+                  </color>
+                 </brush>
+                </colorrole>
+                <colorrole role="Text">
+                 <brush brushstyle="SolidPattern">
+                  <color alpha="255">
+                   <red>60</red>
+                   <green>60</green>
+                   <blue>60</blue>
+                  </color>
+                 </brush>
+                </colorrole>
+                <colorrole role="ButtonText">
+                 <brush brushstyle="SolidPattern">
+                  <color alpha="255">
+                   <red>76</red>
+                   <green>76</green>
+                   <blue>76</blue>
+                  </color>
+                 </brush>
+                </colorrole>
+               </active>
+               <inactive>
+                <colorrole role="WindowText">
+                 <brush brushstyle="SolidPattern">
+                  <color alpha="255">
+                   <red>76</red>
+                   <green>76</green>
+                   <blue>76</blue>
+                  </color>
+                 </brush>
+                </colorrole>
+                <colorrole role="Light">
+                 <brush brushstyle="SolidPattern">
+                  <color alpha="255">
+                   <red>197</red>
+                   <green>197</green>
+                   <blue>197</blue>
+                  </color>
+                 </brush>
+                </colorrole>
+                <colorrole role="Dark">
+                 <brush brushstyle="SolidPattern">
+                  <color alpha="255">
+                   <red>0</red>
+                   <green>0</green>
+                   <blue>0</blue>
+                  </color>
+                 </brush>
+                </colorrole>
+                <colorrole role="Text">
+                 <brush brushstyle="SolidPattern">
+                  <color alpha="255">
+                   <red>60</red>
+                   <green>60</green>
+                   <blue>60</blue>
+                  </color>
+                 </brush>
+                </colorrole>
+                <colorrole role="ButtonText">
+                 <brush brushstyle="SolidPattern">
+                  <color alpha="255">
+                   <red>76</red>
+                   <green>76</green>
+                   <blue>76</blue>
+                  </color>
+                 </brush>
+                </colorrole>
+               </inactive>
+               <disabled>
+                <colorrole role="WindowText">
+                 <brush brushstyle="SolidPattern">
+                  <color alpha="255">
+                   <red>0</red>
+                   <green>0</green>
+                   <blue>0</blue>
+                  </color>
+                 </brush>
+                </colorrole>
+                <colorrole role="Light">
+                 <brush brushstyle="SolidPattern">
+                  <color alpha="255">
+                   <red>197</red>
+                   <green>197</green>
+                   <blue>197</blue>
+                  </color>
+                 </brush>
+                </colorrole>
+                <colorrole role="Dark">
+                 <brush brushstyle="SolidPattern">
+                  <color alpha="255">
+                   <red>0</red>
+                   <green>0</green>
+                   <blue>0</blue>
+                  </color>
+                 </brush>
+                </colorrole>
+                <colorrole role="Text">
+                 <brush brushstyle="SolidPattern">
+                  <color alpha="255">
+                   <red>0</red>
+                   <green>0</green>
+                   <blue>0</blue>
+                  </color>
+                 </brush>
+                </colorrole>
+                <colorrole role="ButtonText">
+                 <brush brushstyle="SolidPattern">
+                  <color alpha="255">
+                   <red>0</red>
+                   <green>0</green>
+                   <blue>0</blue>
+                  </color>
+                 </brush>
+                </colorrole>
+               </disabled>
+              </palette>
+             </property>
+             <property name="frameShape">
+              <enum>QFrame::Panel</enum>
+             </property>
+             <property name="frameShadow">
+              <enum>QFrame::Sunken</enum>
+             </property>
+             <property name="lineWidth">
+              <number>3</number>
+             </property>
+            </widget>
+           </item>
+           <item>
+            <spacer name="verticalSpacer_2">
+             <property name="orientation">
+              <enum>Qt::Vertical</enum>
+             </property>
+             <property name="sizeType">
+              <enum>QSizePolicy::Expanding</enum>
+             </property>
+             <property name="sizeHint" stdset="0">
+              <size>
+               <width>20</width>
+               <height>40</height>
+              </size>
+             </property>
+            </spacer>
+           </item>
+          </layout>
+         </item>
+         <item>
+          <widget class="QPlainTextEdit" name="rxNotificationList">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Expanding" vsizetype="Maximum">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>0</width>
+             <height>20</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>16777215</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="baseSize">
+            <size>
+             <width>0</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="contextMenuPolicy">
+            <enum>Qt::NoContextMenu</enum>
+           </property>
+           <property name="acceptDrops">
+            <bool>false</bool>
+           </property>
+           <property name="toolTip">
+            <string>Rx Notifications seen for the last DRM Hybrid Item.
+You usually only get a partial list due to timing, internet speeds, and the sender having read and deleted them already.</string>
+           </property>
+           <property name="lineWrapMode">
+            <enum>QPlainTextEdit::NoWrap</enum>
+           </property>
+           <property name="readOnly">
+            <bool>true</bool>
+           </property>
+           <property name="tabStopWidth">
+            <number>8</number>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </widget>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>imageViewer</class>
+   <extends>QWidget</extends>
+   <header>widgets/imageviewer.h</header>
+   <container>1</container>
+  </customwidget>
+  <customwidget>
+   <class>vuMeter</class>
+   <extends>QWidget</extends>
+   <header>widgets/vumeter.h</header>
+   <container>1</container>
+  </customwidget>
+  <customwidget>
+   <class>drmStatusFrame</class>
+   <extends>QFrame</extends>
+   <header>drmrx/drmstatusframe.h</header>
+   <container>1</container>
+  </customwidget>
+  <customwidget>
+   <class>drmConstellationFrame</class>
+   <extends>QFrame</extends>
+   <header>drmrx/drmconstellationframe.h</header>
+   <container>1</container>
+  </customwidget>
+ </customwidgets>
+ <resources>
+  <include location="../qsstv.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/qsstv/mainwidgets/txfunctions.cpp b/qsstv/mainwidgets/txfunctions.cpp
new file mode 100644
index 0000000..cfd18e5
--- /dev/null
+++ b/qsstv/mainwidgets/txfunctions.cpp
@@ -0,0 +1,504 @@
+/***************************************************************************
+ *   Copyright (C) 2000-2014 by Johan Maes                                 *
+ *   on4qz at telenet.be                                                      *
+ *   http://users.telenet.be/on4qz                                         *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   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.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#include "txfunctions.h"
+#include "appglobal.h"
+#include "sstv/sstvtx.h"
+#include "sstv/cw.h"
+
+
+#include "configparams.h"
+#include <qmutex.h>
+#include "dsp/synthes.h"
+#include "sstv/modes/modes.h"
+#include "dispatch/dispatcher.h"
+#include "cw.h"
+#include <QApplication>
+#include <assert.h>
+#include "txwidget.h"
+#include "soundbase.h"
+#include "waterfalltext.h"
+#include "hybridcrypt.h"
+#include "rigcontrol.h"
+#include "drm.h"
+#include "drmtx.h"
+#include "fixform.h"
+#include "mainwindow.h"
+
+
+QMutex txMutex;
+
+int templateIndex;
+bool useTemplate;
+bool useCW;
+bool useVOX;
+
+const QString txStateStr[txFunctions::TXTEST+1]=
+{
+  "IDLE",
+  "ACTIVE",
+  "SENDTONE",
+  "SENDID",
+  "SENDDRM",
+  "SENDDRMBSR",
+  "SENDDRMFIX",
+  "SENDDRMTXT",
+  "SSTVIMAGE",
+  "SSTVPOST",
+  "TXTEST"
+};
+
+
+txFunctions::txFunctions(QObject *parent) : QThread(parent)
+{
+
+  txState=TXIDLE;
+  started=false;
+  sstvTxPtr=new sstvTx;
+  drmTxPtr=new drmTx;
+}
+
+txFunctions::~txFunctions()
+{
+  delete synthesPtr;
+  delete sstvTxPtr;
+  delete drmTxPtr;
+}
+
+
+
+void txFunctions::init()
+{
+  synthesPtr=new synthesizer(txClock);
+  switchTxState(TXIDLE);
+  addToLog("txFunc: Init",LOGTXFUNC);
+
+}
+
+void txFunctions::run()
+{
+  double waterfallTime;
+  abort=false;
+  init();
+  while(!abort)
+    {
+
+      started=true;
+      switch (txState)
+        {
+        case TXIDLE:
+          msleep(10);
+        break;
+        case TXACTIVE:
+          msleep(1);
+        break;
+        case TXSENDTONE:
+          waitTxOn();
+          addToLog("txFunc: entered TXSENDTONE",LOGTXFUNC);
+          startProgress(toneDuration);
+          synthesPtr->sendTone(toneDuration,toneLowerFrequency,toneUpperFrequency,false);
+          addToLog("txFunc: TXSENDTONE waiting for end",LOGTXFUNC);
+          waitEnd();
+          switchTxState(TXIDLE);
+        break;
+
+        case TXSENDDRMBINARY:
+          waitTxOn();
+          waterfallTime=waterfallPtr->getDuration("START BIN");
+          waterfallTime+=waterfallPtr->getDuration("END BIN");
+          if(!drmTxPtr->initDRMImage(true,binaryFilename))
+            {
+              waitEnd();
+              switchTxState(TXIDLE);
+            }
+          startProgress(drmTxPtr->calcTxTime(waterfallTime));
+          addToLog("start of wf",LOGTXFUNC);
+          waterfallPtr->setText("START BIN");
+          synthesPtr->sendWFText();
+          addToLog("start of txDrm",LOGTXFUNC);
+          drmTxPtr->start();
+
+          addToLog("end of txDrm",LOGTXFUNC);
+          if(txState==TXSENDDRM) // abort if txState is idle
+            {
+              waterfallPtr->setText("END BIN");
+              synthesPtr->sendWFText();
+              addToLog("end of wf",LOGTXFUNC);
+              addToLog("txFunc: TXSENDDRM waiting for end",LOGTXFUNC);
+              waitEnd();
+            }
+          switchTxState(TXIDLE);
+        break;
+        case TXSENDDRM:
+          waitTxOn();
+          waterfallTime=waterfallPtr->getDuration(endPicWF);
+          waterfallTime+=waterfallPtr->getDuration(startPicWF);
+          if(!drmTxPtr->initDRMImage(false,""))
+            {
+              waitEnd();
+              switchTxState(TXIDLE);
+              break;
+            }
+          startProgress(drmTxPtr->calcTxTime(waterfallTime));
+          addToLog("start of wf",LOGTXFUNC);
+          waterfallPtr->setText(startPicWF);
+          synthesPtr->sendWFText();
+          addToLog("start of txDrm",LOGTXFUNC);
+          drmTxPtr->start();
+
+          addToLog("end of txDrm",LOGTXFUNC);
+          if(txState==TXSENDDRM) // abort if txState is idle
+            {
+              waterfallPtr->setText(endPicWF);
+              synthesPtr->sendWFText();
+              addToLog("end of wf",LOGTXFUNC);
+              addToLog("txFunc: TXSENDDRM waiting for end",LOGTXFUNC);
+              waitEnd();
+            }
+          switchTxState(TXIDLE);
+        break;
+
+
+
+        case TXSENDDRMBSR:
+          waitTxOn();
+          waterfallTime=waterfallPtr->getDuration(bsrWF);
+          startProgress(drmTxPtr->calcTxTime(waterfallTime));
+          synthesPtr->sendWFText();
+          drmTxPtr->start();
+          addToLog("txFunc: TXSENDDRMBSR waiting for end",LOGTXFUNC);
+          waitEnd();
+          switchTxState(TXIDLE);
+        break;
+
+        case TXSENDDRMFIX:
+          waitTxOn();
+          waterfallTime=waterfallPtr->getDuration(fixWF);
+          startProgress(drmTxPtr->calcTxTime(waterfallTime));
+          synthesPtr->sendWFText();
+          drmTxPtr->start();
+          addToLog("txFunc: TXSENDDRMFIX waiting for end",LOGTXFUNC);
+          if(txState==TXSENDDRMFIX) // abort if txState is idle
+            {
+              waterfallPtr->setText(endPicWF);
+              synthesPtr->sendWFText();
+              addToLog("end of wf",LOGTXFUNC);
+              addToLog("txFunc: TXSENDDRM waiting for end",LOGTXFUNC);
+              waitEnd();
+            }
+          switchTxState(TXIDLE);
+        break;
+        case TXSENDDRMTXT:
+          waitTxOn();
+        break;
+        case TXSENDID:
+          addToLog("Entered TXSENDID",LOGTXFUNC);
+          waitTxOn();
+          addToLog("after txon TXSENDID",LOGTXFUNC);
+          startProgress(waterfallPtr->getDuration());
+          synthesPtr->sendWFText();
+          addToLog("TXSENDID waiting for end",LOGTXFUNC);
+          waitEnd();
+          addToLog("TXSENDID  end",LOGTXFUNC);
+          switchTxState(TXIDLE);
+        break;
+        case TXSSTVIMAGE:
+          waitTxOn();
+          addToLog("Entered SSTVTXIMAGE",LOGTXFUNC);
+          startProgress(sstvTxPtr->calcTxTime(0));
+          addToLog("Entered before SSTVTXIMAGE",LOGTXFUNC);
+          if(sstvTxPtr->sendImage(txWidgetPtr->getImageViewerPtr()))
+            {
+              switchTxState(TXSSTVPOST);
+            }
+          else
+            {
+              switchTxState(TXIDLE);
+            }
+        break;
+        case TXSSTVPOST:
+          addToLog("Entered TXSSTVPOST ",LOGTXFUNC);
+          if (useCW)
+            {
+              sendCW();
+            }
+          else
+            {
+              sendFSKID();
+            }
+          waitEnd();
+          switchTxState(TXRESTART);
+        break;
+        case TXRESTART:
+          switchTxState(TXIDLE);
+          break;
+        case TXTEST:
+          sendTestPattern();
+        break;
+
+        }
+    }
+  started=false;
+  addToLog("txFunc stopped",LOGTXFUNC);
+  abort=false;
+  txState=TXIDLE;
+}
+
+void txFunctions::setDRMTxParams(drmTxParams params)
+{
+  drmTxPtr->setTxParams(params);
+}
+
+
+void txFunctions::startProgress(double duration)
+{
+  progressTXEvent *ce;
+  ce=new progressTXEvent(duration+rigControllerPtr->getTxDelay()+SILENCEDELAY);
+  QApplication::postEvent( dispatcherPtr, ce );  // Qt will delete it when done
+}
+
+void txFunctions::stopThread()
+{
+  abort=true;
+ if(!isRunning()) return;
+  while(abort)
+    {
+      qApp->processEvents();
+    }
+}
+
+void txFunctions::startTX(etxState state)
+{
+  switchTxState(state);
+}
+
+void txFunctions::waitTxOn()
+{
+  double txDelay;
+  txDelay=rigControllerPtr->getTxDelay();
+  if(txDelay!=0)
+    {
+      synthesPtr->sendSilence(txDelay);
+    }
+}
+
+void txFunctions::waitEnd()
+{
+  synthesPtr->sendTone(SILENCEDELAY,00,0,true); // send silence
+  addToLog("waitEnd() posting endTXImage",LOGTXFUNC);
+  endImageTXEvent *ce=new endImageTXEvent;
+  QApplication::postEvent(dispatcherPtr, ce );  // Qt will delete it when done
+}
+
+void txFunctions::stopAndWait()
+{
+  stopDRM=true;
+  if(transmissionModeIndex==TRXSSTV)
+    {
+      sstvTxPtr->abort();
+      switchTxState(TXRESTART);
+      while(txState!=TXIDLE)
+        {
+          qApp->processEvents();
+        }
+
+    }
+  addToLog("txFunc: stop initiated",LOGTXFUNC);
+  switchTxState(TXIDLE);
+  while(txState!=TXIDLE)
+    {
+      qApp->processEvents();
+    }
+  soundIOPtr->idleTX();
+  addToLog("txFunc: stop executed",LOGTXFUNC);
+}
+
+
+void txFunctions::sendTestPattern()
+{
+  syncBurst();
+}
+
+
+/** send a burst of syncs */
+void txFunctions::syncBurst()
+{
+  // send 5msec 1200Hz followed by 50 msec silence
+  //	synthesPtr->sendTone(0.005,1200.);
+  for (int i=0;i<50;i++)
+    {
+      synthesPtr->sendTone(0.005,1200,0,true);
+      synthesPtr->sendTone(0.020,1700,0,true);
+    }
+  synthesPtr->sendSilence(0.100);;
+}
+
+
+void txFunctions::sendCW()
+{
+  addToLog("txFunc:sendCW",LOGTXFUNC);
+  float tone;
+  float duration;
+  initCW(cwText);
+  synthesPtr->sendSilence(0.5);
+  while(sendTextCW(tone,duration))
+    {
+      synthesPtr->sendTone(duration,tone,0,true);
+    }
+}
+
+
+void txFunctions:: sendFSKChar(int IDChar)
+{
+  int TxBit;
+
+  for (int i=0;i<6;i++)
+    {
+      TxBit = IDChar & 0x01;
+      IDChar = IDChar >> 1;
+      if (TxBit == 0x01)
+        synthesPtr->sendTone(0.022,1900.,0,true);
+      else
+        synthesPtr->sendTone(0.022,2100.,0,true);
+    }
+}
+
+// sendFSKID by DL3YAP
+
+
+
+
+
+
+void txFunctions:: sendFSKID()
+{
+  int idx;
+  int l;
+  int IDChar;
+  int Checksum;
+
+
+  if (myCallsign.isEmpty()) return;
+  // addToLog("txFunc:sendFSKID",LOGFSKID);
+
+  l=myCallsign.size();
+  idx=0;
+  Checksum=0;
+  // synthesPtr->sendTone(2.0,00,0,false);
+  synthesPtr->sendTone(0.3,1500.,0,false);
+  synthesPtr->sendTone(0.1,2100.,0,true);
+  synthesPtr->sendTone(0.022,1900.,0,true);
+
+  IDChar = 0x2A;
+  sendFSKChar(IDChar);
+
+  QChar IDText=	QChar(myCallsign[idx]);
+  IDChar=int(IDText.toLatin1());
+
+  IDChar = (IDChar - 0x20);
+  Checksum = IDChar;
+
+  while (idx < l)
+    {
+      sendFSKChar(IDChar);
+      idx++;
+      QChar IDText=QChar(myCallsign[idx].toUpper());
+      IDChar=int(IDText.toLatin1());
+      IDChar = (IDChar - 0x20);
+
+      if (idx < l)
+        {
+          Checksum = Checksum ^ IDChar;
+        }
+    }
+
+  IDChar = 0x01;
+
+  sendFSKChar(IDChar);
+
+  IDChar = Checksum & 0x3F ;
+
+  sendFSKChar(IDChar);
+  synthesPtr->sendTone(0.1,1900.,0,true);
+}
+
+void txFunctions::sendBSR(QByteArray *p,drmTxParams dp)
+{
+  if(p==NULL) return;
+  drmTxPtr->sendBSR(p,dp);
+}
+
+
+//void txFunctions::sendHybrid(QString fn)
+//{
+//  drmTxPtr->sendHybrid(fn);
+//}
+
+bool txFunctions::prepareFIX(QByteArray bsrByteArray)
+{
+  int trID;
+  displayMBoxEvent *stce;
+  txSession *sessionPtr;
+  fixForm fx(mainWindowPtr);
+  trID=drmTxPtr->processFIX(bsrByteArray);
+  if(trID<0)  return false;
+  sessionPtr=drmTxPtr->getSessionPtr((uint)trID);
+  if (sessionPtr==NULL)
+    {
+      stce= new displayMBoxEvent("BSR Received","This BSR is not for you");
+      QApplication::postEvent( dispatcherPtr, stce );  // Qt will delete it when done
+      return false;
+    }
+  else
+    {
+      // take it from the transmitlist
+      fx.setInfoInternal(paramsToMode(sessionPtr->drmParams),sessionPtr->filename,fixBlockList.count(),&sessionPtr->ba);
+      if(fx.exec()==QDialog::Rejected) return false;
+      drmTxPtr->initDRMFIX(sessionPtr);
+    }
+  return true;
+}
+
+bool txFunctions::prepareBinary(QString fileName)
+{
+  binaryFilename=fileName;
+  return true;
+}
+
+
+void txFunctions::applyTemplate(imageViewer *ivPtr,QString templateFilename)
+{
+  if(transmissionModeIndex==TRXSSTV)
+    {
+      sstvTxPtr->applyTemplate(templateFilename,useTemplate,ivPtr);
+    }
+  else
+    {
+      drmTxPtr->applyTemplate(templateFilename,useTemplate,ivPtr);
+    }
+}
+
+
+void txFunctions::switchTxState(etxState newState)
+{
+  addToLog(QString("%1 to %2").arg(txStateStr[txState]).arg(txStateStr[newState]),LOGTXFUNC);
+  txState=newState;
+}
diff --git a/qsstv/mainwidgets/txfunctions.h b/qsstv/mainwidgets/txfunctions.h
new file mode 100644
index 0000000..eda3be8
--- /dev/null
+++ b/qsstv/mainwidgets/txfunctions.h
@@ -0,0 +1,85 @@
+#ifndef TXFUNCTIONS_H
+#define TXFUNCTIONS_H
+
+#include <QThread>
+#include "appdefs.h"
+#include "drmparams.h"
+
+#define SILENCEDELAY 0.600           // send silence after transmission
+
+extern int templateIndex;
+extern bool useTemplate;
+extern bool useCW;
+extern bool useVOX;
+
+class sstvTx;
+class drmTx;
+class imageViewer;
+
+
+
+class txFunctions  : public QThread
+{
+  Q_OBJECT
+public:
+  enum etxState
+  {
+    TXIDLE,	//!< in idle loop
+    TXACTIVE,
+    TXSENDTONE,
+    TXSENDID,
+    TXSENDDRM,
+    TXSENDDRMBINARY,
+    TXSENDDRMBSR,
+    TXSENDDRMFIX,
+    TXSENDDRMTXT,
+    TXSSTVIMAGE,
+    TXSSTVPOST,
+    TXRESTART,
+    TXTEST
+
+  };
+  txFunctions(QObject *parent);
+  ~txFunctions();
+  void init();
+  void run();
+  void stopThread();
+  void startTX(etxState state);
+  void stopAndWait();
+  void setToneParam(double duration,double lowerFreq,double upperFreq=0)
+  {
+    toneDuration=duration;
+    toneLowerFrequency=lowerFreq;
+    toneUpperFrequency=upperFreq;
+  }
+  bool prepareFIX(QByteArray bsrByteArray);
+  bool prepareBinary(QString fileName);
+  void sendBSR(QByteArray *p,drmTxParams dp);
+  void applyTemplate(imageViewer *ivPtr,QString templateFilename);
+  etxState getTXState() { return txState;}
+  void setDRMTxParams(drmTxParams params);
+  //  bool initDRMFIX(txSession *sessionPtr);
+
+
+private:
+  void waitTxOn();
+  void waitEnd();
+  void sendCW();
+  void sendFSKID();
+  void sendTestPattern();
+  void syncBurst();
+  void sendFSKChar(int IDChar);
+  void switchTxState(etxState newState);
+  void startProgress(double duration);
+  etxState txState;
+  bool started;
+  bool abort;
+  double toneDuration;
+  double toneLowerFrequency;
+  double toneUpperFrequency;
+  QString binaryFilename;
+  sstvTx *sstvTxPtr;
+  drmTx *drmTxPtr;
+};
+
+#endif // TXFUNCTIONS_H
diff --git a/qsstv/txwidget.cpp b/qsstv/mainwidgets/txwidget.cpp
similarity index 56%
rename from qsstv/txwidget.cpp
rename to qsstv/mainwidgets/txwidget.cpp
index c87a484..5456042 100644
--- a/qsstv/txwidget.cpp
+++ b/qsstv/mainwidgets/txwidget.cpp
@@ -1,58 +1,64 @@
 #include "txwidget.h"
-#include <rxwidget.h>
+#include "appglobal.h"
+#include "drmtx/drmparams.h"
+#include "rxwidget.h"
+#include "rxfunctions.h"
 #include "ui_txwidget.h"
 #include <QTimer>
 #include "configparams.h"
 #include "dispatcher.h"
-#include "utils/supportfunctions.h"
+#include "supportfunctions.h"
 #include "gallerywidget.h"
+#include "waterfalltext.h"
 
 #include "ui_freqform.h"
 #include "ui_sweepform.h"
-#include "widgets/cameracontrol.h"
-#include "videocapt/videocapture.h"
-#include "sound/soundio.h"
-#include "widgets/waterfallform.h"
-#include "drmtx/bsrform.h"
-#include "drmrx/fixform.h"
+#include "cameradialog.h"
+#include "soundbase.h"
+#include "waterfallform.h"
+#include "bsrform.h"
 #include "mainwindow.h"
+#include "rigcontrol.h"
+#include "imageviewer.h"
 
 
 
 
-txWidget *txWidgetPtr;
 
-txWidget::txWidget(QWidget *parent) :
-  QWidget(parent),
-  ui(new Ui::txWidget)
+
+txWidget::txWidget(QWidget *parent) :  QWidget(parent), ui(new Ui::txWidget)
 {
   int i;
   QString tmp;
   ui->setupUi(this);
-  txFunctionsPtr=new txFunctions();
+  ui->previewWidget->setType(imageViewer::PREVIEW);
+  txFunctionsPtr=new txFunctions(this);
   imageViewerPtr=ui->imageFrame;
-  imageViewerPtr->createImage(QSize(320,256),QColor(0,0,128));
-  imageViewerPtr->displayImage(false);
-  readSettings();
-  setProfileNames();
 
-  for(i=0;i<NUMSSTVMODES-1;i++) // exclude Calibrate
+  imageViewerPtr->displayImage();
+  for(i=0;i<NUMSSTVMODES;i++)
     {
       ui->sstvModeComboBox->addItem(getSSTVModeNameLong((esstvMode)i));
     }
+
+
   connect(ui->sstvModeComboBox,SIGNAL(activated(int)),SLOT(slotModeChanged(int )));
+
+
   connect(ui->templatesComboBox,SIGNAL(currentIndexChanged(int)),SLOT(slotGetParams()));
   connect(ui->templateCheckBox,SIGNAL(toggled(bool)),SLOT(slotGetParams()));
+  connect(ui->refreshPushButton,SIGNAL(clicked()),SLOT(slotGetParams()));
   connect(ui->cwCheckBox,SIGNAL(toggled(bool)),SLOT(slotGetParams()));
   connect(ui->voxCheckBox,SIGNAL(toggled(bool)),SLOT(slotGetParams()));
   connect(ui->toCallLineEdit,SIGNAL(editingFinished ()),SLOT(slotGetParams()));
   connect(ui->operatorLineEdit,SIGNAL(editingFinished ()),SLOT(slotGetParams()));
   connect(ui->rsvLineEdit,SIGNAL(editingFinished ()),SLOT(slotGetParams()));
-  connect(ui->comment1LineEdit,SIGNAL(editingFinished ()),SLOT(slotGetParams()));
-  connect(ui->comment2LineEdit,SIGNAL(editingFinished ()),SLOT(slotGetParams()));
-  connect(ui->comment3LineEdit,SIGNAL(editingFinished ()),SLOT(slotGetParams()));
+  connect(ui->xPlainTextEdit,SIGNAL(editingFinished()),SLOT(slotGetParams()));
+  connect(ui->yPlainTextEdit,SIGNAL(editingFinished()),SLOT(slotGetParams()));
+  connect(ui->zPlainTextEdit,SIGNAL(editingFinished()),SLOT(slotGetParams()));
+
+
   connect(ui->startToolButton, SIGNAL(clicked()), this, SLOT(slotStart()));
-//  connect(ui->hybridCheckBox, SIGNAL(toggled(bool)), this, SLOT(slotHybridStart(bool)));
   connect(ui->stopToolButton, SIGNAL(clicked()), this, SLOT(slotStop()));
   connect(ui->drmProfileComboBox,SIGNAL(activated(int)),SLOT(slotProfileChanged(int )));
 
@@ -60,23 +66,24 @@ txWidget::txWidget(QWidget *parent) :
   connect(ui->sweepToneToolButton, SIGNAL(clicked()), this, SLOT(slotSweepSignal()));
   connect(ui->repeaterToneToolButton, SIGNAL(clicked()), this, SLOT(slotGenerateRepeaterTone()));
   connect(ui->openToolButton, SIGNAL(clicked()), this, SLOT(slotFileOpen()));
-  //   connect(ui->actionAlignement, SIGNAL(triggered()), this, SLOT(slotAlignementSignal()));
   connect(ui->editToolButton, SIGNAL(clicked()), this, SLOT(slotEdit()));
-  //   connect(ui->actionReplay, SIGNAL(triggered()), this, SLOT(slotReplay()));
   connect(ui->snapshotToolButton, SIGNAL(clicked()), this, SLOT(slotSnapshot()));
-  connect(imageViewerPtr, SIGNAL(imageChanged()), this, SLOT(slotGetParams()));
+  connect(ui->binaryPushButton,SIGNAL(clicked()),this,SLOT(slotBinary()));
   connect(ui->sizeSlider,SIGNAL(valueChanged(int)),SLOT(slotSize(int)));
-  connect(ui->sizeSlider,SIGNAL(sliderReleased()),SLOT(slotSizeApply()));
   connect(ui->settingsTableWidget,SIGNAL(currentChanged(int)),this, SLOT(slotTransmissionMode(int)));
-  connect(ui->imageFrame,SIGNAL(imageChanged()),SLOT(slotImageChanged()));
-
+  connect(imageViewerPtr,SIGNAL(imageChanged()),SLOT(slotImageChanged()));
+  connect(ui->templateCheckBox,SIGNAL(toggled(bool)),SLOT(slotImageChanged()));
+  connect(ui->templatesComboBox,SIGNAL(currentIndexChanged(int)),SLOT(slotImageChanged()));
 
-  currentTXMode=NOMODE;
+  sizeRatio=-1;
 }
 
 txWidget::~txWidget()
 {
-    delete ui;
+  writeSettings();
+  txFunctionsPtr->terminate();
+  delete txFunctionsPtr;
+  delete ui;
 }
 
 void txWidget::init()
@@ -84,26 +91,38 @@ void txWidget::init()
   splashStr+=QString( "Setting up TX" ).rightJustified(25,' ')+"\n";
   splashPtr->showMessage ( splashStr ,Qt::AlignLeft,Qt::white);
   qApp->processEvents();
+
+  readSettings();
+  initView();
+  setProfileNames();
+
   ed=NULL;
   repeaterIndex=0;
-  initView();
+
   repeaterTimer=new QTimer(this);
   connect(repeaterTimer,SIGNAL(timeout()),SLOT(slotRepeaterTimer()));
   repeaterTimer->start(60000*repeaterImageInterval);
   imageViewerPtr->setType(imageViewer::TXIMG);
-  slotModeChanged(modeIndexTx);
-  slotSize(sizeRatio);
-  txFunctionsPtr->start();
-
+  slotModeChanged(sstvModeIndexTx);
+  ui->sizeSlider->setValue(sizeRatio);
+  changeTransmissionMode(transmissionModeIndex);
+  //  setSettingsTab();
+  slotProfileChanged(0);
 }
 
 void txWidget::readSettings()
 {
   QSettings qSettings;
   qSettings.beginGroup("TX");
-  modeIndexTx=((esstvMode)qSettings.value("modeIndexTx",0).toInt());
+  sstvModeIndexTx=((esstvMode)qSettings.value("sstvModeIndexTx",0).toInt());
+  if((sstvModeIndexTx<M1) || (sstvModeIndexTx>=NOTVALID))
+    {
+      sstvModeIndexTx=M1;
+    }
+
   templateIndex=qSettings.value("templateIndex",0).toInt();
   useTemplate=qSettings.value("useTemplate",false).toBool();
+
   useCW=qSettings.value("useCW",false).toBool();
   useVOX=qSettings.value("useVOX",false).toBool();
   useHybrid=qSettings.value("useHybrid",false).toBool();
@@ -123,7 +142,7 @@ void txWidget::writeSettings()
   QSettings qSettings;
   slotGetParams();
   qSettings.beginGroup("TX");
-  qSettings.setValue( "modeIndexTx", modeIndexTx);
+  qSettings.setValue( "sstvModeIndexTx", sstvModeIndexTx);
   qSettings.setValue( "templateIndex", templateIndex);
   qSettings.setValue( "useTemplate", useTemplate);
   qSettings.setValue( "useVOX", useVOX);
@@ -141,9 +160,9 @@ void txWidget::writeSettings()
 
 void txWidget::slotGetParams()
 {
-  int temp=modeIndexTx;
+  int temp=sstvModeIndexTx;
   getIndex(temp,ui->sstvModeComboBox);
-  modeIndexTx=esstvMode(temp);
+  sstvModeIndexTx=esstvMode(temp);
   getIndex(templateIndex,ui->templatesComboBox);
   getValue(useTemplate,ui->templateCheckBox);
   getValue(useVOX,ui->voxCheckBox);
@@ -152,9 +171,9 @@ void txWidget::slotGetParams()
   getValue(imageViewerPtr->toCall,ui->toCallLineEdit);
   getValue(imageViewerPtr->toOperator,ui->operatorLineEdit);
   getValue(imageViewerPtr->rsv,ui->rsvLineEdit);
-  getValue(imageViewerPtr->comment1,ui->comment1LineEdit);
-  getValue(imageViewerPtr->comment2,ui->comment2LineEdit);
-  getValue(imageViewerPtr->comment3,ui->comment3LineEdit);
+  getValue(imageViewerPtr->comment1,ui->xPlainTextEdit);
+  getValue(imageViewerPtr->comment2,ui->yPlainTextEdit);
+  getValue(imageViewerPtr->comment3,ui->zPlainTextEdit);
   getIndex(drmParams.bandwith,ui->drmTxBandwidthComboBox);
   getIndex(drmParams.interleaver,ui->drmTxInterleaveComboBox);
   getIndex(drmParams.protection,ui->drmTxProtectionComboBox);
@@ -163,7 +182,6 @@ void txWidget::slotGetParams()
   getIndex(drmParams.reedSolomon,ui->drmTxReedSolomonComboBox);
   getValue(sizeRatio,ui->sizeSlider);
   drmParams.callsign=myCallsign;
-//  if(!txFunctionsPtr->isRunning())
   if(txFunctionsPtr->getTXState()==txFunctions::TXIDLE)
     {
       applyTemplate();
@@ -172,9 +190,13 @@ void txWidget::slotGetParams()
 
 void txWidget::setParams()
 {
-  setIndex(((int)modeIndexTx),ui->sstvModeComboBox);
+  setIndex(((int)sstvModeIndexTx),ui->sstvModeComboBox);
+  ui->templateCheckBox->blockSignals(true);
+  ui->templatesComboBox->blockSignals(true);
   setIndex(templateIndex,ui->templatesComboBox);
   setValue(useTemplate,ui->templateCheckBox);
+  ui->templateCheckBox->blockSignals(false);
+  ui->templatesComboBox->blockSignals(false);
   setValue(useVOX,ui->voxCheckBox);
   setValue(useCW,ui->cwCheckBox);
   setValue(useHybrid,ui->hybridCheckBox);
@@ -200,30 +222,39 @@ void txWidget::copyProfile(drmTxParams d)
 
 void txWidget::initView()
 {
-  ui->sstvModeComboBox->setCurrentIndex((int)modeIndexTx);
+  imageViewerPtr->createImage(QSize(320,256),imageBackGroundColor,imageStretch);
+  imageViewerPtr->setType(imageViewer::TXIMG);
   setupTemplatesComboBox();
-  ui->progressBar->setRange(0,100);
+  ui->txProgressBar->setRange(0,100);
 }
 
+
 void txWidget::setupTemplatesComboBox()
 {
   QStringList sl;
-   int i;
+  int i;
   ui->templatesComboBox->clear();
   sl=galleryWidgetPtr->getFilenames();
   for(i=0;i<sl.count();i++)
-  {
-    ui->templatesComboBox->insertItem(i,sl.at(i));
-  }
-   ui->templatesComboBox->setCurrentIndex(templateIndex);
+    {
+      ui->templatesComboBox->insertItem(i,sl.at(i));
+    }
+  ui->templatesComboBox->setCurrentIndex(templateIndex);
+}
+
+
+QString txWidget::getPreviewFilename()
+{
+  return ui->previewWidget->getFilename();
 }
 
 void  txWidget::setPreviewWidget(QString fn)
 {
-   ui->previewWidget->openImage(fn,false,false);
+
+  ui->previewWidget->openImage(fn,false,false,false);
 }
 
-void txWidget::start(bool st,bool check)
+void txWidget::startTX(bool st,bool check)
 {
   if(st)
     {
@@ -236,7 +267,6 @@ void txWidget::start(bool st,bool check)
               return;
             }
         }
-      soundIOPtr->startPlayback();
     }
   else
     {
@@ -247,41 +277,39 @@ void txWidget::start(bool st,bool check)
 
 void txWidget::slotStart()
 {
-//  start(true);
-  QFileInfo finf;
+  QDateTime dt(QDateTime::currentDateTime().toUTC()); //this is compatible with QT 4.6
+  dt.setTimeSpec(Qt::UTC);
+  if(!imageViewerPtr->hasValidImage()) return;
+  QFileInfo finf=imageViewerPtr->getFilename();
   QString fn;
   slotGetParams();
-  switch(currentTXMode)
+  switch(transmissionModeIndex)
     {
-    case SSTV:
-       dispatcherPtr->startSSTVTx();
-    break;
-    case DRM:
-      txFunctionsPtr->setDRMTxParams(drmParams);
-      if(ui->hybridCheckBox->isChecked())
+    case TRXSSTV:
+      if(saveTXimages)
         {
-          finf.setFile(txWidgetPtr->getImageViewerPtr()->getFilename());
-
-          fn="de_"+myCallsign+"-1-"+finf.baseName()+"."+finf.suffix();
-          txFunctionsPtr->setHybrid(true,fn);
-          dispatcherPtr->startDRMHybridTx(fn);
+          fn=QString("%1/%2_%3.%4").arg(txSSTVImagesPath).arg(finf.baseName()).arg(dt.toString("yyyyMMdd_HHmmss")).arg(defaultImageFormat);
+          imageViewerPtr->save(fn,defaultImageFormat,true,false);
+          galleryWidgetPtr->txImageChanged();
         }
-      else
+      dispatcherPtr->startTX(txFunctions::TXSSTVIMAGE);
+      break;
+    case TRXDRM:
+      if(saveTXimages)
         {
-          txFunctionsPtr->setHybrid(false);
-          dispatcherPtr->startDRMTx();
+          fn=QString("%1/%2_%3.%4").arg(txDRMImagesPath).arg(finf.baseName()).arg(dt.toString("yyyyMMdd_HHmmss")).arg(defaultImageFormat);
+          imageViewerPtr->save(fn,defaultImageFormat,true,false);
+          galleryWidgetPtr->txImageChanged();
         }
-
-
-    break;
-//    case FAX:
-//    break;
-    case NOMODE:
+      dispatcherPtr->startTX(txFunctions::TXSENDDRM);
+      break;
+      //    case FAX:
+      //    break;
+    case TRXNOMODE:
       break;
     }
 }
 
-
 void txWidget::sendBSR()
 {
   QByteArray *p;
@@ -291,15 +319,16 @@ void txWidget::sendBSR()
   res=(bsrForm::eResult)bsrf.exec();
   if(res==bsrForm::CANCEL) return;
   p=bsrf.getBA(res==bsrForm::COMPAT);
-  drmParams=bsrf.getDRMParams();
-  txFunctionsPtr->setDRMTxParams(drmParams);
-  dispatcherPtr->startDRMBSRTx(p);
+  txFunctionsPtr->sendBSR(p,bsrf.getDRMParams());
 }
 
 
 void txWidget::sendID()
 {
-  dispatcherPtr->sendWF(myCallsign);
+
+  waterfallPtr->setText(myCallsign);
+  dispatcherPtr->startTX(txFunctions::TXSENDID);
+  addToLog("sendID",LOGTXMAIN);
 }
 
 void txWidget::sendWfText()
@@ -307,22 +336,21 @@ void txWidget::sendWfText()
   waterfallForm wf;
   if((wf.exec()==QDialog::Accepted)&&(!wf.text().isEmpty()))
     {
-      dispatcherPtr->sendWF(wf.text());
+      waterfallPtr->setText(wf.text());
+      dispatcherPtr->startTX(txFunctions::TXSENDID);
+      addToLog("sendID",LOGTXMAIN);
     }
 }
 
 void txWidget::slotStop()
 {
-//  qDebug() << "slotStop tx";
-  soundIOPtr->abortPlayback();
-  start(false);
-  dispatcherPtr->restartRX();
+  dispatcherPtr->startRX();
 }
 
 
 void txWidget::slotDisplayStatusMessage(QString s)
 {
-    statusBarPtr->showMessage(s);
+  statusBarPtr->showMessage(s);
 }
 
 
@@ -347,13 +375,13 @@ void txWidget::slotDisplayStatusMessage(QString s)
 void txWidget::slotFileOpen()
 {
   QString fileName;
-  imageViewerPtr->openImage(fileName,txImagesPath,true,true,true);
+  imageViewerPtr->openImage(fileName,txStockImagesPath,true,true,true,false);
 }
 
 void txWidget::slotGenerateSignal()
 {
   QDialog qd;
-   Ui::freqForm *ff=new Ui::freqForm;
+  Ui::freqForm *ff=new Ui::freqForm;
 
   ff->setupUi(&qd);
   int freq;
@@ -362,14 +390,15 @@ void txWidget::slotGenerateSignal()
     {
       getValue(freq,ff->frequencySpinBox);
       getValue(duration,ff->durationSpinBox);
-      dispatcherPtr->sendTone((double)duration,(double)freq);
+      txFunctionsPtr->setToneParam((double)duration,(double)freq);
+      dispatcherPtr->startTX(txFunctions::TXSENDTONE);
     }
 }
 
 void txWidget::slotSweepSignal()
 {
   QDialog qd;
- Ui::sweepForm *ff=new Ui::sweepForm;
+  Ui::sweepForm *ff=new Ui::sweepForm;
   ff->setupUi(&qd);
   int upperFreq;
   int lowerFreq;
@@ -379,19 +408,24 @@ void txWidget::slotSweepSignal()
       getValue(lowerFreq,ff->lowerFrequencySpinBox);
       getValue(upperFreq,ff->upperFrequencySpinBox);
       getValue(duration,ff->durationSpinBox);
-      dispatcherPtr->sendSweepTone((double)duration,(double)lowerFreq,(double)upperFreq);
+      txFunctionsPtr->setToneParam((double)duration,(double)lowerFreq,(double)upperFreq);
+      dispatcherPtr->startTX(txFunctions::TXSENDTONE);
     }
 }
 
 
+
 void txWidget::slotGenerateRepeaterTone()
 {
-  addToLog(QString("start of buffer %1").arg(soundIOPtr->txBuffer.count()),LOGTXMAIN);
-  dispatcherPtr->sendTone(3.,1750);
+  //  addToLog(QString("start of buffer %1").arg(soundIOPtr->txBuffer.count()),LOGTXMAIN);
+  txFunctionsPtr->setToneParam(3.,1750);
+  dispatcherPtr->startTX(txFunctions::TXSENDTONE);
+  addToLog("sendTone",LOGTXMAIN);
 }
 
 
 
+
 void txWidget::slotEdit()
 {
   if (ed!=NULL) delete ed;
@@ -407,49 +441,41 @@ void txWidget::slotEdit()
 }
 
 
-void txWidget::slotModeChanged(int m)
-{
-  addToLog("slotModeChange",LOGTXMAIN);
-  modeIndexTx=(esstvMode)m;
-//  txFunctionsPtr->create(modeIndexTx,txClock/SUBSAMPLINGRATIO);
-  applyTemplate();
-}
-
-
 
 
 /** \todo implement repeater */
 void txWidget::applyTemplate()
 {
-  if(currentTXMode!=DRM)
-    {
-      txFunctionsPtr->create(modeIndexTx,txClock/SUBSAMPLINGRATIO);
-      imageViewerPtr->applyTemplate(galleryWidgetPtr->getTemplateFileName(ui->templatesComboBox->currentIndex()),useTemplate, txSSTVParam.numberOfPixels,txSSTVParam.numberOfDisplayLines);
-    }
-  else
-    {
-      slotSize(sizeRatio);
-      imageViewerPtr->applyTemplate(galleryWidgetPtr->getTemplateFileName(ui->templatesComboBox->currentIndex()),useTemplate);
-    }
+  txFunctionsPtr->applyTemplate(imageViewerPtr,galleryWidgetPtr->getTemplateFileName(ui->templatesComboBox->currentIndex()));
 }
 
-void 	txWidget::setImage(QImage *im)
-{
-  if(imageViewerPtr->openImage(*im))
-    {
-      applyTemplate();
-    }
-}
+//void 	txWidget::setImage(QImage *im)
+//{
+//  if(imageViewerPtr->openImage(*im))
+//    {
+//      applyTemplate();
+//    }
+//}
 
 void 	txWidget::setImage(QString fn)
 {
-  imageViewerPtr->openImage(fn,true,true);
+  imageViewerPtr->openImage(fn,true,true,false);
 }
 
 
 void txWidget::setProgress(uint prg)
 {
-  ui->progressBar->setValue(prg);
+  ui->txProgressBar->setValue(prg);
+}
+
+void txWidget::slotModeChanged(int m)
+{
+  addToLog("slotModeChange",LOGTXMAIN);
+  if(transmissionModeIndex==TRXSSTV)
+    {
+      sstvModeIndexTx=(esstvMode)m;
+      applyTemplate();
+    }
 }
 
 
@@ -458,7 +484,7 @@ void txWidget::setProgress(uint prg)
 // void txWidget::repeat(QImage *im,esstvMode sm)
 void txWidget::repeat(QImage *,esstvMode )
 {
-/*	setValue((int)sm,ui->modeComboBox);
+  /*	setValue((int)sm,ui->modeComboBox);
   txf->setModeIndex((sstvMode)sm);
 //	slotModeChanged(sm);
 
@@ -482,20 +508,20 @@ void txWidget::slotRepeaterTimer()
     {
       switch(repeaterIndex)
         {
-          case 0:
-            fn=repeaterImage1;
+        case 0:
+          fn=repeaterImage1;
           break;
-          case 1:
-            fn=repeaterImage2;
+        case 1:
+          fn=repeaterImage2;
           break;
-          case 2:
-            fn=repeaterImage3;
+        case 2:
+          fn=repeaterImage3;
           break;
-          case 3:
-            fn=repeaterImage4;
+        case 3:
+          fn=repeaterImage4;
           break;
-          default:
-            fn=repeaterImage1;
+        default:
+          fn=repeaterImage1;
           break;
         }
       fi.setFileName(fn);
@@ -517,160 +543,51 @@ void txWidget::slotRepeaterTimer()
 
 void txWidget::slotSnapshot()
 {
-  cameraControl cc(this);
-  if(cc.exec())
+  QImage *im;
+  cameraDialog camera;
+  if(camera.exec()==QDialog::Accepted)
     {
-      setImage(cc.getImage());
+      im=camera.getImage();
+      if(im)
+        {
+          QTemporaryFile itmp(txStockImagesPath+"/snapshotXXXXXX.jpg");
+          itmp.setAutoRemove(false);
+          if(!itmp.open()) return;
+          im->save(itmp.fileName());
+          setImage(itmp.fileName());
+          galleryWidgetPtr->txStockImageChanged();
+        }
     }
 }
 
 
 
-
-
-//void txWidget::test()
-//{
-
-//}
-
 void txWidget::setSettingsTab()
 {
-  int i;
-  currentTXMode=transmissionModeIndex;
   {
-    if(currentTXMode==DRM)
+    if(transmissionModeIndex==TRXDRM)
       {
         ui->hybridCheckBox->setEnabled(true);
+        ui->binaryPushButton->setEnabled(true);
+        ui->sizeLabel->setEnabled(true);
+        ui->sizeSlider->setEnabled(true);
+        ui->sizeKbLabel->setEnabled(true);
+        mainWindowPtr->setSSTVDRMPushButton(true);
       }
     else
       {
         ui->hybridCheckBox->setEnabled(false);
+        ui->binaryPushButton->setEnabled(false);
+        ui->sizeLabel->setEnabled(false);
+        ui->sizeSlider->setEnabled(false);
+        ui->sizeKbLabel->setEnabled(false);
+        mainWindowPtr->setSSTVDRMPushButton(false);
       }
-
   }
 
-  if((transmissionModeIndex>=0)&&(transmissionModeIndex<NOMODE))
-    {
-      for(i=0;i<NOMODE;i++)
-        {
-          if(i!=transmissionModeIndex) ui->settingsTableWidget->widget(i)->setEnabled(false);
-        }
-      ui->settingsTableWidget->widget(transmissionModeIndex)->setEnabled(true);
-      ui->settingsTableWidget->setCurrentIndex(transmissionModeIndex);
-    }
   applyTemplate();
 }
 
-bool txWidget::prepareFIX(QByteArray bsrByteArray)
-{
-  int i,j;
-  displayMBoxEvent *stce;
-//  unsigned int mode=0;
-//  eRSType rsType;
-  bool inSeries;
-  QString fileName,extension;
-  txSession *sessionPtr;
-  bool extended,done;
-  int block;
-  unsigned short trID,lastBlock;
-
-  fixBlockList.clear();
-  txFunctionsPtr->setHybrid(true);
-  QString str(bsrByteArray);
-  str.replace("\r","");
-  //  information is in the QByteArray ba
-  QStringList sl;
-  sl=str.split("\n",QString::SkipEmptyParts);
-
-  if(sl.at(1)!="H_OK")
-    {
-      return false;
-    }
-  trID=sl.at(0).toUInt();
-  lastBlock=sl.at(3).toUInt();
-  fixBlockList.append(lastBlock++);
-  inSeries=false;
-  done=false;
-  extended=false;
-  for(i=4;(!done)&&i<sl.count();i++)
-    {
-      block=sl.at(i).toInt();
-      if(block==-99)
-        {
-          done=true;
-          i++;
-          break;
-        }
-      if(block<0) inSeries=true;
-      else
-        {
-          if(inSeries)
-            {
-              inSeries=false;
-              for(j=lastBlock;j<block;j++) fixBlockList.append(j);
-            }
-          fixBlockList.append(block);
-          lastBlock=block+1;
-        }
-    }
-  // check if we have a filename beyond -99
-  if((i+1)<sl.count()) // we need an additional 2 entries (filename and mode)
-    {
-      extended=true;
-      fileName=sl.at(i++);
-//      mode=sl.at(i).toUInt();
-//      qDebug() << " bsr received with " << fileName << mode;
-    }
-  fixForm fx(mainWindowPtr);
-  sessionPtr=txFunctionsPtr->getSessionPtr(trID);
-  if ((sessionPtr==NULL) && (!extended))
-    {
-      stce= new displayMBoxEvent("BSR Received","This BSR is not for you");
-      QApplication::postEvent( dispatcherPtr, stce );  // Qt will delete it when done
-
-      return false;
-    }
-  else if (sessionPtr!=NULL)
-    {
-      // take it from the transmitlist
-
-      fx.setInfoInternal(paramsToMode(sessionPtr->drmParams),sessionPtr->filename,fixBlockList.count(),&sessionPtr->ba);
-      if(fx.exec()==QDialog::Rejected) return false;
-      txFunctionsPtr->initDRMFIX(sessionPtr);
-     }
-  else
-    {
-      QMessageBox *mbox = new QMessageBox(this);
-      mbox->setWindowTitle(tr("BSR Received"));
-      mbox->setText("This BSR is not for you");
-      mbox->show();
-      QTimer::singleShot(4000, mbox, SLOT(hide()));
-      return false;
-    }
-  return true;
-}
-
-//bool txWidget::prepareHybrid(QString fn)
-//{
-//  txFunctionsPtr->setHybrid(true);
-//  return true;
-//}
-
-bool txWidget::prepareText(QString )
-{
-  txFunctionsPtr->setHybrid(false);
-//  QString fn;
-//  QDateTime dt(QDateTime::currentDateTime().toUTC()); //this is compatible with QT 4.6
-//  dt.setTimeSpec(Qt::UTC);
-//  dt
-//  int intdate=dt.date().year()*10000+dt.date().month()*100+dt.date().day();
-//  int inttime=dt.time().hour()*10000+100*dt.time().minute()+dt.time().second();
-//  s.sprintf("%s_%d_%d",rxWidgetPtr->functionsPtr()->getModeString().toLatin1().data(),intdate,inttime);
-//  fileName=rxImagesPath+"/"+s+"."+defaultImageFormat;
-//  QFile fo("de ON4QZ")
-  return true;
-}
-
 
 void txWidget::slotSize(int v)
 {
@@ -679,62 +596,65 @@ void txWidget::slotSize(int v)
     {
       sizeRatioChanged=true;
       sizeRatio=v;
-      ui->sizeKbLabel->setText( QString::number(imageViewerPtr->calcSize(v))+ "kB");
+      slotSizeApply();
     }
 }
 
 void txWidget::slotSizeApply()
 {
+  float fileSize;
   QApplication::setOverrideCursor(Qt::WaitCursor);
   sizeRatioChanged=false;
-  imageViewerPtr->setSizeRatio(sizeRatio);
-  imageViewerPtr->displayImage(currentTXMode==DRM);
+  fileSize=imageViewerPtr->setSizeRatio(sizeRatio,transmissionModeIndex==TRXDRM);
+  imageViewerPtr->displayImage();
+  ui->sizeKbLabel->setText( QString::number(fileSize/1000)+ "kB");
+  applyTemplate();
   QApplication::restoreOverrideCursor();
 }
 
 void txWidget::slotTransmissionMode(int rxtxMode)
 {
+  emit modeSwitch(rxtxMode);
+}
+
+void txWidget::changeTransmissionMode(int rxtxMode)
+{
+  int i;
   transmissionModeIndex=(etransmissionMode)rxtxMode;
-  start(false);
-  rxWidgetPtr->setSettingsTab();
-  setSettingsTab();
-  if(transmissionModeIndex==DRM)
+  if((transmissionModeIndex>=0)&&(transmissionModeIndex<TRXNOMODE))
     {
-      ui->sizeLabel->setEnabled(true);
-      ui->sizeSlider->setEnabled(true);
-      ui->sizeKbLabel->setEnabled(true);
-//      ui->sizeApplyPushButton->setEnabled(true);
-      mainWindowPtr->setBSRPushButton(true);
-    }
-  else
-    {
-      ui->sizeLabel->setEnabled(false);
-      ui->sizeSlider->setEnabled(false);
-      ui->sizeKbLabel->setEnabled(false);
-//      ui->sizeApplyPushButton->setEnabled(false);
-      mainWindowPtr->setBSRPushButton(false);
+      for(i=0;i<TRXNOMODE;i++)
+        {
+          if(i!=transmissionModeIndex) ui->settingsTableWidget->widget(i)->setEnabled(false);
+        }
+      ui->settingsTableWidget->widget(transmissionModeIndex)->setEnabled(true);
+      ui->settingsTableWidget->blockSignals(true);
+      ui->settingsTableWidget->setCurrentIndex(transmissionModeIndex);
+      ui->settingsTableWidget->blockSignals(false);
+
     }
+  setSettingsTab();
 }
 
 void txWidget::slotProfileChanged(int i)
 {
-    drmProfilePtr->getDRMParams(i,drmParams);
-    setParams();
+  drmProfileConfigPtr->getDRMParams(i,drmParams);
+  setParams();
 }
 
 void txWidget::setProfileNames()
 {
-    QString tmp;
-    ui->drmProfileComboBox->clear();
-    if(drmProfilePtr->getName(0,tmp))
+  QString tmp;
+  ui->drmProfileComboBox->clear();
+  if(drmProfileConfigPtr->getName(0,tmp))
     {
       ui->drmProfileComboBox->addItem(tmp);
     }
-    if(drmProfilePtr->getName(1,tmp))
+  if(drmProfileConfigPtr->getName(1,tmp))
     {
       ui->drmProfileComboBox->addItem(tmp);
     }
-    if(drmProfilePtr->getName(2,tmp))
+  if(drmProfileConfigPtr->getName(2,tmp))
     {
       ui->drmProfileComboBox->addItem(tmp);
     }
@@ -742,8 +662,21 @@ void txWidget::setProfileNames()
 
 void txWidget::slotImageChanged()
 {
-    int sz=sizeRatio;
-    sizeRatio=0;
-    slotSize(sz);
-    slotSizeApply();
+  int temp=sizeRatio;
+  sizeRatio=-1;
+  slotSize(temp);
+}
+
+void txWidget::slotBinary()
+{
+  slotGetParams();
+  dispatcherPtr->startDRMTxBinary();
 }
+
+
+
+
+
+
+
+
diff --git a/qsstv/txwidget.h b/qsstv/mainwidgets/txwidget.h
similarity index 53%
rename from qsstv/txwidget.h
rename to qsstv/mainwidgets/txwidget.h
index ff1fa38..ed947b7 100644
--- a/qsstv/txwidget.h
+++ b/qsstv/mainwidgets/txwidget.h
@@ -1,26 +1,29 @@
 #ifndef TXWIDGET_H
 #define TXWIDGET_H
 
-#include <QWidget>
-#include "widgets/imageviewer.h"
-#include "sstv/sstvparam.h"
+
+#include "imageviewer.h"
+#include "sstvparam.h"
 #include "txfunctions.h"
-#include "drmtx/drmtransmitter.h"
+#include "drmtransmitter.h"
+#include "ui_txwidget.h"
+
+#include <QWidget>
 
 class drmTransmitter;
 namespace Ui {
-    class txWidget;
+class txWidget;
 }
 
 class txWidget : public QWidget
 {
-    Q_OBJECT
+  Q_OBJECT
 
 public:
   explicit txWidget(QWidget *parent = 0);
-    ~txWidget();
+  ~txWidget();
   void init();
-  void start(bool st, bool check=true);
+  void startTX(bool st, bool check=true);
   void writeSettings();
   void readSettings();
   imageViewer *getImagePtr();
@@ -33,15 +36,25 @@ public:
   void setSettingsTab();
   txFunctions *functionsPtr() {return txFunctionsPtr;}
   imageViewer *getImageViewerPtr(){ return imageViewerPtr;}
-  bool prepareFIX(QByteArray bsrByteArray);
-//  bool prepareHybrid(QString fn);
+  QString getPreviewFilename();
+
+  void setDRMNotifyText(QString txt) {      
+      //ui->txNotificationList->clear();                 
+      ui->txNotificationList->setPlainText(txt);
+      }
+  void appendDRMNotifyText(QString txt) {      
+      ui->txNotificationList->appendPlainText(txt);
+      }
+
+  //  bool prepareHybrid(QString fn);
   bool prepareText(QString txt);
   void copyProfile(drmTxParams d);
   void setProfileNames();
+  void changeTransmissionMode(int rxtxMode);
 
 
-//  void test();
-//  void sendFIX();
+  //  void test();
+  //  void sendFIX();
   void sendBSR();
   void sendWfText();
   void sendID();
@@ -56,39 +69,42 @@ public slots:
   void slotSweepSignal();
   void slotGenerateRepeaterTone();
   void slotEdit();
-//  void slotReplay();
+  //  void slotReplay();
   void slotRepeaterTimer();
   void slotFileOpen();
-  void slotModeChanged(int);
+
   void slotSnapshot();
-  void slotSize(int);
+  void slotSize(int v);
   void slotSizeApply();
   void slotTransmissionMode(int rxtxMode);
   void slotProfileChanged(int );
   void slotImageChanged();
+  void slotModeChanged(int);
+  void slotBinary();
 
-private:
-    Ui::txWidget *ui;
-    txFunctions *txFunctionsPtr;
-    void initView();
-    void setParams();
-    editor *ed;
-    QTimer *repeaterTimer;
-    int repeaterIndex;
-    QImage origImage;
-    QImage resultImage;
-    void applyTemplate();
-    imageViewer *imageViewerPtr;
-    etransmissionMode currentTXMode;
-    drmTxParams drmParams;
-    int sizeRatio;
-    bool sizeRatioChanged;
-    int drmProfileIdx;
+signals:
+  void modeSwitch(int);
 
+private:
+  Ui::txWidget *ui;
+  txFunctions *txFunctionsPtr;
+  void initView();
+  void setParams();
+  void sendHybrid(QString fn);
+  editor *ed;
+  QTimer *repeaterTimer;
+  int repeaterIndex;
+  QImage origImage;
+  QImage resultImage;
+  void applyTemplate();
+  imageViewer *imageViewerPtr;
+  etransmissionMode currentTXMode;
+  int sizeRatio;
+  bool sizeRatioChanged;
+  int drmProfileIdx;
+  QString previewFilename;
 };
 
-extern txWidget *txWidgetPtr;
-
 #endif // TXWIDGET_H
 
 
@@ -97,3 +113,11 @@ extern txWidget *txWidgetPtr;
 
 
 
+
+
+
+
+
+
+
+
diff --git a/qsstv/txwidget.ui b/qsstv/mainwidgets/txwidget.ui
similarity index 88%
rename from qsstv/txwidget.ui
rename to qsstv/mainwidgets/txwidget.ui
index 80a221d..7c1342f 100644
--- a/qsstv/txwidget.ui
+++ b/qsstv/mainwidgets/txwidget.ui
@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>840</width>
-    <height>529</height>
+    <width>990</width>
+    <height>835</height>
    </rect>
   </property>
   <property name="font">
@@ -18,11 +18,26 @@
   <property name="windowTitle">
    <string>Form</string>
   </property>
-  <layout class="QHBoxLayout" name="horizontalLayout_7">
+  <layout class="QHBoxLayout" name="horizontalLayout_9" stretch="2,0">
+   <property name="spacing">
+    <number>2</number>
+   </property>
+   <property name="leftMargin">
+    <number>0</number>
+   </property>
+   <property name="topMargin">
+    <number>0</number>
+   </property>
+   <property name="rightMargin">
+    <number>0</number>
+   </property>
+   <property name="bottomMargin">
+    <number>0</number>
+   </property>
    <item>
     <layout class="QVBoxLayout" name="verticalLayout_2" stretch="0,1,0">
      <item>
-      <layout class="QHBoxLayout" name="horizontalLayout_5">
+      <layout class="QHBoxLayout" name="horizontalLayout_5" stretch="0,0,0,0,0,0,0,1,0,3,0,0">
        <property name="spacing">
         <number>2</number>
        </property>
@@ -38,7 +53,7 @@
           <string>...</string>
          </property>
          <property name="icon">
-          <iconset resource="qsstv.qrc">
+          <iconset resource="../qsstv.qrc">
            <normaloff>:/icons/start.png</normaloff>:/icons/start.png</iconset>
          </property>
         </widget>
@@ -55,7 +70,7 @@
           <string>...</string>
          </property>
          <property name="icon">
-          <iconset resource="qsstv.qrc">
+          <iconset resource="../qsstv.qrc">
            <normaloff>:/icons/stop.png</normaloff>:/icons/stop.png</iconset>
          </property>
         </widget>
@@ -72,7 +87,7 @@
           <string>...</string>
          </property>
          <property name="icon">
-          <iconset resource="qsstv.qrc">
+          <iconset resource="../qsstv.qrc">
            <normaloff>:/icons/tone.png</normaloff>:/icons/tone.png</iconset>
          </property>
         </widget>
@@ -89,7 +104,7 @@
           <string>...</string>
          </property>
          <property name="icon">
-          <iconset resource="qsstv.qrc">
+          <iconset resource="../qsstv.qrc">
            <normaloff>:/icons/fileopen.png</normaloff>:/icons/fileopen.png</iconset>
          </property>
         </widget>
@@ -106,7 +121,7 @@
           <string>...</string>
          </property>
          <property name="icon">
-          <iconset resource="qsstv.qrc">
+          <iconset resource="../qsstv.qrc">
            <normaloff>:/icons/edit.png</normaloff>:/icons/edit.png</iconset>
          </property>
         </widget>
@@ -123,12 +138,33 @@
           <string>...</string>
          </property>
          <property name="icon">
-          <iconset resource="qsstv.qrc">
+          <iconset resource="../qsstv.qrc">
            <normaloff>:/icons/camera.png</normaloff>:/icons/camera.png</iconset>
          </property>
         </widget>
        </item>
        <item>
+        <widget class="QPushButton" name="binaryPushButton">
+         <property name="icon">
+          <iconset resource="../qsstv.qrc">
+           <normaloff>:/icons/binary.png</normaloff>:/icons/binary.png</iconset>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <spacer name="horizontalSpacer_4">
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>10</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item>
         <widget class="QCheckBox" name="hybridCheckBox">
          <property name="text">
           <string>Hybrid</string>
@@ -160,7 +196,7 @@
           <string>...</string>
          </property>
          <property name="icon">
-          <iconset resource="qsstv.qrc">
+          <iconset resource="../qsstv.qrc">
            <normaloff>:/icons/doubletone.png</normaloff>:/icons/doubletone.png</iconset>
          </property>
         </widget>
@@ -177,7 +213,7 @@
           <string>...</string>
          </property>
          <property name="icon">
-          <iconset resource="qsstv.qrc">
+          <iconset resource="../qsstv.qrc">
            <normaloff>:/icons/sweep.png</normaloff>:/icons/sweep.png</iconset>
          </property>
         </widget>
@@ -188,14 +224,14 @@
       <widget class="imageViewer" name="imageFrame" native="true">
        <property name="minimumSize">
         <size>
-         <width>580</width>
-         <height>360</height>
+         <width>320</width>
+         <height>256</height>
         </size>
        </property>
        <property name="maximumSize">
         <size>
-         <width>1200</width>
-         <height>800</height>
+         <width>16777215</width>
+         <height>16777215</height>
         </size>
        </property>
       </widget>
@@ -215,7 +251,7 @@
           <number>1</number>
          </property>
          <property name="maximum">
-          <number>100</number>
+          <number>200</number>
          </property>
          <property name="pageStep">
           <number>10</number>
@@ -223,12 +259,24 @@
          <property name="sliderPosition">
           <number>25</number>
          </property>
+         <property name="tracking">
+          <bool>false</bool>
+         </property>
          <property name="orientation">
           <enum>Qt::Horizontal</enum>
          </property>
+         <property name="invertedAppearance">
+          <bool>false</bool>
+         </property>
+         <property name="invertedControls">
+          <bool>false</bool>
+         </property>
          <property name="tickPosition">
           <enum>QSlider::TicksBelow</enum>
          </property>
+         <property name="tickInterval">
+          <number>2</number>
+         </property>
         </widget>
        </item>
        <item>
@@ -269,7 +317,7 @@
    <item>
     <layout class="QVBoxLayout" name="verticalLayout_3">
      <property name="spacing">
-      <number>1</number>
+      <number>2</number>
      </property>
      <item>
       <widget class="QTabWidget" name="settingsTableWidget">
@@ -740,7 +788,20 @@
            <item>
             <layout class="QHBoxLayout" name="horizontalLayout_4">
              <item>
-              <widget class="QLabel" name="rstLabel_7">
+              <spacer name="horizontalSpacer_6">
+               <property name="orientation">
+                <enum>Qt::Horizontal</enum>
+               </property>
+               <property name="sizeHint" stdset="0">
+                <size>
+                 <width>40</width>
+                 <height>20</height>
+                </size>
+               </property>
+              </spacer>
+             </item>
+             <item>
+              <widget class="QLabel" name="modeLabel">
                <property name="text">
                 <string>Mode</string>
                </property>
@@ -786,67 +847,41 @@
          <string>DRM</string>
         </attribute>
         <layout class="QVBoxLayout" name="verticalLayout">
-         <property name="spacing">
-          <number>1</number>
-         </property>
-         <property name="margin">
-          <number>1</number>
-         </property>
          <item>
           <layout class="QGridLayout" name="gridLayout_2">
            <property name="spacing">
-            <number>0</number>
+            <number>2</number>
            </property>
-           <item row="1" column="0">
-            <widget class="QLabel" name="drmQAMLabel">
-             <property name="minimumSize">
-              <size>
-               <width>30</width>
-               <height>0</height>
-              </size>
-             </property>
-             <property name="text">
-              <string>QAM</string>
-             </property>
-             <property name="alignment">
-              <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-             </property>
-             <property name="wordWrap">
-              <bool>false</bool>
-             </property>
-            </widget>
-           </item>
-           <item row="3" column="1">
-            <widget class="QComboBox" name="drmTxReedSolomonComboBox">
-             <item>
-              <property name="text">
-               <string>None</string>
-              </property>
-             </item>
+           <item row="2" column="2">
+            <widget class="QComboBox" name="drmTxInterleaveComboBox">
              <item>
               <property name="text">
-               <string>RS1</string>
+               <string>Short</string>
               </property>
              </item>
              <item>
               <property name="text">
-               <string>RS2</string>
+               <string>Long</string>
               </property>
              </item>
+            </widget>
+           </item>
+           <item row="1" column="2">
+            <widget class="QComboBox" name="drmTxProtectionComboBox">
              <item>
               <property name="text">
-               <string>RS3</string>
+               <string>High</string>
               </property>
              </item>
              <item>
               <property name="text">
-               <string>RS4</string>
+               <string>Low</string>
               </property>
              </item>
             </widget>
            </item>
-           <item row="0" column="0">
-            <widget class="QLabel" name="drmModeLabel">
+           <item row="0" column="3">
+            <widget class="QLabel" name="drmQAMLabel">
              <property name="minimumSize">
               <size>
                <width>30</width>
@@ -854,7 +889,7 @@
               </size>
              </property>
              <property name="text">
-              <string>Mode</string>
+              <string>QAM</string>
              </property>
              <property name="alignment">
               <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
@@ -864,7 +899,26 @@
              </property>
             </widget>
            </item>
-           <item row="3" column="0">
+           <item row="0" column="2">
+            <widget class="QComboBox" name="drmTxModeComboBox">
+             <item>
+              <property name="text">
+               <string>A</string>
+              </property>
+             </item>
+             <item>
+              <property name="text">
+               <string>B</string>
+              </property>
+             </item>
+             <item>
+              <property name="text">
+               <string>E</string>
+              </property>
+             </item>
+            </widget>
+           </item>
+           <item row="2" column="3">
             <widget class="QLabel" name="drmReadSolomonLabel">
              <property name="minimumSize">
               <size>
@@ -884,7 +938,7 @@
             </widget>
            </item>
            <item row="2" column="0">
-            <widget class="QLabel" name="drmProtectionLabel">
+            <widget class="QLabel" name="drmInterleavelabel">
              <property name="minimumSize">
               <size>
                <width>30</width>
@@ -892,7 +946,7 @@
               </size>
              </property>
              <property name="text">
-              <string>Prot.</string>
+              <string>Interleave</string>
              </property>
              <property name="alignment">
               <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
@@ -902,72 +956,70 @@
              </property>
             </widget>
            </item>
-           <item row="2" column="4">
-            <widget class="QSpinBox" name="drmTxInstancesSpinBox"/>
-           </item>
-           <item row="0" column="4">
-            <widget class="QComboBox" name="drmTxBandwidthComboBox">
+           <item row="0" column="4" colspan="2">
+            <widget class="QComboBox" name="drmTxQAMComboBox">
              <item>
               <property name="text">
-               <string>2.2 KHz</string>
+               <string>4</string>
               </property>
              </item>
              <item>
               <property name="text">
-               <string>2.5 KHz</string>
+               <string>16</string>
               </property>
              </item>
-            </widget>
-           </item>
-           <item row="0" column="1">
-            <widget class="QComboBox" name="drmTxModeComboBox">
              <item>
               <property name="text">
-               <string>A</string>
+               <string>64</string>
               </property>
              </item>
+            </widget>
+           </item>
+           <item row="1" column="4" colspan="2">
+            <widget class="QComboBox" name="drmTxBandwidthComboBox">
              <item>
               <property name="text">
-               <string>B</string>
+               <string>2.2 KHz</string>
               </property>
              </item>
              <item>
               <property name="text">
-               <string>E</string>
+               <string>2.5 KHz</string>
               </property>
              </item>
             </widget>
            </item>
-           <item row="1" column="4">
-            <widget class="QComboBox" name="drmTxInterleaveComboBox">
+           <item row="2" column="4" colspan="2">
+            <widget class="QComboBox" name="drmTxReedSolomonComboBox">
              <item>
               <property name="text">
-               <string>Short</string>
+               <string>None</string>
               </property>
              </item>
              <item>
               <property name="text">
-               <string>Long</string>
+               <string>RS1</string>
               </property>
              </item>
-            </widget>
-           </item>
-           <item row="2" column="1">
-            <widget class="QComboBox" name="drmTxProtectionComboBox">
              <item>
               <property name="text">
-               <string>High</string>
+               <string>RS2</string>
               </property>
              </item>
              <item>
               <property name="text">
-               <string>Low</string>
+               <string>RS3</string>
+              </property>
+             </item>
+             <item>
+              <property name="text">
+               <string>RS4</string>
               </property>
              </item>
             </widget>
            </item>
-           <item row="0" column="3">
-            <widget class="QLabel" name="drmBandwidthLabel">
+           <item row="1" column="0">
+            <widget class="QLabel" name="drmProtectionLabel">
              <property name="minimumSize">
               <size>
                <width>30</width>
@@ -975,7 +1027,7 @@
               </size>
              </property>
              <property name="text">
-              <string>BW</string>
+              <string>Prot.</string>
              </property>
              <property name="alignment">
               <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
@@ -985,8 +1037,8 @@
              </property>
             </widget>
            </item>
-           <item row="1" column="3">
-            <widget class="QLabel" name="drmInterleavelabel">
+           <item row="0" column="0">
+            <widget class="QLabel" name="drmModeLabel">
              <property name="minimumSize">
               <size>
                <width>30</width>
@@ -994,7 +1046,7 @@
               </size>
              </property>
              <property name="text">
-              <string>Interleave</string>
+              <string>Mode</string>
              </property>
              <property name="alignment">
               <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
@@ -1004,8 +1056,8 @@
              </property>
             </widget>
            </item>
-           <item row="2" column="3">
-            <widget class="QLabel" name="drmInstancesLabel">
+           <item row="1" column="3">
+            <widget class="QLabel" name="drmBandwidthLabel">
              <property name="minimumSize">
               <size>
                <width>30</width>
@@ -1013,7 +1065,7 @@
               </size>
              </property>
              <property name="text">
-              <string>Instances</string>
+              <string>BW</string>
              </property>
              <property name="alignment">
               <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
@@ -1023,26 +1075,7 @@
              </property>
             </widget>
            </item>
-           <item row="1" column="1">
-            <widget class="QComboBox" name="drmTxQAMComboBox">
-             <item>
-              <property name="text">
-               <string>4</string>
-              </property>
-             </item>
-             <item>
-              <property name="text">
-               <string>16</string>
-              </property>
-             </item>
-             <item>
-              <property name="text">
-               <string>64</string>
-              </property>
-             </item>
-            </widget>
-           </item>
-           <item row="3" column="3">
+           <item row="3" column="0">
             <widget class="QLabel" name="drmProfileLabel">
              <property name="text">
               <string>Profile</string>
@@ -1052,24 +1085,11 @@
              </property>
             </widget>
            </item>
-           <item row="3" column="4">
+           <item row="3" column="2">
             <widget class="QComboBox" name="drmProfileComboBox"/>
            </item>
           </layout>
          </item>
-         <item>
-          <spacer name="verticalSpacer_3">
-           <property name="orientation">
-            <enum>Qt::Vertical</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>20</width>
-             <height>0</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
         </layout>
        </widget>
       </widget>
@@ -1093,7 +1113,7 @@
         </widget>
        </item>
        <item>
-        <widget class="QProgressBar" name="progressBar">
+        <widget class="QProgressBar" name="txProgressBar">
          <property name="value">
           <number>0</number>
          </property>
@@ -1156,52 +1176,24 @@
      </item>
      <item>
       <layout class="QGridLayout" name="gridLayout">
-       <property name="horizontalSpacing">
-        <number>0</number>
-       </property>
-       <property name="verticalSpacing">
-        <number>1</number>
-       </property>
-       <item row="4" column="1" colspan="5">
-        <widget class="QLineEdit" name="comment1LineEdit">
-         <property name="minimumSize">
-          <size>
-           <width>120</width>
-           <height>25</height>
-          </size>
-         </property>
-         <property name="maximumSize">
-          <size>
-           <width>208</width>
-           <height>25</height>
-          </size>
-         </property>
-         <property name="toolTip">
-          <string>Template info</string>
-         </property>
-         <property name="statusTip">
-          <string>Template info</string>
-         </property>
-        </widget>
-       </item>
-       <item row="6" column="0">
-        <widget class="QLabel" name="rstLabel_6">
+       <item row="0" column="0">
+        <widget class="QLabel" name="toCallLabel">
          <property name="minimumSize">
           <size>
-           <width>10</width>
+           <width>0</width>
            <height>0</height>
           </size>
          </property>
          <property name="text">
-          <string>z</string>
+          <string>To:</string>
          </property>
          <property name="wordWrap">
           <bool>false</bool>
          </property>
         </widget>
        </item>
-       <item row="5" column="1" colspan="5">
-        <widget class="QLineEdit" name="comment2LineEdit">
+       <item row="0" column="1">
+        <widget class="QLineEdit" name="toCallLineEdit">
          <property name="minimumSize">
           <size>
            <width>120</width>
@@ -1210,7 +1202,7 @@
          </property>
          <property name="maximumSize">
           <size>
-           <width>208</width>
+           <width>120</width>
            <height>25</height>
           </size>
          </property>
@@ -1222,30 +1214,24 @@
          </property>
         </widget>
        </item>
-       <item row="1" column="4">
-        <widget class="QLineEdit" name="rsvLineEdit">
+       <item row="1" column="0">
+        <widget class="QLabel" name="operatorLabel">
          <property name="minimumSize">
           <size>
-           <width>50</width>
-           <height>25</height>
-          </size>
-         </property>
-         <property name="maximumSize">
-          <size>
-           <width>50</width>
-           <height>25</height>
+           <width>0</width>
+           <height>0</height>
           </size>
          </property>
-         <property name="toolTip">
-          <string>Template info</string>
+         <property name="text">
+          <string>Op:</string>
          </property>
-         <property name="statusTip">
-          <string>Template info</string>
+         <property name="wordWrap">
+          <bool>false</bool>
          </property>
         </widget>
        </item>
-       <item row="0" column="1">
-        <widget class="QLineEdit" name="toCallLineEdit">
+       <item row="1" column="1">
+        <widget class="QLineEdit" name="operatorLineEdit">
          <property name="minimumSize">
           <size>
            <width>120</width>
@@ -1266,11 +1252,11 @@
          </property>
         </widget>
        </item>
-       <item row="1" column="3">
+       <item row="1" column="2">
         <widget class="QLabel" name="rsvLabel">
          <property name="minimumSize">
           <size>
-           <width>30</width>
+           <width>0</width>
            <height>0</height>
           </size>
          </property>
@@ -1282,37 +1268,34 @@
          </property>
         </widget>
        </item>
-       <item row="1" column="2">
-        <spacer name="horizontalSpacer_5">
-         <property name="orientation">
-          <enum>Qt::Horizontal</enum>
-         </property>
-         <property name="sizeHint" stdset="0">
+       <item row="1" column="3">
+        <widget class="QLineEdit" name="rsvLineEdit">
+         <property name="minimumSize">
           <size>
-           <width>40</width>
-           <height>20</height>
+           <width>50</width>
+           <height>25</height>
           </size>
          </property>
-        </spacer>
-       </item>
-       <item row="0" column="0">
-        <widget class="QLabel" name="toCallLabel">
-         <property name="minimumSize">
+         <property name="maximumSize">
           <size>
-           <width>30</width>
-           <height>0</height>
+           <width>100</width>
+           <height>25</height>
           </size>
          </property>
-         <property name="text">
-          <string>To:</string>
+         <property name="toolTip">
+          <string>Template info</string>
          </property>
-         <property name="wordWrap">
-          <bool>false</bool>
+         <property name="statusTip">
+          <string>Template info</string>
          </property>
         </widget>
        </item>
-       <item row="5" column="0">
-        <widget class="QLabel" name="rstLabel_5">
+      </layout>
+     </item>
+     <item>
+      <layout class="QHBoxLayout" name="horizontalLayout_8">
+       <item>
+        <widget class="QLabel" name="rstLabel_4">
          <property name="minimumSize">
           <size>
            <width>10</width>
@@ -1320,37 +1303,29 @@
           </size>
          </property>
          <property name="text">
-          <string>y</string>
+          <string>x</string>
          </property>
          <property name="wordWrap">
           <bool>false</bool>
          </property>
         </widget>
        </item>
-       <item row="6" column="1" colspan="5">
-        <widget class="QLineEdit" name="comment3LineEdit">
-         <property name="minimumSize">
-          <size>
-           <width>126</width>
-           <height>25</height>
-          </size>
-         </property>
+       <item>
+        <widget class="xyzPlainTextEdit" name="xPlainTextEdit">
          <property name="maximumSize">
           <size>
-           <width>208</width>
-           <height>25</height>
+           <width>16777215</width>
+           <height>60</height>
           </size>
          </property>
-         <property name="toolTip">
-          <string>Template info</string>
-         </property>
-         <property name="statusTip">
-          <string>Template info</string>
-         </property>
         </widget>
        </item>
-       <item row="4" column="0">
-        <widget class="QLabel" name="rstLabel_4">
+      </layout>
+     </item>
+     <item>
+      <layout class="QHBoxLayout" name="horizontalLayout_3">
+       <item>
+        <widget class="QLabel" name="rstLabel_5">
          <property name="minimumSize">
           <size>
            <width>10</width>
@@ -1358,83 +1333,66 @@
           </size>
          </property>
          <property name="text">
-          <string>x</string>
+          <string>y</string>
          </property>
          <property name="wordWrap">
           <bool>false</bool>
          </property>
         </widget>
        </item>
-       <item row="1" column="1">
-        <widget class="QLineEdit" name="operatorLineEdit">
-         <property name="minimumSize">
-          <size>
-           <width>120</width>
-           <height>25</height>
-          </size>
-         </property>
+       <item>
+        <widget class="xyzPlainTextEdit" name="yPlainTextEdit">
          <property name="maximumSize">
           <size>
-           <width>120</width>
-           <height>25</height>
+           <width>16777215</width>
+           <height>60</height>
           </size>
          </property>
-         <property name="toolTip">
-          <string>Template info</string>
-         </property>
-         <property name="statusTip">
-          <string>Template info</string>
-         </property>
         </widget>
        </item>
-       <item row="1" column="0">
-        <widget class="QLabel" name="operatorLabel">
+      </layout>
+     </item>
+     <item>
+      <layout class="QHBoxLayout" name="horizontalLayout_7">
+       <item>
+        <widget class="QLabel" name="rstLabel_6">
          <property name="minimumSize">
           <size>
-           <width>30</width>
+           <width>10</width>
            <height>0</height>
           </size>
          </property>
          <property name="text">
-          <string>Op:</string>
+          <string>z</string>
          </property>
          <property name="wordWrap">
           <bool>false</bool>
          </property>
         </widget>
        </item>
-       <item row="0" column="2">
-        <spacer name="horizontalSpacer_4">
-         <property name="orientation">
-          <enum>Qt::Horizontal</enum>
-         </property>
-         <property name="sizeHint" stdset="0">
+       <item>
+        <widget class="xyzPlainTextEdit" name="zPlainTextEdit">
+         <property name="maximumSize">
           <size>
-           <width>40</width>
-           <height>20</height>
+           <width>16777215</width>
+           <height>60</height>
           </size>
          </property>
-        </spacer>
+        </widget>
        </item>
       </layout>
      </item>
      <item>
-      <layout class="QHBoxLayout" name="horizontalLayout_2" stretch="0,0,0">
+      <layout class="QHBoxLayout" name="horizontalLayout_2" stretch="0,0">
        <property name="spacing">
         <number>4</number>
        </property>
        <item>
-        <spacer name="horizontalSpacer_2">
-         <property name="orientation">
-          <enum>Qt::Horizontal</enum>
-         </property>
-         <property name="sizeHint" stdset="0">
-          <size>
-           <width>40</width>
-           <height>20</height>
-          </size>
+        <widget class="QPushButton" name="refreshPushButton">
+         <property name="text">
+          <string>Refresh</string>
          </property>
-        </spacer>
+        </widget>
        </item>
        <item>
         <widget class="imageViewer" name="previewWidget" native="true">
@@ -1446,19 +1404,6 @@
          </property>
         </widget>
        </item>
-       <item>
-        <spacer name="horizontalSpacer_3">
-         <property name="orientation">
-          <enum>Qt::Horizontal</enum>
-         </property>
-         <property name="sizeHint" stdset="0">
-          <size>
-           <width>40</width>
-           <height>20</height>
-          </size>
-         </property>
-        </spacer>
-       </item>
       </layout>
      </item>
      <item>
@@ -1469,11 +1414,33 @@
        <property name="sizeHint" stdset="0">
         <size>
          <width>20</width>
-         <height>0</height>
+         <height>28</height>
         </size>
        </property>
       </spacer>
      </item>
+     <item>
+      <widget class="QPlainTextEdit" name="txNotificationList">
+       <property name="acceptDrops">
+        <bool>false</bool>
+       </property>
+       <property name="toolTip">
+        <string>Rx Notifications seen for the last DSSTV Hybrid image sent</string>
+       </property>
+       <property name="statusTip">
+        <string/>
+       </property>
+       <property name="lineWrapMode">
+        <enum>QPlainTextEdit::NoWrap</enum>
+       </property>
+       <property name="readOnly">
+        <bool>true</bool>
+       </property>
+       <property name="tabStopWidth">
+        <number>8</number>
+       </property>
+      </widget>
+     </item>
     </layout>
    </item>
   </layout>
@@ -1485,9 +1452,14 @@
    <header>widgets/imageviewer.h</header>
    <container>1</container>
   </customwidget>
+  <customwidget>
+   <class>xyzPlainTextEdit</class>
+   <extends>QPlainTextEdit</extends>
+   <header>xyzplaintextedit.h</header>
+  </customwidget>
  </customwidgets>
  <resources>
-  <include location="qsstv.qrc"/>
+  <include location="../qsstv.qrc"/>
  </resources>
  <connections/>
 </ui>
diff --git a/qsstv/mainwindow.cpp b/qsstv/mainwindow.cpp
index c50d348..437434a 100644
--- a/qsstv/mainwindow.cpp
+++ b/qsstv/mainwindow.cpp
@@ -20,27 +20,30 @@
 ***************************************************************************/
 
 #include "mainwindow.h"
-#include "qsstvglobal.h"
+#include "appglobal.h"
+#include "utils/logging.h"
+#include "dispatch/dispatcher.h"
 #include "ui_mainwindow.h"
-#include "sound/soundio.h"
+#include "soundpulse.h"
+#include "soundalsa.h"
 #include "configdialog.h"
 #include "configparams.h"
+#include "rigcontrol.h"
+#include "waterfalltext.h"
+#include "calibration.h"
+#include "frequencyselectwidget.h"
+#include "hexconvertor.h"
 #ifndef QT_NO_DEBUG
 #include "scope/scopeview.h"
 #endif
-
+#include "scope/scopeoffset.h"
+#include "rxfunctions.h"
+#include "logbook.h"
 #include <QFont>
 #include <QCloseEvent>
 #include <QMessageBox>
-#include "dispatcher.h"
-#include "sound/calibration.h"
-#include "dsp/filterparam.h"
-#include "dsp/filter.h"
-#include "utils/supportfunctions.h"
-#include "utils/ftp.h"
-#include "rig/rigcontrol.h"
-#include "logbook/logbook.h"
-
+#include <QScreen>
+#include <QApplication>
 
 
 /**
@@ -48,149 +51,186 @@
  *
  * @param parent
  */
-mainWindow::mainWindow(QWidget *parent) :
-  QMainWindow(parent),
-  ui(new Ui::MainWindow)
+mainWindow::mainWindow(QWidget *parent) : QMainWindow(parent),  ui(new Ui::MainWindow)
 {
-  soundIOPtr=new soundIO;
-  rigControllerR1=new rigControl(1);
-//  rigControllerR2=new rigControl(2);
-  rigController=rigControllerR1;
-  confDiag=new configDialog();
-#ifndef QT_NO_DEBUG
-  scopeViewerData=new scopeView("Data Scope");
-  scopeViewerSync=new scopeView("Sync Scope");
-  scopeViewerData->setAlternativeScaleMultiplier(SUBSAMPLINGRATIO/rxClock);
-  scopeViewerSync->setAlternativeScaleMultiplier(SUBSAMPLINGRATIO/rxClock);
-#endif
-
-//  drmProfileComboBox->addItem("FAX");
+  QApplication::instance()->thread()->setObjectName("qsstv_main");
   wfTextPushButton=new QPushButton("WF Text",this);
   bsrPushButton=new QPushButton("BSR",this);
-  idPushButton=new QPushButton("ID",this);
 
-  greenPXM=new QPixmap(16,16);
-  greenPXM->fill(Qt::green);
-  redPXM=new QPixmap(16,16);
-  redPXM->fill(Qt::red);
+  freqComboBox=new QComboBox(this);
+  idPushButton=new QPushButton("ID",this);
+  QFont f;
+
+  freqDisplay = new QLabel(this);
+  f.setBold(true);
+  f.setPixelSize(15);
+  freqDisplay->setFont(f);
+  freqDisplay->setObjectName("freqDisplay");
+  freqDisplay->setMinimumSize(QSize(100, 0));
+  freqDisplay->setMaximumSize(QSize(100, 16777215));
+  freqDisplay->setFrameShape(QFrame::Box);
+  freqDisplay->setFrameShadow(QFrame::Raised);
+  freqDisplay->setLineWidth(2);
   pttText.setText("   PTT");
   pttIcon=new QLabel(this);
   pttIcon->setFixedSize(16,16);
-  pttIcon->setPixmap(*greenPXM);
+  pttIcon->setPixmap(*greenPXMPtr);
   pttIcon->setFrameShape(QFrame::Panel);
   pttIcon->setFrameShadow(QFrame::Raised);
   pttIcon->setLineWidth(2);
-  dispatcherPtr=NULL;
-
-  setWindowIcon(QPixmap(":/icons/qsstv.png"));
-  readSettings();
+  rigControllerPtr=new rigControl(1); // must preceed configDialog construction
+  configDialogPtr=new configDialog(this);
+  configDialogPtr->readSettings();
 
   ui->setupUi(this);
+  setWindowTitle(qsstvVersion);
+  setWindowIcon(QPixmap(":/icons/qsstv.png"));
   ui->maintabWidget->setCurrentIndex(0);
+  ui->statusBar->addPermanentWidget(freqDisplay);
+  ui->statusBar->addPermanentWidget(freqComboBox);
   ui->statusBar->addPermanentWidget(wfTextPushButton);
   ui->statusBar->addPermanentWidget(bsrPushButton);
   ui->statusBar->addPermanentWidget(idPushButton);
   ui->statusBar->addPermanentWidget(&pttText);
   ui->statusBar->addPermanentWidget(pttIcon);
   statusBarPtr=statusBar(); // must be after setup UI
+  spectrumFramePtr=ui->spectrumFrame;
 
 
-  setWindowTitle(qsstvVersion);
-  logBookPtr=new logBook;
-}
+  // setting up pointers
+  soundIOPtr=NULL;
 
-/**
- * @brief
- *
- */
-mainWindow::~mainWindow()
-{
-#ifndef QT_NO_DEBUG
-  delete scopeViewerData;
-  delete scopeViewerSync;
-#endif
-  delete ui;
-}
 
-/**
- * @brief initialize sound device and dispatcher
- *
- */
-void mainWindow::init()
-{
-  QString ret;
-  readSettings();
   rxWidgetPtr=ui->rxWindow;
   txWidgetPtr=ui->txWindow;
   galleryWidgetPtr=ui->galleryWindow;
-   if(!dispatcherPtr) dispatcherPtr=new dispatcher();
-   ret=dispatcherPtr->init();
-   if(!ret.isEmpty())
-   {
-     splashStr+=ret.rightJustified(25,' ')+"\n";
-     splashPtr->showMessage(splashStr ,Qt::AlignLeft,Qt::white);
-   }
+  readSettings();
+  if(pulseSelected) soundIOPtr=new soundPulse;
+  else  soundIOPtr=new soundAlsa;
 
+  dispatcherPtr=new dispatcher;
+  waterfallPtr=new waterfallText;
+  xmlIntfPtr=new xmlInterface;
+  logBookPtr=new logBook;
+
+  // setup connections
 
-  confDiag->readSettings();
   connect(ui->actionExit,SIGNAL(triggered()),this, SLOT(slotExit()));
   connect(ui->actionConfigure,SIGNAL(triggered()),this, SLOT(slotConfigure()));
   connect(ui->actionCalibrate,SIGNAL(triggered()),this, SLOT(slotCalibrate()));
   connect(ui->actionAboutQSSTV, SIGNAL(triggered()),SLOT(slotAboutQSSTV()));
   connect(ui->actionAboutQt, SIGNAL(triggered()),SLOT(slotAboutQt()));
   connect(ui->actionUsersGuide, SIGNAL(triggered()),SLOT(slotDocumentation()));
-
-
   connect(idPushButton, SIGNAL(clicked()), this, SLOT(slotSendID()));
   connect(bsrPushButton, SIGNAL(clicked()), this, SLOT(slotSendBSR()));
-//  connect(fixPushButton, SIGNAL(clicked()), this, SLOT(slotSendFIX()));
+  connect(freqComboBox,SIGNAL(activated(int)),SLOT(slotSetFrequency(int)));
   connect(wfTextPushButton, SIGNAL(clicked()), this, SLOT(slotSendWfText()));
+  connect(rxWidgetPtr,SIGNAL(modeSwitch(int)),this, SLOT(slotModeChange(int)));
+  connect(txWidgetPtr,SIGNAL(modeSwitch(int)),this, SLOT(slotModeChange(int)));
 
-
-#ifndef QT_NO_DEBUG
-//  connect(ui->actionTest,SIGNAL(triggered()),this, SLOT(slotTest()));
+ #ifdef ENABLELOGGING
   connect(ui->actionLogSettings, SIGNAL(triggered()),SLOT(slotLogSettings()));
   connect(ui->actionResetLog, SIGNAL(triggered()),SLOT(slotResetLog()));
-  connect(ui->actionShowDataScope, SIGNAL(triggered()),SLOT(slotShowDataScope()));
-  connect(ui->actionShowSyncScope, SIGNAL(triggered()),SLOT(slotShowSyncScope()));
-  connect(ui->actionScopeOffset,SIGNAL(triggered()),this, SLOT(slotScopeOffset()));
 #else
-  ui->menuOptions->removeAction(ui->actionTest);
-  ui->menuOptions->removeAction(ui->actionLogSettings);
-  ui->menuOptions->removeAction(ui->actionShowDataScope);
-  ui->menuOptions->removeAction(ui->actionShowSyncScope);
   ui->menuOptions->removeAction(ui->actionLogSettings);
   ui->menuOptions->removeAction(ui->actionResetLog);
-  ui->menuOptions->removeAction(ui->actionScopeOffset);
-
 #endif
+#ifndef QT_NO_DEBUG
 
+  connect(ui->actionShowDataScope, SIGNAL(triggered()),SLOT(slotShowDataScope()));
+  connect(ui->actionShowSyncScopeNarrow, SIGNAL(triggered()),SLOT(slotShowSyncScopeNarrow()));
+  connect(ui->actionShowSyncScopeWide, SIGNAL(triggered()),SLOT(slotShowSyncScopeWide()));
+  connect(ui->actionScopeOffset,SIGNAL(triggered()),this, SLOT(slotScopeOffset()));
+  connect(ui->actionDumpSamplesPerLine,SIGNAL(triggered()),this, SLOT(slotDumpSamplesPerLine()));
 
-  if(!soundIOPtr->init())
-  {
-    splashStr+=QString("Soundcard error: %1").arg(*soundIOPtr->getLastError()).rightJustified(25,' ')+"\n";;
-    splashPtr->showMessage(splashStr ,Qt::AlignLeft,Qt::white);
-  }
-  else
-  {
-    soundIOPtr->start();
-  }
+#else
+  ui->menuOptions->removeAction(ui->actionDumpSamplesPerLine);
+  ui->menuScope->removeAction(ui->actionShowDataScope);
+  ui->menuScope->removeAction(ui->actionShowSyncScopeNarrow);
+  ui->menuScope->removeAction(ui->actionShowSyncScopeWide);
+
+  ui->menuScope->removeAction(ui->actionScopeOffset);
+  ui->menuScope->menuAction()->setVisible(false);
 
-#ifndef QT_NO_DEBUG
- rxWidgetPtr->functionsPtr()->setOffset(dataScopeOffset,false);
 #endif
+}
 
+/**
+ * @brief
+ *
+ */
+mainWindow::~mainWindow()
+{
+  delete ui;
 }
 
-void mainWindow::startReceiving()
+/**
+ * @brief initialize sound device and dispatcher
+ *
+ */
+void mainWindow::init()
+{
+  // starting threads
+  // todo  ftp threads
+  cleanUpCache(rxSSTVImagesPath);
+  cleanUpCache(rxDRMImagesPath);
+  cleanUpCache(txSSTVImagesPath);
+  cleanUpCache(txDRMImagesPath);
+  //start rx and tx threads
+  rxWidgetPtr->functionsPtr()->start();
+  txWidgetPtr->functionsPtr()->start();
+  restartSound(true);
+  dispatcherPtr->init();
+  galleryWidgetPtr->init();
+  txWidgetPtr->init();
+  waterfallPtr->init();
+  rigControllerPtr->init();
+  rxWidgetPtr->init();
+  if(!rigControllerPtr->initError.isEmpty())
+    {
+      splashStr+=rigControllerPtr->initError.rightJustified(25,' ')+"\n";
+      splashPtr->showMessage(splashStr ,Qt::AlignLeft,Qt::white);
+    }
+  startTimer(1000);
+}
+
+void mainWindow::restartSound(bool inStartUp)
+{
+  //first check if sound
+  if(soundIOPtr!=NULL)
+    {
+      soundIOPtr->stopSoundThread();
+      delete soundIOPtr;
+      soundIOPtr=NULL;
+    }
+  if(pulseSelected) soundIOPtr=new soundPulse;
+  else soundIOPtr=new soundAlsa;
+  if(!soundIOPtr->init(BASESAMPLERATE))
+    {
+      if(inStartUp)
+        {
+          splashStr+=QString("Soundcard error: %1").arg(soundIOPtr->getLastError()).rightJustified(25,' ')+"\n";;
+          splashPtr->showMessage(splashStr ,Qt::AlignLeft,Qt::white);
+        }
+      else
+        {
+          QMessageBox::critical(this, tr("Soundcard error"),soundIOPtr->getLastError());
+        }
+    }
+  soundIOPtr->start();
+}
+
+
+void mainWindow::startRunning()
 {
-  txWidgetPtr->setSettingsTab();
-  rxWidgetPtr->setSettingsTab();
-  rxWidgetPtr->start(true);
+  dispatcherPtr->startRX();
 }
 
+
 void mainWindow::readSettings()
 {
+
+
   QSettings qSettings;
   qSettings.beginGroup("MAIN");
   int windowWidth = qSettings.value("windowWidth", 460 ).toInt();
@@ -198,11 +238,16 @@ void mainWindow::readSettings()
   int windowX = qSettings.value( "windowX", -1 ).toInt();
   int windowY = qSettings.value( "windowY", -1 ).toInt();
   resize( windowWidth, windowHeight );
-  if ( windowX != -1 || windowY != -1 ) 	move( windowX, windowY );
+  if ( windowX != -1 || windowY != -1 )
+    {
+      move( windowX, windowY );
+    }
   transmissionModeIndex=(etransmissionMode)qSettings.value("transmissionModeIndex",0).toInt();
-  dataScopeOffset=qSettings.value("dataScopeOffset",0).toUInt();
-  logfile->readSettings(qSettings);
   qSettings.endGroup();
+  ui->spectrumFrame->readSettings();
+//  configDialogPtr->readSettings();
+  logFilePtr->readSettings();
+
 }
 
 void mainWindow::writeSettings()
@@ -213,12 +258,15 @@ void mainWindow::writeSettings()
   qSettings.setValue( "windowHeight", height() );
   qSettings.setValue( "windowX", x() );
   qSettings.setValue( "windowY", y() );
-  qSettings.setValue("dataScopeOffset",dataScopeOffset);
   qSettings.setValue("transmissionModeIndex",(int)transmissionModeIndex);
-
-  logfile->writeSettings(qSettings);
-  galleryWidgetPtr->writeSettings(false);
+  logFilePtr->writeSettings();
+  galleryWidgetPtr->writeSettings();
+  rxWidgetPtr->writeSettings();
+  txWidgetPtr->writeSettings();
+  configDialogPtr->writeSettings();
+  logFilePtr->writeSettings();
   qSettings.endGroup();
+  ui->spectrumFrame->writeSettings();
 }
 
 
@@ -227,30 +275,27 @@ void mainWindow::writeSettings()
  */
 void mainWindow::setNewFont()
 {
-//  QFont fnt;
-//  fnt.fromString(fontString);
-//  setFont(fnt);
-//  galMW->setFont(fnt);
-//  rxMW->setFont(fnt);
-//  txMW->setFont(fnt);
+  //  QFont fnt;
+  //  fnt.fromString(fontString);
+  //  setFont(fnt);
+  //  galMW->setFont(fnt);
+  //  rxMW->setFont(fnt);
+  //  txMW->setFont(fnt);
 }
 
 void mainWindow::slotExit()
 {
   int exit;
-  exit=QMessageBox::information(this, tr("Quit..."),
-                                tr("Do your really want to quit QSSTV?"),
-                                QMessageBox::Ok, QMessageBox::Cancel);
-    if(exit==QMessageBox::Ok)
-        {
-
-           dispatcherPtr->stopRXTX();
-           deleteFiles(rxImagesPath,"*.rs*");
-           deleteFiles(txImagesPath,"*.rs*");
-           soundIOPtr->stopAndWait();
-           QApplication::quit();
-      }
-   writeSettings();
+  exit=QMessageBox::information(this, tr("Quit..."),tr("Do you really want to quit QSSTV?"), QMessageBox::Ok, QMessageBox::Cancel);
+  if(exit==QMessageBox::Ok)
+    {
+      dispatcherPtr->idleAll();
+      rxWidgetPtr->functionsPtr()->stopThread();
+      txWidgetPtr->functionsPtr()->stopThread();
+      if(soundIOPtr) soundIOPtr->stopSoundThread();
+      writeSettings();
+      QApplication::quit();
+    }
 }
 
 void  mainWindow::closeEvent ( QCloseEvent *e )
@@ -262,74 +307,89 @@ void  mainWindow::closeEvent ( QCloseEvent *e )
 void mainWindow::slotConfigure()
 {
 
-  if(confDiag->exec()==QDialog::Accepted)
+  if(configDialogPtr->exec()==QDialog::Accepted)
     {
-      if(!soundIOPtr->init())
-        {
-          QMessageBox::critical(this, tr("Soundcard error"),*soundIOPtr->getLastError());
-        }
-      else
+      if(configDialogPtr->soundNeedsRestart)
         {
-           soundIOPtr->start();
+          restartSound(false);
         }
-     dispatcherPtr->init();
-     rxWidgetPtr->start(true);
+      dispatcherPtr->init();
     }
 }
 
 void mainWindow::slotLogSettings()
 {
-  logfile->maskSelect(this);
+  logFilePtr->maskSelect(this);
 }
 
 void mainWindow::slotResetLog()
 {
- logfile->reset();
+  logFilePtr->reset();
 }
 
-
-void mainWindow::slotCalibrate()
+void mainWindow::slotDocumentation()
 {
-  calibration calib(this);
-  if(calib.exec()==QDialog::Accepted)
-    {
-      rxClock=calib.getRXClock();
-      txClock=calib.getTXClock();
-    }
+  QDesktopServices::openUrl(docURL);
+
 }
 
-void mainWindow::slotAboutQSSTV()
-{
-  QString temp=tr("QSSTV\nVersion: ") + MAJORVERSION + MINORVERSION ;
-  temp += QString("\n http://users.telenet.be/on4qz \n(c) 2014-%1 -- Johan Maes - ON4QZ\n%2").arg(QDate::currentDate().toString("yyyy")).arg(shortText);
-//  temp += "\n http://users.telenet.be/on4qz \n(c) 2000-20135-- Johan Maes - ON4QZ\n HAMDRM Software based on RX/TXAMADRM\n from PA0MBO";
 
 
+void mainWindow::slotAboutQSSTV()
+{
+  QString temp=tr("QSSTV\nVersion: ") + MAJORVERSION + MINORVERSION;
+  temp += "\n http://users.telenet.be/on4qz \n(c) 2000-2016 -- Johan Maes - ON4QZ\n HAMDRM Software based on RX/TXAMADRM\n from PA0MBO";
   QMessageBox::about(this,tr("About..."),temp);
 
-
-//  QString temp=tr("QSSTV\nVersion: ") + MAJORVERSION + MINORVERSION;
-//  temp += "\n http://users.telenet.be/on4qz \n(c) 2000-20135-- Johan Maes - ON4QZ\n HAMDRM Software based on RX/TXAMADRM\n from PA0MBO";
-//  QMessageBox::about(this,tr("About..."),temp);
-
 }
 
 void mainWindow::slotAboutQt()
 {
-   QMessageBox::aboutQt(this,tr("About..."));
+  QMessageBox::aboutQt(this,tr("About..."));
 
 }
+void mainWindow::setPTT(bool p)
+{
+  if(p) pttIcon->setPixmap(*redPXMPtr);
+  else pttIcon->setPixmap(*greenPXMPtr);
+}
 
+void mainWindow::setSSTVDRMPushButton(bool inDRM)
+{
+  int i;
+  QString modeStr;
+  bsrPushButton->setEnabled(inDRM);
+  freqComboBox->clear();
+  if(inDRM) modeStr="DRM";
+  else modeStr="SSTV";
+  modModeList.clear();
+  for(i=0;i<freqList.count();i++)
+    {
+      if(modeList.at(i)==modeStr)
+        {
+          freqComboBox->addItem(freqList.at(i));
+          modModeList.append(sbModeList.at(i));
+        }
+    }
+}
 
-
-
-
-void mainWindow::setPTT(bool p)
+void mainWindow::slotCalibrate()
 {
-  if(p) pttIcon->setPixmap(*redPXM);
-  else pttIcon->setPixmap(*greenPXM);
+  calibration calib(this);
+  if(calib.exec()==QDialog::Accepted)
+    {
+      rxClock=calib.getRXClock();
+      txClock=calib.getTXClock();
+    }
+  writeSettings();
 }
 
+void mainWindow::slotModeChange(int rxtxMode)
+{
+  txWidgetPtr->changeTransmissionMode(rxtxMode);
+  rxWidgetPtr->changeTransmissionMode(rxtxMode);
+  lastReceivedCall.clear();
+}
 
 void mainWindow::slotSendBSR()
 {
@@ -349,25 +409,97 @@ void mainWindow::slotSendWfText()
  txWidgetPtr->sendWfText();
 }
 
-void mainWindow::slotDocumentation()
+void mainWindow::slotSetFrequency(int freqIndex)
 {
-    QDesktopServices::openUrl(docURL);
+  QByteArray ba;
+  QString freqStr,mode;
+  freqStr=freqComboBox->itemText(freqIndex);
+  mode=modModeList.at(freqIndex);
+  if(freqStr.isEmpty()) return;
+  double fr=freqStr.toDouble()*1000000.;
+  rigControllerPtr->setFrequency(fr);
+  rigControllerPtr->setMode(mode);
+  QString s=additionalCommand;
+  //FEF7AE01A060101FD
+  if(!s.isEmpty() && !rigControllerPtr->params()->enableXMLRPC)
+    {
+      if(hexFromString(s,ba,additionalCommandHex))
+        {
+          rigControllerPtr->rawCommand(ba);
+        }
+      else
+        {
+          QMessageBox::critical(this,"Cat Error","Advanced command invalid");
+        }
+    }
+}
+
+
 
+
+void mainWindow::timerEvent(QTimerEvent *)
+{
+    double fr;
+    if(rigControllerPtr->getFrequency(fr))
+      {
+    fr/=1000000.;
+    if(fr>1) freqDisplay->setText(QString::number(fr,'f',6));
+      }
 }
 
-void mainWindow::setBSRPushButton(bool b)
+void mainWindow::cleanUpCache(QString dirPath)
 {
-  bsrPushButton->setEnabled(b);
+  int i,j;
+  bool found;
+  QFileInfoList orgFileList;
+  QFileInfoList cacheFileList;
+  QFileInfoList removeFileList;
+  QDir dirOrg(dirPath);
+  dirOrg.setFilter(QDir::Files | QDir::NoSymLinks);
+  orgFileList = dirOrg.entryInfoList();
+  // get a orgiriginal filelist
+  QDir dirCache(dirPath+"/cache");
+  dirCache.setFilter(QDir::Files | QDir::NoSymLinks);
+  cacheFileList = dirCache.entryInfoList();
+  // get a orgiriginal filelist
+  for(i=0;i<cacheFileList.count();i++)
+  {
+    found=false;
+    for(j=0;j<orgFileList.count();j++)
+    {
+
+      if(cacheFileList.at(i).baseName()==QString(orgFileList.at(j).baseName()+orgFileList.at(j).created().toString()))
+      {
+        found=true;
+        break;
+      }
+    }
+   if(!found)
+   {
+     removeFileList.append(cacheFileList.at(i));
+   }
+  }
+  for(i=0;i<removeFileList.count();i++)
+  {
+    QFile fi(removeFileList.at(i).absoluteFilePath());
+    fi.remove();
+  }
 }
 
+
 #ifndef QT_NO_DEBUG
 void mainWindow::slotShowDataScope()
 {
   scopeViewerData->show(true,true,true,true);
 }
-void mainWindow::slotShowSyncScope()
+void mainWindow::slotShowSyncScopeNarrow()
+{
+  scopeViewerSyncNarrow->show(true,true,true,true);
+}
+
+void mainWindow::slotShowSyncScopeWide()
 {
-  scopeViewerSync->show(true,true,true,true);
+  scopeViewerSyncWide->show(true,true,true,true);
 }
 
 void mainWindow::slotScopeOffset()
@@ -375,6 +507,12 @@ void mainWindow::slotScopeOffset()
   dataScopeOffset=rxWidgetPtr->functionsPtr()->setOffset(dataScopeOffset,true);
 }
 
+void mainWindow::slotDumpSamplesPerLine()
+{
+  dumpSamplesPerLine();
+}
+
+
 
 
 #endif
diff --git a/qsstv/mainwindow.h b/qsstv/mainwindow.h
index f862035..abc5c2e 100644
--- a/qsstv/mainwindow.h
+++ b/qsstv/mainwindow.h
@@ -6,6 +6,9 @@
 #include <QPushButton>
 #include <QLabel>
 
+class configDialog;
+class spectrumWidget;
+
 namespace Ui {
   class MainWindow;
   }
@@ -18,42 +21,55 @@ public:
   explicit mainWindow(QWidget *parent = 0);
   ~mainWindow();
   void init();
+  void startRunning();
   void setNewFont();
   void setPTT(bool p);
-  void setBSRPushButton(bool b);
-  void startReceiving();
+  void setSSTVDRMPushButton(bool inDRM);
+  spectrumWidget *spectrumFramePtr;
 
 private slots:
   void slotConfigure();
   void slotExit();
   void slotResetLog();
   void slotLogSettings();
-  void slotCalibrate();
   void slotAboutQt();
   void slotAboutQSSTV();
   void slotDocumentation();
+  void slotCalibrate();
+  void slotModeChange(int);
   void slotSendID();
   void slotSendBSR();
   void slotSendWfText();
+  void slotSetFrequency(int freqIndex);
+
+
 #ifndef QT_NO_DEBUG
   void slotShowDataScope();
-  void slotShowSyncScope();
+  void slotShowSyncScopeNarrow();
+  void slotShowSyncScopeWide();
   void slotScopeOffset();
+  void slotDumpSamplesPerLine();
 
 #endif
+
 private:
   Ui::MainWindow *ui;
   void closeEvent ( QCloseEvent *e );
   void readSettings();
   void writeSettings();
+  void restartSound(bool inStartUp);
+  void cleanUpCache(QString dirPath);
   QComboBox *transmissionModeComboBox;
   QPushButton *wfTextPushButton;
   QPushButton *fixPushButton;
   QPushButton *bsrPushButton;
   QPushButton *idPushButton;
+  QComboBox *freqComboBox;
   QLabel pttText;
   QLabel *pttIcon;
-
+  QLabel *freqDisplay;
+  void timerEvent(QTimerEvent *);
+  QStringList modModeList;
 };
 
 #endif // MAINWINDOW_H
diff --git a/qsstv/mainwindow.ui b/qsstv/mainwindow.ui
index 5c2b14b..5689e5b 100644
--- a/qsstv/mainwindow.ui
+++ b/qsstv/mainwindow.ui
@@ -25,13 +25,7 @@
    <enum>QTabWidget::Rounded</enum>
   </property>
   <widget class="QWidget" name="centralwidget">
-   <layout class="QVBoxLayout" name="verticalLayout">
-    <property name="spacing">
-     <number>1</number>
-    </property>
-    <property name="margin">
-     <number>1</number>
-    </property>
+   <layout class="QHBoxLayout" name="horizontalLayout">
     <item>
      <widget class="QTabWidget" name="maintabWidget">
       <property name="font">
@@ -61,7 +55,16 @@
         <property name="spacing">
          <number>1</number>
         </property>
-        <property name="margin">
+        <property name="leftMargin">
+         <number>1</number>
+        </property>
+        <property name="topMargin">
+         <number>1</number>
+        </property>
+        <property name="rightMargin">
+         <number>1</number>
+        </property>
+        <property name="bottomMargin">
          <number>1</number>
         </property>
         <item>
@@ -77,7 +80,16 @@
         <property name="spacing">
          <number>1</number>
         </property>
-        <property name="margin">
+        <property name="leftMargin">
+         <number>1</number>
+        </property>
+        <property name="topMargin">
+         <number>1</number>
+        </property>
+        <property name="rightMargin">
+         <number>1</number>
+        </property>
+        <property name="bottomMargin">
          <number>1</number>
         </property>
         <item>
@@ -93,7 +105,16 @@
         <property name="spacing">
          <number>1</number>
         </property>
-        <property name="margin">
+        <property name="leftMargin">
+         <number>1</number>
+        </property>
+        <property name="topMargin">
+         <number>1</number>
+        </property>
+        <property name="rightMargin">
+         <number>1</number>
+        </property>
+        <property name="bottomMargin">
          <number>1</number>
         </property>
         <item>
@@ -103,6 +124,34 @@
       </widget>
      </widget>
     </item>
+    <item>
+     <widget class="spectrumWidget" name="spectrumFrame">
+      <property name="sizePolicy">
+       <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+        <horstretch>0</horstretch>
+        <verstretch>0</verstretch>
+       </sizepolicy>
+      </property>
+      <property name="minimumSize">
+       <size>
+        <width>180</width>
+        <height>0</height>
+       </size>
+      </property>
+      <property name="maximumSize">
+       <size>
+        <width>180</width>
+        <height>16777215</height>
+       </size>
+      </property>
+      <property name="frameShape">
+       <enum>QFrame::StyledPanel</enum>
+      </property>
+      <property name="frameShadow">
+       <enum>QFrame::Raised</enum>
+      </property>
+     </widget>
+    </item>
    </layout>
   </widget>
   <widget class="QMenuBar" name="menubar">
@@ -111,7 +160,7 @@
      <x>0</x>
      <y>0</y>
      <width>831</width>
-     <height>21</height>
+     <height>19</height>
     </rect>
    </property>
    <property name="font">
@@ -131,13 +180,11 @@
      <string>Options</string>
     </property>
     <addaction name="actionConfigure"/>
-    <addaction name="actionTest"/>
     <addaction name="actionCalibrate"/>
-    <addaction name="actionShowDataScope"/>
-    <addaction name="actionShowSyncScope"/>
+    <addaction name="separator"/>
     <addaction name="actionLogSettings"/>
     <addaction name="actionResetLog"/>
-    <addaction name="actionScopeOffset"/>
+    <addaction name="actionDumpSamplesPerLine"/>
    </widget>
    <widget class="QMenu" name="menuHelp">
     <property name="title">
@@ -147,9 +194,19 @@
     <addaction name="actionAboutQt"/>
     <addaction name="actionUsersGuide"/>
    </widget>
+   <widget class="QMenu" name="menuScope">
+    <property name="title">
+     <string>Scope</string>
+    </property>
+    <addaction name="actionShowDataScope"/>
+    <addaction name="actionShowSyncScopeNarrow"/>
+    <addaction name="actionShowSyncScopeWide"/>
+    <addaction name="actionScopeOffset"/>
+   </widget>
    <addaction name="menuFile"/>
    <addaction name="menuOptions"/>
    <addaction name="menuHelp"/>
+   <addaction name="menuScope"/>
   </widget>
   <widget class="QStatusBar" name="statusBar">
    <property name="minimumSize">
@@ -175,16 +232,12 @@
     <string>Configuration</string>
    </property>
   </action>
-  <action name="actionTest">
+  <action name="actionDumpSamplesPerLine">
    <property name="text">
-    <string>Test</string>
+    <string>Dump Samples Per Line</string>
    </property>
   </action>
   <action name="actionCalibrate">
-   <property name="icon">
-    <iconset resource="qsstv.qrc">
-     <normaloff>:/icons/edit.png</normaloff>:/icons/edit.png</iconset>
-   </property>
    <property name="text">
     <string>Calibrate</string>
    </property>
@@ -219,9 +272,9 @@
     <string>Users Guide</string>
    </property>
   </action>
-  <action name="actionShowSyncScope">
+  <action name="actionShowSyncScopeNarrow">
    <property name="text">
-    <string>Show Sync Scope</string>
+    <string>Show Sync Scope Narrow</string>
    </property>
   </action>
   <action name="actionScopeOffset">
@@ -229,6 +282,11 @@
     <string>Scope Offset</string>
    </property>
   </action>
+  <action name="actionShowSyncScopeWide">
+   <property name="text">
+    <string>Show Sync Scope Wide</string>
+   </property>
+  </action>
  </widget>
  <customwidgets>
   <customwidget>
@@ -249,9 +307,13 @@
    <header>gallerywidget.h</header>
    <container>1</container>
   </customwidget>
+  <customwidget>
+   <class>spectrumWidget</class>
+   <extends>QFrame</extends>
+   <header>spectrumwidget.h</header>
+   <container>1</container>
+  </customwidget>
  </customwidgets>
- <resources>
-  <include location="qsstv.qrc"/>
- </resources>
+ <resources/>
  <connections/>
 </ui>
diff --git a/qsstv/qsstv.pro b/qsstv/qsstv.pro
index f36c370..fc4980e 100644
--- a/qsstv/qsstv.pro
+++ b/qsstv/qsstv.pro
@@ -1,439 +1,528 @@
 #-------------------------------------------------
 #
-# Project created by QtCreator 2013-01-21T00:18:40
+# Project created by QtCreator 2014-08-10T15:28:21
 #
 #-------------------------------------------------
 
 QT       += core gui xml network
+#multimedia multimediawidgets
 
 greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
 
+QMAKE_CXXFLAGS_DEBUG += -O0
+QMAKE_CXXFLAGS_RELEASE-= -O2
+QMAKE_CXXFLAGS_RELEASE += -O3
+
 TARGET = qsstv
 TEMPLATE = app
+INCLUDEPATH += config utils sound widgets dsp dispatch logbook mainwidgets rig sstv videocapt drmrx drmtx xmlrpc  /usr/include/openjpeg-2.1
 
 
-
-QMAKE_CXXFLAGS_DEBUG += -g3 -O0
-INCLUDEPATH += src widgets ../qwt
-
-
-SOURCES += \
-    drmrx/viterbi_decode.cpp \
-    drmrx/sourcedecoder.cpp \
-    drmrx/nrutil.cpp \
-    drmrx/newfft.cpp \
-    drmrx/msdhardmsc.cpp \
-    drmrx/msdhardfac.cpp \
-    drmrx/mkmscmap.cpp \
-    drmrx/mkfacmap.cpp \
-    drmrx/ludcmp.cpp \
-    drmrx/lubksb.cpp \
-    drmrx/getsymbolidx.cpp \
-    drmrx/getofdmsync.cpp \
-    drmrx/getofdm.cpp \
-    drmrx/getmode.cpp \
-    drmrx/getfoffsint.cpp \
-    drmrx/filter1c.cpp \
-    drmrx/filter1.cpp \
-    drmrx/drmstatusframe.cpp \
-    drmrx/drmdatainput.cpp \
-    drmrx/drmconstellationframe.cpp \
-    drmrx/drm.cpp \
-    drmrx/demodulator.cpp \
-    drmrx/deinterleaver.cpp \
+SOURCES += main.cpp\
+        mainwindow.cpp \
+    config/baseconfig.cpp \
+    config/soundconfig.cpp \
+    utils/dirdialog.cpp \
+    utils/logging.cpp \
+    utils/loggingparams.cpp \
+    appglobal.cpp \
+    utils/supportfunctions.cpp \
+    sound/wavio.cpp \
+    config/directoriesconfig.cpp \
+    config/configdialog.cpp \
+    sound/soundbase.cpp \
+    sound/soundpulse.cpp \
+    widgets/spectrumwidget.cpp \
+    widgets/vumeter.cpp \
+    widgets/fftdisplay.cpp \
+    widgets/markerwidget.cpp \
+    dsp/downsamplefilter.cpp \
+    utils/arraydumper.cpp \
+    sound/soundalsa.cpp \
+    sound/calibration.cpp \
+    dsp/synthes.cpp \
+    dsp/filterparam.cpp \
+    sound/waterfalltext.cpp \
+    utils/macroexpansion.cpp \
+    widgets/imageviewer.cpp \
+    editor/editor.cpp \
+    editor/editorscene.cpp \
+    editor/editorview.cpp \
+    editor/gradientdialog.cpp \
+    editor/graphicitems.cpp \
+    widgets/textdisplay.cpp \
+    dispatch/dispatcher.cpp \
+    drmrx/bits2bytes.cpp \
+    drmrx/channeldecode.cpp \
     drmrx/crc16_bytewise.cpp \
     drmrx/crc8_c.cpp \
-    drmrx/channeldecode.cpp \
-    drmrx/bits2bytes.cpp \
-    drmtx/drmtransmitter.cpp \
-    drmtx/common/Parameter.cpp \
-    drmtx/common/OFDM.cpp \
-    drmtx/common/DrmTransmitter.cpp \
-    drmtx/common/DRMSignalIO.cpp \
-    drmtx/common/DataIO.cpp \
-    drmtx/common/csoundout.cpp \
-    drmtx/common/datadecoding/MOTSlideShow.cpp \
-    drmtx/common/datadecoding/DataDecoder.cpp \
+    drmrx/deinterleaver.cpp \
+    drmrx/demodulator.cpp \
+    drmrx/drm.cpp \
+    drmrx/drmconstellationframe.cpp \
+    drmrx/drmpsdframe.cpp \
+    drmrx/drmrx.cpp \
+    drmrx/drmstatusframe.cpp \
+    drmrx/filter1.cpp \
+    drmrx/filter1c.cpp \
+    drmrx/fixform.cpp \
+    drmrx/getfoffsint.cpp \
+    drmrx/getmode.cpp \
+    drmrx/getofdm.cpp \
+    drmrx/getofdmsync.cpp \
+    drmrx/getsymbolidx.cpp \
+    drmrx/lubksb.cpp \
+    drmrx/ludcmp.cpp \
+    drmrx/mkfacmap.cpp \
+    drmrx/mkmscmap.cpp \
+    drmrx/msdhardfac.cpp \
+    drmrx/msdhardmsc.cpp \
+    drmrx/newfft.cpp \
+    drmrx/nrutil.cpp \
+    drmrx/psdcmean.cpp \
+    drmrx/psdmean.cpp \
+    drmrx/sourcedecoder.cpp \
+    drmrx/viterbi_decode.cpp \
     drmtx/common/datadecoding/DABMOT.cpp \
+    drmtx/common/datadecoding/DataDecoder.cpp \
+    drmtx/common/datadecoding/MOTSlideShow.cpp \
     drmtx/common/FAC/FAC.cpp \
-    drmtx/common/interleaver/SymbolInterleaver.cpp \
     drmtx/common/interleaver/BlockInterleaver.cpp \
-    drmtx/common/matlib/MatlibStdToolbox.cpp \
+    drmtx/common/interleaver/SymbolInterleaver.cpp \
     drmtx/common/matlib/MatlibSigProToolbox.cpp \
-    drmtx/common/mlc/QAMMapping.cpp \
-    drmtx/common/mlc/MLC.cpp \
-    drmtx/common/mlc/EnergyDispersal.cpp \
-    drmtx/common/mlc/ConvEncoder.cpp \
-    drmtx/common/mlc/ChannelCode.cpp \
+    drmtx/common/matlib/MatlibStdToolbox.cpp \
     drmtx/common/mlc/BitInterleaver.cpp \
-    drmtx/common/ofdmcellmapping/OFDMCellMapping.cpp \
+    drmtx/common/mlc/ChannelCode.cpp \
+    drmtx/common/mlc/ConvEncoder.cpp \
+    drmtx/common/mlc/EnergyDispersal.cpp \
+    drmtx/common/mlc/MLC.cpp \
+    drmtx/common/mlc/QAMMapping.cpp \
     drmtx/common/ofdmcellmapping/CellMappingTable.cpp \
+    drmtx/common/ofdmcellmapping/OFDMCellMapping.cpp \
     drmtx/common/SDC/SDCTransmit.cpp \
     drmtx/common/sourcedecoders/AudioSourceDecoder.cpp \
     drmtx/common/tables/TableFAC.cpp \
-    drmtx/common/util/Utilities.cpp \
     drmtx/common/util/CRC.cpp \
-    dsp/synthes.cpp \
-    dsp/filterparam.cpp \
-    dsp/filter.cpp \
-    dsp/downsamplefilter.cpp \
-    editor/graphicitems.cpp \
-    editor/gradientdialog.cpp \
-    editor/editorview.cpp \
-    editor/editorscene.cpp \
-    editor/editor.cpp \
+    drmtx/common/util/Utilities.cpp \
+    drmtx/common/csoundout.cpp \
+    drmtx/common/DataIO.cpp \
+    drmtx/common/DRMSignalIO.cpp \
+    drmtx/common/DrmTransmitter.cpp \
+    drmtx/common/OFDM.cpp \
+    drmtx/common/Parameter.cpp \
+    drmtx/bsrform.cpp \
+    drmtx/drmparams.cpp \
+    drmtx/drmtransmitter.cpp \
+    drmtx/drmtx.cpp \
+    logbook/logbook.cpp \
+    mainwidgets/gallerywidget.cpp \
+    mainwidgets/rxfunctions.cpp \
+    mainwidgets/rxwidget.cpp \
+    mainwidgets/txfunctions.cpp \
+    mainwidgets/txwidget.cpp \
+    rig/freqdisplay.cpp \
     rig/rigcontrol.cpp \
-		sound/wavio.cpp \
-    sound/waterfalltext.cpp \
-    sound/soundio.cpp \
-    sound/soundcontrol.cpp \
-    sound/resampler.cpp \
-    sound/resamplefilter.cpp \
-    sound/calibration.cpp \
-    sstv/modes/moderobot2.cpp \
-    sstv/modes/moderobot1.cpp \
-    sstv/modes/modergb.cpp \
-    sstv/modes/modepd.cpp \
-    sstv/modes/modegbr2.cpp \
-    sstv/modes/modegbr.cpp \
-    sstv/modes/modebw.cpp \
-    sstv/modes/modebase.cpp \
     sstv/modes/modeavt.cpp \
-    sstv/syncprocessor.cpp \
-    sstv/sstvparam.cpp \
+    sstv/modes/modebase.cpp \
+    sstv/modes/modebw.cpp \
+    sstv/modes/modegbr.cpp \
+    sstv/modes/modegbr2.cpp \
+    sstv/modes/modepd.cpp \
+    sstv/modes/modergb.cpp \
+    sstv/modes/moderobot1.cpp \
+    sstv/modes/moderobot2.cpp \
     sstv/cw.cpp \
-    utils/supportfunctions.cpp \
-    utils/rs.cpp \
-    utils/reedsolomoncoder.cpp \
-    utils/loggingparams.cpp \
-    utils/logging.cpp \
-    utils/ftp.cpp \
-    videocapt/videocapture.cpp \
-    widgets/waterfallform.cpp \
-    widgets/vumeter.cpp \
-    widgets/spectrumwidget.cpp \
-    widgets/qscale.cpp \
-    widgets/imageviewer.cpp \
-    widgets/fftdisplay.cpp \
-    widgets/cameracontrol.cpp \
-    widgets/blockview.cpp \
-    txwidget.cpp \
-    txfunctions.cpp \
-    rxwidget.cpp \
-    rxfunctions.cpp \
-    qsstvglobal.cpp \
-    mainwindow.cpp \
-    main.cpp \
-    gallerywidget.cpp \
-    dispatcher.cpp \
-    configparams.cpp \
-    configdialog.cpp \
-    drmrx/psdmean.cpp \
-    drmrx/psdcmean.cpp \
-    drmrx/drmpsdframe.cpp \
-    drmtx/bsrform.cpp \
-    drmrx/fixform.cpp \
-    rig/rigcontrolform.cpp \
+    sstv/sstvparam.cpp \
+    sstv/sstvrx.cpp \
+    sstv/sstvtx.cpp \
+    sstv/syncprocessor.cpp \
     utils/qurlinfo.cpp \
-    utils/qftp.cpp \
-    utils/qjp2io.cpp \
-    widgets/textdisplay.cpp \
-    rig/freqdisplay.cpp \
-    widgets/markerwidget.cpp \
-    utils/hybridcrypt.cpp \
-    utils/macroexpansion.cpp \
-    xmlrpc/maiaXmlRpcClient.cpp \
+    utils/reedsolomoncoder.cpp \
+    utils/rs.cpp \
+    xmlrpc/ipcmessage.cpp \
     xmlrpc/maiaFault.cpp \
-    xmlrpc/maiaXmlRpcServer.cpp \
     xmlrpc/maiaObject.cpp \
+    xmlrpc/maiaXmlRpcClient.cpp \
+    xmlrpc/maiaXmlRpcServer.cpp \
     xmlrpc/maiaXmlRpcServerConnection.cpp \
     xmlrpc/xmlinterface.cpp \
-    drmprofileform.cpp \
-    xmlrpc/ipcmessage.cpp \
-    logbook/logbook.cpp
+    config/operatorconfig.cpp \
+    widgets/extviewer.cpp \
+    config/guiconfig.cpp \
+    utils/ftp.cpp \
+    utils/qftp.cpp \
+    sound/resamplefilter.cpp \
+    widgets/imagematrix.cpp \
+    widgets/waterfallform.cpp \
+    config/rigconfig.cpp \
+    config/cwconfig.cpp \
+    config/drmprofileconfig.cpp \
+    config/ftpconfig.cpp \
+    config/hybridconfig.cpp \
+    config/repeaterconfig.cpp \
+    config/waterfallconfig.cpp \
+    utils/hybridcrypt.cpp \
+    videocapt/cameradialog.cpp \
+    videocapt/imagesettings.cpp \
+    videocapt/v4l2control.cpp \
+    videocapt/videocapture.cpp \
+    sstv/visfskid.cpp \
+    dsp/filters.cpp \
+    dsp/filter.cpp \
+    widgets/drmsegmentsview.cpp \
+    widgets/xyzplaintextedit.cpp \
+    utils/hexconvertor.cpp \
+    config/frequencyselectwidget.cpp \
+    editor/canvassizeform.cpp \
+    utils/fftcalc.cpp \
+    config/hybridnotifyconfig.cpp \
+    utils/jp2io.cpp \
+    utils/color.cpp
 
-HEADERS  += \
-    drmrx/viterbi_decode.h \
-    drmrx/structtemplates.h \
-    drmrx/sourcedecoder.h \
-    drmrx/resamplefilter.h \
-    drmrx/nrutil.h \
-    drmrx/msd_hard_sdc.h \
-    drmrx/msd_hard.h \
-    drmrx/drmstatusframe.h \
-    drmrx/drmproto.h \
-    drmrx/drmdefs.h \
-    drmrx/drmdatainput.h \
-    drmrx/drmconstellationframe.h \
-    drmrx/drm.h \
+
+HEADERS  += mainwindow.h \
+    config/baseconfig.h \
+    config/configparams.h \
+    config/soundconfig.h \
+    utils/dirdialog.h \
+    utils/logging.h \
+    utils/loggingparams.h \
+    appglobal.h \
+    utils/supportfunctions.h \
+    utils/buffermanag.h \
+    sound/wavio.h \
+    config/directoriesconfig.h \
+    appdefs.h \
+    config/configdialog.h \
+    sound/soundbase.h \
+    sound/soundpulse.h \
+    widgets/spectrumwidget.h \
+    widgets/vumeter.h \
+    widgets/fftdisplay.h \
+    widgets/markerwidget.h \
+    dsp/downsamplefilter.h \
+    dsp/nco.h \
+    utils/macroexpansion.h \
+    utils/arraydumper.h \
+    sound/soundalsa.h \
+    sound/calibration.h \
+    dsp/synthes.h \
+    dsp/filterparam.h \
+    sound/waterfalltext.h \
+    utils/macroexpansion.h \
+    widgets/imageviewer.h \
+    editor/editor.h \
+    editor/editorscene.h \
+    editor/editorview.h \
+    editor/gradientdialog.h \
+    editor/graphicitems.h \
+    editor/qdialog_p.h \
+    widgets/textdisplay.h \
+    dispatch/dispatcher.h \
+    dispatch/dispatchevents.h \
     drmrx/demodulator.h \
-    drmtx/common/datadecoding/MOTSlideShow.h \
-    drmtx/common/datadecoding/DataDecoder.h \
+    drmrx/drm.h \
+    drmrx/drmconstellationframe.h \
+    drmrx/drmdefs.h \
+    drmrx/drmproto.h \
+    drmrx/drmpsdframe.h \
+    drmrx/drmrx.h \
+    drmrx/drmstatusframe.h \
+    drmrx/fixform.h \
+    drmrx/mkmap.h \
+    drmrx/msd_hard.h \
+    drmrx/msd_hard_sdc.h \
+    drmrx/nrutil.h \
+    drmrx/resamplefilter.h \
+    drmrx/sourcedecoder.h \
+    drmrx/structtemplates.h \
+    drmrx/viterbi_decode.h \
     drmtx/common/datadecoding/DABMOT.h \
-    drmtx/drmtransmitter.h \
-    drmtx/config.h \
-    drmtx/common/soundinterface.h \
-    drmtx/common/Parameter.h \
-    drmtx/common/OFDM.h \
-    drmtx/common/GlobalDefinitions.h \
-    drmtx/common/DrmTransmitter.h \
-    drmtx/common/DRMSignalIO.h \
-    drmtx/common/DataIO.h \
-    drmtx/common/csoundout.h \
+    drmtx/common/datadecoding/DataDecoder.h \
+    drmtx/common/datadecoding/MOTSlideShow.h \
     drmtx/common/FAC/FAC.h \
-    drmtx/common/interleaver/SymbolInterleaver.h \
     drmtx/common/interleaver/BlockInterleaver.h \
-    drmtx/common/matlib/MatlibStdToolbox.h \
-    drmtx/common/matlib/MatlibSigProToolbox.h \
+    drmtx/common/interleaver/SymbolInterleaver.h \
     drmtx/common/matlib/Matlib.h \
-    drmtx/common/mlc/QAMMapping.h \
-    drmtx/common/mlc/MLC.h \
-    drmtx/common/mlc/EnergyDispersal.h \
-    drmtx/common/mlc/ConvEncoder.h \
-    drmtx/common/mlc/ChannelCode.h \
+    drmtx/common/matlib/MatlibSigProToolbox.h \
+    drmtx/common/matlib/MatlibStdToolbox.h \
     drmtx/common/mlc/BitInterleaver.h \
-    drmtx/common/ofdmcellmapping/OFDMCellMapping.h \
+    drmtx/common/mlc/ChannelCode.h \
+    drmtx/common/mlc/ConvEncoder.h \
+    drmtx/common/mlc/EnergyDispersal.h \
+    drmtx/common/mlc/MLC.h \
+    drmtx/common/mlc/QAMMapping.h \
     drmtx/common/ofdmcellmapping/CellMappingTable.h \
+    drmtx/common/ofdmcellmapping/OFDMCellMapping.h \
     drmtx/common/SDC/SDC.h \
     drmtx/common/sourcedecoders/AudioSourceDecoder.h \
-    drmtx/common/tables/TableQAMMapping.h \
-    drmtx/common/tables/TableMLC.h \
-    drmtx/common/tables/TableFAC.h \
-    drmtx/common/tables/TableDRMGlobal.h \
-    drmtx/common/tables/TableCarrier.h \
-    drmtx/common/tables/TableCarMap.h \
     drmtx/common/tables/TableAMSS.h \
-    drmtx/common/util/Utilities.h \
-    drmtx/common/util/Modul.h \
-    drmtx/common/util/CRC.h \
+    drmtx/common/tables/TableCarMap.h \
+    drmtx/common/tables/TableCarrier.h \
+    drmtx/common/tables/TableDRMGlobal.h \
+    drmtx/common/tables/TableFAC.h \
+    drmtx/common/tables/TableMLC.h \
+    drmtx/common/tables/TableQAMMapping.h \
     drmtx/common/util/Buffer.h \
-    dsp/synthes.h \
-    dsp/nco.h \
-    dsp/filterparam.h \
-    dsp/filter.h \
-    dsp/downsamplefilter.h \
-    editor/qdialog_p.h \
-    editor/graphicitems.h \
-    editor/gradientdialog.h \
-    editor/editorview.h \
-    editor/editorscene.h \
-    editor/editor.h \
+    drmtx/common/util/CRC.h \
+    drmtx/common/util/Modul.h \
+    drmtx/common/util/Utilities.h \
+    drmtx/common/csoundout.h \
+    drmtx/common/DataIO.h \
+    drmtx/common/DRMSignalIO.h \
+    drmtx/common/DrmTransmitter.h \
+    drmtx/common/GlobalDefinitions.h \
+    drmtx/common/OFDM.h \
+    drmtx/common/Parameter.h \
+    drmtx/common/soundinterface.h \
+    drmtx/bsrform.h \
+    drmtx/config.h \
+    drmtx/drmparams.h \
+    drmtx/drmtransmitter.h \
+    drmtx/drmtx.h \
+    logbook/logbook.h \
+    mainwidgets/gallerywidget.h \
+    mainwidgets/rxfunctions.h \
+    mainwidgets/rxwidget.h \
+    mainwidgets/txfunctions.h \
+    mainwidgets/txwidget.h \
+    rig/freqdisplay.h \
     rig/rigcontrol.h \
-    sound/wavio.h \
-    sound/waterfalltext.h \
-    sound/soundio.h \
-    sound/soundcontrol.h \
-    sound/resampler.h \
-    sound/resampler.cpp_new \
-    sound/resamplefilter.h \
-    sound/calibration.h \
-    sstv/modes/modes.h \
-    sstv/modes/moderobot2.h \
-    sstv/modes/moderobot1.h \
-    sstv/modes/modergb.h \
-    sstv/modes/modepd.h \
-    sstv/modes/modegbr2.h \
-    sstv/modes/modegbr.h \
-    sstv/modes/modebw.h \
-    sstv/modes/modebase.h \
     sstv/modes/modeavt.h \
-    sstv/syncprocessor.h \
-    sstv/sstvparam.h \
+    sstv/modes/modebase.h \
+    sstv/modes/modebw.h \
+    sstv/modes/modegbr.h \
+    sstv/modes/modegbr2.h \
+    sstv/modes/modepd.h \
+    sstv/modes/modergb.h \
+    sstv/modes/moderobot1.h \
+    sstv/modes/moderobot2.h \
+    sstv/modes/modes.h \
     sstv/cw.h \
-    utils/vector.h \
-    utils/supportfunctions.h \
-    utils/rs.h \
-    utils/reedsolomoncoder.h \
-    utils/loggingparams.h \
-    utils/logging.h \
-    utils/ftp.h \
-    utils/buffermanag.h \
-    videocapt/videocapture.h \
-    widgets/waterfallform.h \
-    widgets/vumeter.h \
-    widgets/spectrumwidget.h \
-    widgets/qscale.h \
-    widgets/imageviewer.h \
-    widgets/fftdisplay.h \
-    widgets/cameracontrol.h \
-    widgets/blockview.h \
-    txwidget.h \
-    txfunctions.h \
-    rxwidget.h \
-    rxfunctions.h \
-    qsstvglobal.h \
-    qsstvdefs.h \
-    mainwindow.h \
-    gallerywidget.h \
-    dispatchevents.h \
-    dispatcher.h \
-    configparams.h \
-    configdialog.h \
-    drmrx/drmpsdframe.h \
-    drmtx/bsrform.h \
-    drmrx/fixform.h \
-    rig/rigcontrolform.h \
-    drmrx/mkmap.h \
+    sstv/sstvparam.h \
+    sstv/sstvrx.h \
+    sstv/sstvtx.h \
+    sstv/syncprocessor.h \
     utils/qurlinfo.h \
-    utils/qftp.h \
-    utils/qjp2io.h \
-    widgets/textdisplay.h \
-    rig/freqdisplay.h \
-    rig/rigparams.h \
-    widgets/markerwidget.h \
-    utils/hybridcrypt.h \
-    utils/macroexpansion.h \
+    utils/reedsolomoncoder.h \
+    utils/rs.h \
+    utils/vector.h \
+    xmlrpc/ipcmessage.h \
     xmlrpc/maiaFault.h \
-    xmlrpc/maiaXmlRpcServer.h \
-    xmlrpc/maiaXmlRpcClient.h \
     xmlrpc/maiaObject.h \
+    xmlrpc/maiaXmlRpcClient.h \
+    xmlrpc/maiaXmlRpcServer.h \
     xmlrpc/maiaXmlRpcServerConnection.h \
     xmlrpc/xmlinterface.h \
-    drmprofileform.h \
-    xmlrpc/ipcmessage.h \
-    logbook/logbook.h
+    config/operatorconfig.h \
+    widgets/extviewer.h \
+    config/guiconfig.h \
+    utils/ftp.h \
+    utils/qftp.h \
+    sound/resamplefilter.h \
+    widgets/imagematrix.h \
+    widgets/waterfallform.h \
+    config/rigconfig.h \
+    config/cwconfig.h \
+    config/drmprofileconfig.h \
+    config/ftpconfig.h \
+    config/hybridconfig.h \
+    config/repeaterconfig.h \
+    config/waterfallconfig.h \
+    utils/hybridcrypt.h \
+    videocapt/cameradialog.h \
+    videocapt/imagesettings.h \
+    videocapt/v4l2control.h \
+    videocapt/videocapture.h \
+    sstv/visfskid.h \
+    dsp/filters.h \
+    dsp/filter.h \
+    widgets/drmsegmentsview.h \
+    widgets/xyzplaintextedit.h \
+    utils/hexconvertor.h \
+    config/frequencyselectwidget.h \
+    editor/canvassizeform.h \
+    utils/fftcalc.h \
+    config/hybridnotifyconfig.h \
+    utils/jp2io.h \
+    utils/color.h
 
-FORMS    += \
-    drmrx/drmstatusframe.ui \
-    drmrx/drmpsdframe.ui \
-    drmrx/drmconstellationframe.ui \
-    editor/textform.ui \
-    editor/gradientform.ui \
-    editor/editorform.ui \
-    sound/soundcontrol.ui \
-    sound/calibrationform.ui \
-    sound/calibration.ui \
+
+FORMS += mainwindow.ui \
+    config/guiconfig.ui \
+    config/soundconfig.ui \
     utils/loggingform.ui \
-    widgets/waterfallform.ui \
-    widgets/sweepform.ui \
+    config/directoriesconfig.ui \
+    config/configdialog.ui \
     widgets/spectrumwidget.ui \
-    widgets/freqform.ui \
-    widgets/cameracontrol.ui \
-    widgets/blockview.ui \
-    txwidget.ui \
-    rxwidget.ui \
-    mainwindow.ui \
-    gallerywidget.ui \
-    configform.ui \
-    drmtx/bsrform.ui \
-    drmrx/fixform.ui \
-    rig/rigcontrolform.ui \
+    sound/calibration.ui \
+    editor/editorform.ui \
+    editor/gradientform.ui \
+    editor/textform.ui \
     widgets/textdisplay.ui \
+    config/operatorconfig.ui \
+    drmrx/drmconstellationframe.ui \
+    drmrx/drmpsdframe.ui \
+    drmrx/drmstatusframe.ui \
+    widgets/extviewer.ui \
+    widgets/sweepform.ui \
+    widgets/waterfallform.ui \
+    config/rigconfig.ui \
+    config/cwconfig.ui \
+    config/drmprofileconfig.ui \
+    config/ftpconfig.ui \
+    config/hybridconfig.ui \
+    config/repeaterconfig.ui \
+    config/waterfallconfig.ui \
+    drmtx/bsrform.ui \
+    mainwidgets/gallerywidget.ui \
+    mainwidgets/rxwidget.ui \
+    mainwidgets/txwidget.ui \
+    widgets/freqform.ui \
     rig/freqdisplay.ui \
-    drmprofileform.ui
+    videocapt/cameradialog.ui \
+    videocapt/imagesettings.ui \
+    widgets/drmsegmentsview.ui \
+    drmrx/fixform.ui \
+    config/frequencyselectwidget.ui \
+    editor/canvassizeform.ui \
+    config/hybridnotifyconfig.ui
+
+ LIBS += -lasound \
+         -lpulse \
+         -lpulse-simple \
+         -lfftw3f \
+         -lfftw3 \
+         -lhamlib \
+          -lv4l2 \
+         -lv4lconvert \
+         -lopenjp2 \
+         -lrt
 
-RESOURCES += \
-    qsstv.qrc
 
 OTHER_FILES += \
-    icons/transparency.png \
-    icons/tone.png \
-    icons/text.png \
-    icons/sweep.png \
-    icons/stop.png \
-    icons/start.png \
-    icons/replay.png \
-    icons/qsstvsplash.png \
-    icons/qsstv.png \
-    icons/line.png \
-    icons/image.png \
-    icons/gradient.png \
-    icons/frect.png \
-    icons/filesave.png \
     icons/fileopen.png \
-    icons/filenew.png \
-    icons/fcircle.png \
-    icons/eraser.png \
-    icons/edit.png \
-    icons/doubletone.png \
-    icons/colorselector.png \
-    icons/colorpicker.png \
-    icons/colorline.png \
-    icons/colorfill.png \
-    icons/camera.png \
-    icons/arrow.png \
-    Documentation/manual/qsstv.css \
-    Documentation/manual/manual.txt \
-    Documentation/manual/manual.doxy \
-    Doxyfile \
-    COPYING \
+    icons/filesave.png \
     icons/mgc.raw \
-    Documentation/manual/images/Gallery_rx.png \
-    Documentation/manual/images/tx-with-template.png \
-    Documentation/manual/images/Gallery_tx.png \
-    Documentation/manual/images/receivesstv.png \
-    Documentation/manual/images/transmitsstv.png \
-    Documentation/manual/images/waterfall.png \
-    Documentation/manual/images/receivedrm.png \
-    Documentation/manual/images/transmitdrm.png \
-    Documentation/manual/images/editor_3.png \
-    Documentation/manual/images/Gallery_template.png \
-    Documentation/manual/images/config4.png \
-    Documentation/manual/images/fix.png \
-    Documentation/manual/images/config2.png \
-    Documentation/manual/images/config3.png \
-    Documentation/manual/images/config6.png \
-    Documentation/manual/images/editor_2.png \
-    Documentation/manual/images/config7.png \
-    Documentation/manual/images/config10.png \
-    Documentation/manual/images/config1.png \
-    Documentation/manual/images/bsr_select.png \
-    Documentation/manual/images/config8.png \
-    Documentation/manual/images/config9.png \
-    Documentation/manual/images/editor_1.png \
-    Documentation/manual/images/config5.png \
-    Documentation/manual/images/wftextpopup.png \
-    Documentation/manual/images/config.png \
-    Documentation/manual/images/calibration.png \
-    Documentation/manual/images/bsr_nfy.png \
-    Documentation/manual/images/statusbar.png \
-    Documentation/manual/images/statusleds.png \
-    Documentation/manual/images/hybrid_checkbox.png \
-    Documentation/manual/images/hybrid_dis_checkbox.png \
-    Documentation/manual/images/config11.png \
-    Documentation/manual/images/flrig1.png \
-    Documentation/manual/images/rxdrm_constellation.png \
-    Documentation/manual/images/rxdrm_status.png \
-    Documentation/manual/images/rxdrm_segments.png \
-    Documentation/manual/images/txdrm_compression.png \
-    Documentation/manual/images/txdrm_options.png \
-    Documentation/manual/images/txdrm_status.png \
-    Documentation/manual/images/cqrlog1.png \
-    Documentation/manual/images/cqrlog2.png
-
-
- LIBS += -lasound \
-	-lhamlib \
-	 -lfftw3f \
-	-lfftw3 \
- -ljasper
+    icons/mgc2.raw \
+    icons/arrow.png \
+    icons/camera.png \
+    icons/colorfill.png \
+    icons/colorline.png \
+    icons/colorpicker.png \
+    icons/colorselector.png \
+    icons/doubleleft.png \
+    icons/doubleright.png \
+    icons/doubletone.png \
+    icons/edit.png \
+    icons/eraser.png \
+    icons/fcircle.png \
+    icons/filenew.png \
+    icons/frect.png \
+    icons/gradient.png \
+    icons/image.png \
+    icons/left.png \
+    icons/line.png \
+    icons/qsstv.png \
+    icons/qsstvsplash.png \
+    icons/replay.png \
+    icons/start.png \
+    icons/stop.png \
+    icons/sweep.png \
+    icons/text.png \
+    icons/tone.png \
+    icons/transparency.png \
+    icons/whatsthis.png \
+    documentation/manual/qsstv.css \
+    documentation/manual/images/rxdrm_segments.png \
+    documentation/manual/images/hybrid_dis_checkbox.png \
+    documentation/manual/images/hybrid_checkbox.png \
+    documentation/manual/images/statusleds.png \
+    documentation/manual/images/txdrm_compression.png \
+    documentation/manual/images/rxdrm_constellation.png \
+    documentation/manual/images/statusbar.png \
+    documentation/manual/images/wf_bsr_id.png \
+    documentation/manual/images/bsr_nfy.png \
+    documentation/manual/images/rxdrm_status.png \
+    documentation/manual/images/txdrm_status.png \
+    documentation/manual/images/config.png \
+    documentation/manual/images/calibration.png \
+    documentation/manual/images/sstvdrmselect.png \
+    documentation/manual/images/wftextpopup.png \
+    documentation/manual/images/txdrm_options.png \
+    documentation/manual/images/editor_1.png \
+    documentation/manual/images/bsr_select.png \
+    documentation/manual/images/config9.png \
+    documentation/manual/images/cqrlog1.png \
+    documentation/manual/images/config5.png \
+    documentation/manual/images/config1.png \
+    documentation/manual/images/config8.png \
+    documentation/manual/images/config11.png \
+    documentation/manual/images/flrig1.png \
+    documentation/manual/images/editor_2.png \
+    documentation/manual/images/config6.png \
+    documentation/manual/images/config3.png \
+    documentation/manual/images/fix.png \
+    documentation/manual/images/config2.png \
+    documentation/manual/images/config10.png \
+    documentation/manual/images/config7.png \
+    documentation/manual/images/config4.png \
+    documentation/manual/images/cqrlog2.png \
+    documentation/manual/images/Gallery_template.png \
+    documentation/manual/images/editor_3.png \
+    documentation/manual/images/waterfall.png \
+    documentation/manual/images/receivedrm.png \
+    documentation/manual/images/Gallery_tx.png \
+    documentation/manual/images/transmitdrm.png \
+    documentation/manual/images/tx-with-template.png \
+    documentation/manual/images/Gallery_rx.png \
+    documentation/manual/manual.txt \
+    documentation/manual/manual.doxy \
+    documentation/manual/images/txwidget1.png \
+    documentation/manual/images/rxwidget1.png \
+    icons/binary.png \
+    documentation/manual/images/Gallery_image_options.png \
+    documentation/manual/images/eraser.png \
+    documentation/manual/images/refreshbutton.png \
+    documentation/manual/images/config12.png \
+    documentation/manual/images/binary.png \
+    documentation/manual/images/vk4aes.jpg \
+    documentation/manual/images/multiline.png \
+    documentation/manual/images/entertext.png \
+    ../COPYING \
+    ../README.txt \
+    documentation/manual/images/editor_image_size.png
 
 CONFIG(debug ,debug|release){
-	message(added debugging)
-SOURCES +=     scope/scopeoffset.cpp \
-		scope/scopeview.cpp \
-		scope/scopeplot.cpp
+        message(added debugging)
+SOURCES +=      scope/scopeoffset.cpp \
+                scope/scopeview.cpp \
+                scope/scopeplot.cpp
 HEADERS  += scope/scopeoffset.h \
-		scope/scopeview.h \
-		scope/scopeplot.h
+                scope/scopeview.h \
+                scope/scopeplot.h
 
 FORMS   += scope/scopeoffset.ui \
-				scope/plotform.ui
-
- INCLUDEPATH += /usr/include/qwt
+                scope/plotform.ui
+ INCLUDEPATH += ../qwt
  LIBS += ../qwt/libqwt.a
 }
 
 CONFIG(debug ,debug|release){
-dox.commands = cd $$PWD/Documentation/manual ;doxygen  manual.doxy;
+dox.commands = cd $$PWD/documentation/manual ;doxygen  manual.doxy;
 dox.depends= FORCE
 PRE_TARGETDEPS       +=    dox
 message(dox will be generated)
 }
+
 dox.path=/usr/share/doc/$$TARGET
 dox.files= $$PWD/manual/*
 QMAKE_EXTRA_TARGETS   +=   dox
 
+
+
+RESOURCES += \
+    qsstv.qrc
+
 target.path = /usr/bin
 INSTALLS += target dox
-
diff --git a/qsstv/qsstv.qrc b/qsstv/qsstv.qrc
index b35049b..18443d6 100644
--- a/qsstv/qsstv.qrc
+++ b/qsstv/qsstv.qrc
@@ -27,5 +27,11 @@
         <file>icons/mgc.raw</file>
         <file>icons/mgc2.raw</file>
         <file>icons/colorline.png</file>
+        <file>icons/left.png</file>
+        <file>icons/doubleleft.png</file>
+        <file>icons/doubleright.png</file>
+        <file>icons/binary.png</file>
+        <file>icons/down.png</file>
+        <file>icons/up.png</file>
     </qresource>
 </RCC>
diff --git a/qsstv/qsstvglobal.cpp b/qsstv/qsstvglobal.cpp
deleted file mode 100644
index dc384e2..0000000
--- a/qsstv/qsstvglobal.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-/**************************************************************************
-*   Copyright (C) 2000-2012 by Johan Maes                                 *
-*   on4qz at telenet.be                                                      *
-*   http://users.telenet.be/on4qz                                         *
-*                                                                         *
-*   This program is free software; you can redistribute it and/or modify  *
-*   it under the terms of the GNU General Public License as published by  *
-*   the Free Software Foundation; either version 2 of the License, or     *
-*   (at your option) any later version.                                   *
-*                                                                         *
-*   This program is distributed in the hope that it will be useful,       *
-*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
-*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
-*   GNU General Public License for more details.                          *
-*                                                                         *
-*   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.,                                       *
-*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
-***************************************************************************/
-
-#include "qsstvglobal.h"
-
-
-#include <QString>
-#include <QPixmap>
-
-
-
-
-const QString MAJORVERSION  = "8.2";
-const QString CONFIGVERSION = "8.1";
-const QString MINORVERSION  = ".12";
-const QString LOGVERSION = ("qsstv."+MAJORVERSION+MINORVERSION+".log");
-const QString ORGANIZATION = "ON4QZ";
-const QString APPLICATION  = ("qsstv" +CONFIGVERSION);
-const QString qsstvVersion=QString("QSSTV " + MAJORVERSION+MINORVERSION);
-const QString shortText=QString("HAMDRM Software based on RX/TXAMADRM\n from PA0MBO")
-
-;
-QByteArray *debugPtr;
-QStatusBar *statusBarPtr;
-configDialog *confDiag;
-#ifndef QT_NO_DEBUG
-scopeView *scopeViewerData;
-scopeView *scopeViewerSync;
-#endif
-
-mainWindow *mainWindowPtr;
-dispatcher *dispatcherPtr;
-waterfallText *waterfallPtr;
-QSplashScreen *splashPtr;
-QString splashStr;
-
-
-
-QCursor *cpCursor;
-logFile *logfile;
-
-
-// for DRM
-emscStatus msc_valid;
-int bodyTotalSegments;
-int rxSegments;
-int currentSegmentNumber;
-unsigned int rxTransportID;
-//unsigned int bitsPerSecond;
-QList<short unsigned int> drmBlockList;
-sourceDecoder srcDecoder;
-uint txTransportID;
-QList<short unsigned int> fixBlockList;
-bool stopDRM;
-float avgSNR;
-float lastAvgSNR;
-QPixmap *greenPXM;
-QPixmap *redPXM;
-
-logBook *logBookPtr;
-xmlInterface *xmlIntfPtr;
-
-
-void globalInit(void)
-{
-  logfile=new logFile;
-  logfile->open(LOGVERSION);
-  QPixmap pm(":/icons/colorpicker.png");
-  cpCursor=new QCursor(pm,0,pm.height()-1);
-
-}
-
-void globalEnd(void)
-{
-  logfile->close();
-}
-
diff --git a/qsstv/qsstvglobal.h b/qsstv/qsstvglobal.h
deleted file mode 100644
index 1c55a49..0000000
--- a/qsstv/qsstvglobal.h
+++ /dev/null
@@ -1,88 +0,0 @@
-#ifndef SSTVGLOBAL_H
-#define SSTVGLOBAL_H
-#include <QString>
-#include <QCursor>
-#include "utils/logging.h"
-#include "drmrx/sourcedecoder.h"
-#include "qsstvdefs.h"
-
-
-
-
-class QSplashScreen;
-class QStatusBar;
-class logFile;
-class galleryWidget ;
-class configDialog;
-class dispatcher;
-class rxWidget;
-class txWidget;
-class imageViewer;
-class mainWindow;
-class waterfallText;
-class logBook;
-class xmlInterface;
-
-class synthesizer;
-
-extern const QString MAJORVERSION;
-extern const QString CONFIGVERSION;
-extern const QString MINORVERSION;
-extern const QString ORGANIZATION;
-extern const QString APPLICATION;
-extern const QString qsstvVersion;
-extern const QString shortText;
-#define MAGICNUMBER   (('4'<<24)+('Q'<<16)+('Z'<<8)+'S')
-
-extern QSplashScreen    *splashPtr;
-extern configDialog     *confDiag;
-extern mainWindow *mainWindowPtr;
-extern waterfallText *waterfallPtr;
-extern QString splashStr;
-
-
-extern txWidget *txWidgetPtr;
-extern galleryWidget *galleryWidgetPtr;
-
-extern synthesizer *synthesPtr;
-extern dispatcher *dispatcherPtr;
-extern QStatusBar *statusBarPtr;
-
-// for DRM
-enum emscStatus {INVALID,VALID,ALREADYRECEIVED};
-extern emscStatus msc_valid;
-extern int bodyTotalSegments;
-extern int rxSegments;
-extern int currentSegmentNumber;
-extern unsigned int rxTransportID;
-extern unsigned int bitsPerSecond;
-extern bool stopDRM;
-extern QList<short unsigned int> drmBlockList;
-extern uint txTransportID;
-extern QList<short unsigned int> fixBlockList;
-extern float avgSNR;
-extern float lastAvgSNR;
-
-extern QCursor *cpCursor;
-void globalInit(void);
-void globalEnd(void);
-
-extern logFile *logfile;
-extern logBook *logBookPtr;
-extern xmlInterface *xmlIntfPtr;
-
-#ifndef QT_NO_DEBUG
-class scopeView;
-extern scopeView *scopeViewerData;
-extern scopeView *scopeViewerSync;
-#endif
-
-extern QByteArray *debugPtr;
-extern sourceDecoder srcDecoder;
-
-extern QPixmap *greenPXM;
-extern QPixmap *redPXM;
-
-
-
-#endif
diff --git a/qsstv/rig/freqdisplay.ui b/qsstv/rig/freqdisplay.ui
index bae6f81..0808089 100644
--- a/qsstv/rig/freqdisplay.ui
+++ b/qsstv/rig/freqdisplay.ui
@@ -17,7 +17,16 @@
    <property name="spacing">
     <number>2</number>
    </property>
-   <property name="margin">
+   <property name="leftMargin">
+    <number>1</number>
+   </property>
+   <property name="topMargin">
+    <number>1</number>
+   </property>
+   <property name="rightMargin">
+    <number>1</number>
+   </property>
+   <property name="bottomMargin">
     <number>1</number>
    </property>
    <item>
@@ -357,7 +366,7 @@
      <property name="frameShadow">
       <enum>QFrame::Sunken</enum>
      </property>
-     <property name="numDigits">
+     <property name="digitCount">
       <number>10</number>
      </property>
      <property name="segmentStyle">
diff --git a/qsstv/rig/rigcontrol.cpp b/qsstv/rig/rigcontrol.cpp
index 954bc0f..7e515a1 100644
--- a/qsstv/rig/rigcontrol.cpp
+++ b/qsstv/rig/rigcontrol.cpp
@@ -19,9 +19,7 @@
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
 #include "rigcontrol.h"
-#include "qsstvglobal.h"
-#include "rigparams.h"
-#include <QMessageBox>
+#include "appglobal.h"
 #include <QSplashScreen>
 #include <QApplication>
 #include <sys/ioctl.h>
@@ -30,13 +28,11 @@
 #include "mainwindow.h"
 #include <QMessageBox>
 #include "txwidget.h"
+#include "configparams.h"
 
 
 #define MAXCONFLEN 128
 
-rigControl *rigControllerR1;
-rigControl *rigControllerR2;
-rigControl *rigController;
 
 QList<const rig_caps *> capsList;
 bool radiolistLoaded=false;
@@ -46,324 +42,374 @@ bool radiolistLoaded=false;
 
 int collect(const rig_caps *caps,rig_ptr_t)
 {
-  capsList.append(caps);
-  return 1;
+    capsList.append(caps);
+    return 1;
 }
 
 rigControl::rigControl(int radioIndex)
 {
-  rigControlEnabled=false;
-  catParams.configLabel=QString("radio%1").arg(radioIndex);
-  rig_set_debug(RIG_DEBUG_NONE);
-  getRadioList();
-  serialP=0;
-  xmlIntfPtr=new xmlInterface;
+    rigControlEnabled=false;
+    catParams.configLabel=QString("radio%1").arg(radioIndex);
+    rig_set_debug(RIG_DEBUG_NONE);
+    getRadioList();
+    serialP=0;
+    lastFrequency=0.0;
+    xmlModes<<"USB"<<"LSB"<<"FM"<<"AM";
 }
 
 rigControl::~rigControl()
 {
-  rig_close(my_rig); /* close port */
-  rig_cleanup(my_rig); /* if you care about memory */
+    rig_close(my_rig); /* close port */
+    rig_cleanup(my_rig); /* if you care about memory */
 }
 
 bool rigControl::init()
 {
-  int retcode;
-  if(!catParams.enableCAT) return false;
-  myport.type.rig = RIG_PORT_SERIAL;
-  myport.parm.serial.rate = catParams.baudrate;
-  myport.parm.serial.data_bits =catParams.databits;
-  myport.parm.serial.stop_bits =catParams.stopbits;
-  if(catParams.parity=="Even") myport.parm.serial.parity = RIG_PARITY_EVEN;
-  else if (catParams.parity=="Odd") myport.parm.serial.parity = RIG_PARITY_ODD;
-  else  myport.parm.serial.parity = RIG_PARITY_NONE;
-  if(catParams.handshake=="XOn/Xoff")
-    {
-      myport.parm.serial.handshake = RIG_HANDSHAKE_XONXOFF;
-    }
-  if(catParams.handshake=="Hardware")
-    {
-      myport.parm.serial.handshake = RIG_HANDSHAKE_HARDWARE;
-    }
+    int retcode;
+    if(!catParams.enableCAT) return false;
 
-  else
-    {
-      myport.parm.serial.handshake = RIG_HANDSHAKE_NONE;
-    }
-  strncpy(myport.pathname, (const char *)catParams.serialPort.toLatin1().data(), FILPATHLEN);
-  //  myport.parm.serial.rts_state=RIG_SIGNAL_OFF;
-  //  myport.parm.serial.dtr_state=RIG_SIGNAL_OFF;
-  addToLog(QString("rigcontrol:init myport pathname: %1").arg(myport.pathname),LOGRIGCTRL);
-  catParams.radioModelNumber=getModelNumber(getRadioModelIndex());
-  my_rig = rig_init(catParams.radioModelNumber);
-  if(!my_rig)
+    addToLog(QString("rigcontrol:init myport pathname: %1").arg(myport.pathname),LOGRIGCTRL);
+    catParams.radioModelNumber=getModelNumber(getRadioModelIndex());
+    my_rig = rig_init(catParams.radioModelNumber);
+    if(!my_rig)
     {
-      addToLog(QString("Error in connection using radio model %1").arg(catParams.radioModel),LOGRIGCTRL);
-      initError=QString("Error in connection using radio model %1").arg(catParams.radioModel);
-      return false;
+        addToLog(QString("Error in connection using radio model %1").arg(catParams.radioModel),LOGALL);
+        initError=QString("Error in connection using radio model %1").arg(catParams.radioModel);
+        return false;
     }
 
-  if(QString(my_rig->caps->mfg_name)=="Icom")
+    if(QString(my_rig->caps->mfg_name)=="Icom")
     {
-      if(!catParams.civAddress.isEmpty())
+        if(!catParams.civAddress.isEmpty())
         {
-          rig_set_conf(my_rig, rig_token_lookup(my_rig, "civaddr"), catParams.civAddress.toLatin1());
+            rig_set_conf(my_rig, rig_token_lookup(my_rig, "civaddr"), catParams.civAddress.toLatin1());
         }
     }
 
-  strncpy(my_rig->state.rigport.pathname,(const char *)catParams.serialPort.toLatin1().data(),FILPATHLEN);
-  strncpy(my_rig->state.pttport.pathname,(const char *)catParams.serialPort.toLatin1().data(),FILPATHLEN);
-  my_rig->state.rigport.parm.serial.rate = catParams.baudrate;
-  my_rig->state.rigport.parm.serial.data_bits=catParams.databits;
-  my_rig->state.rigport.parm.serial.stop_bits=catParams.stopbits;
-  if(catParams.parity=="Even") my_rig->state.rigport.parm.serial.parity= RIG_PARITY_EVEN;
-  else if (catParams.parity=="Odd") my_rig->state.rigport.parm.serial.parity = RIG_PARITY_ODD;
-  else  my_rig->state.rigport.parm.serial.parity = RIG_PARITY_NONE;
-  if(catParams.handshake=="XOn/Xoff") my_rig->state.rigport.parm.serial.handshake = RIG_HANDSHAKE_XONXOFF;
-  if(catParams.handshake=="Hardware") my_rig->state.rigport.parm.serial.handshake = RIG_HANDSHAKE_HARDWARE;
-  else my_rig->state.rigport.parm.serial.handshake = RIG_HANDSHAKE_NONE;
-
-
-
-  //my_rig->state.rigport.parm.serial.rts_state=RIG_SIGNAL_OFF;
-  //my_rig->state.rigport.parm.serial.dtr_state=RIG_SIGNAL_OFF;
-  my_rig->state.pttport.type.ptt = catParams.pttType;
-
-  addToLog(QString("rigcontrol:init rigport.pathname: %1").arg(my_rig->state.rigport.pathname),LOGRIGCTRL);
-  retcode = rig_open(my_rig);
-  if (retcode != RIG_OK )
+    strncpy(my_rig->state.rigport.pathname,(const char *)catParams.serialPort.toLatin1().data(),FILPATHLEN);
+    strncpy(my_rig->state.pttport.pathname,(const char *)catParams.serialPort.toLatin1().data(),FILPATHLEN);
+    my_rig->state.rigport.parm.serial.rate = catParams.baudrate;
+    my_rig->state.rigport.parm.serial.data_bits=catParams.databits;
+    my_rig->state.rigport.parm.serial.stop_bits=catParams.stopbits;
+    if(catParams.parity=="Even") my_rig->state.rigport.parm.serial.parity= RIG_PARITY_EVEN;
+    else if (catParams.parity=="Odd") my_rig->state.rigport.parm.serial.parity = RIG_PARITY_ODD;
+    else  my_rig->state.rigport.parm.serial.parity = RIG_PARITY_NONE;
+    if(catParams.handshake=="XOn/Xoff") my_rig->state.rigport.parm.serial.handshake = RIG_HANDSHAKE_XONXOFF;
+    if(catParams.handshake=="Hardware") my_rig->state.rigport.parm.serial.handshake = RIG_HANDSHAKE_HARDWARE;
+    else my_rig->state.rigport.parm.serial.handshake = RIG_HANDSHAKE_NONE;
+    my_rig->state.pttport.type.ptt = catParams.pttType;
+
+    addToLog(QString("rigcontrol:init rigport.pathname: %1").arg(my_rig->state.rigport.pathname),LOGRIGCTRL);
+    retcode = rig_open(my_rig);
+    if (retcode != RIG_OK )
     {
-      addToLog(QString("CAT Error: %1").arg(QString(rigerror(retcode))),LOGRIGCTRL);
-      initError=QString("CAT Error: %1").arg(QString(rigerror(retcode)));
-      return false;
+        addToLog(QString("CAT Error: %1").arg(QString(rigerror(retcode))),LOGALL);
+        initError=QString("CAT Error: %1").arg(QString(rigerror(retcode)));
+        return false;
     }
-  addToLog("rigcontroller successfully opened",LOGRIGCTRL);
-  rigControlEnabled=true;
-  //	int verbose=0;
-
-  //	rig_set_debug(verbose<2 ? RIG_DEBUG_NONE: (rig_debug_level_e)verbose);
-  //rig_debug(RIG_DEBUG_VERBOSE, "rigctl, %s\n", hamlib_version);
-  // test if we can contact the tranceiver
-  double fr;
-  if(!getFrequency(fr))
+    addToLog("rigcontroller successfully opened",LOGRIGCTRL);
+    rigControlEnabled=true;
+    // int verbose=0;
+    // rig_set_debug(verbose<2 ? RIG_DEBUG_NONE: (rig_debug_level_e)verbose);
+    // rig_debug(RIG_DEBUG_VERBOSE, "rigctl, %s\n", hamlib_version);
+    // test if we can contact the tranceiver
+    double fr;
+    if(!getFrequency(fr))
     {
-      //        rigControlEnabled=false;
+        //        rigControlEnabled=false;
     }
-  return true;
+    return true;
 }
 
 bool rigControl::getFrequency(double &frequency)
 {
-  int retcode;
-  if(!rigControlEnabled) return false;
-  //  retcode = rig_set_vfo(my_rig, RIG_VFO_A);
-  //  if (retcode != RIG_OK ) {errorMessage(retcode,"setVFO"); return false; }
-  retcode = rig_get_freq(my_rig, RIG_VFO_CURR, &frequency);
-  if (retcode != RIG_OK ) {errorMessage(retcode,"getFrequency"); return false; }
-  return true;
+    int retcode;
+    if(catParams.enableXMLRPC)
+    {
+        frequency=xmlIntfPtr->getFrequency();
+    }
+    else
+    {
+        if(!rigControlEnabled) return false;
+        retcode = rig_get_freq(my_rig, RIG_VFO_CURR, &frequency);
+        if (retcode != RIG_OK )
+            frequency=lastFrequency;
+        //    {errorMessage(retcode,"getFrequency"); return false; }
+    }
+    return true;
 }
 
 bool rigControl::setFrequency(double frequency)
 {
-  int retcode;
-  if(!rigControlEnabled) return false;
-  retcode = rig_set_vfo(my_rig, RIG_VFO_CURR);
-  if (retcode != RIG_OK ) {errorMessage(retcode,"setVFO"); return false; }
-  retcode = rig_set_freq(my_rig, RIG_VFO_CURR, frequency);
-  if (retcode != RIG_OK ) {errorMessage(retcode,"setFrequency"); return false; }
-  return true;
+    int retcode;
+    if(catParams.enableXMLRPC)
+    {
+        xmlIntfPtr->setFrequency(frequency);
+    }
+    else
+    {
+        if(!rigControlEnabled) return false;
+        retcode = rig_set_vfo(my_rig, RIG_VFO_CURR);
+        if (retcode != RIG_OK ) {errorMessage(retcode,"setVFO"); return false; }
+        retcode = rig_set_freq(my_rig, RIG_VFO_CURR, frequency);
+        if (retcode != RIG_OK ) {errorMessage(retcode,"setFrequency"); return false; }
+    }
+    return true;
 }
 
 void rigControl::disable()
 {
-  if(rigControlEnabled)
+    if(rigControlEnabled)
     {
-      rig_close(my_rig); /* close port */
-      rig_cleanup(my_rig); /* if you care about memory */
-      rigControlEnabled=false;
+        rig_close(my_rig); /* close port */
+        rig_cleanup(my_rig);
+        rigControlEnabled=false;
     }
 }
 
-
-
-
 bool rigControl::getMode(QString &mode)
 {
-  rmode_t rmode;
-  pbwidth_t width;
-  int retcode;
-  if(!rigControlEnabled) return false;
-  retcode = rig_get_mode(my_rig, RIG_VFO_CURR, &rmode, &width);
-  if (retcode != RIG_OK ) {errorMessage(retcode,"getMode"); return false; }
-  mode=QString(rig_strrmode(rmode));
-  return true;
+    if(catParams.enableXMLRPC)
+    {
+        mode =xmlIntfPtr->getMode();
+    }
+    else
+    {
+        rmode_t rmode;
+        pbwidth_t width;
+        int retcode;
+        if(!rigControlEnabled) return false;
+        retcode = rig_get_mode(my_rig, RIG_VFO_CURR, &rmode, &width);
+        if (retcode != RIG_OK ) {errorMessage(retcode,"getMode"); return false; }
+        mode=QString(rig_strrmode(rmode));
+    }
+    return true;
 }
 
 bool rigControl::setMode(QString mode)
 {
-  rmode_t rmode=rig_parse_mode(mode.toLatin1().data());
-  int retcode;
-  if(!rigControlEnabled) return false;
-  retcode = rig_set_mode(my_rig, RIG_VFO_CURR, rmode, rig_passband_normal(my_rig,rmode));
-  if (retcode != RIG_OK ) {errorMessage(retcode,"setMode"); return false; }
-  return true;
+    QString orgMode;
+    int i;
+    int pos=-1;
+    if(catParams.enableXMLRPC)
+    {
+        orgMode=xmlIntfPtr->getMode();
+        for(i=0;i<xmlModes.count();i++)
+        {
+            pos=orgMode.indexOf(xmlModes.at(i),Qt::CaseInsensitive);
+            if(pos>=0)
+            {
+                orgMode.replace(xmlModes.at(i),mode);
+                break;
+            }
+        }
+        if(pos>=0) xmlIntfPtr->setMode(orgMode);
+    }
+    else
+    {
+        rmode_t rmode=rig_parse_mode(mode.toLatin1().data());
+        int retcode;
+        if(!rigControlEnabled) return false;
+        retcode = rig_set_mode(my_rig, RIG_VFO_CURR, rmode, rig_passband_normal(my_rig,rmode));
+        if (retcode != RIG_OK ) {errorMessage(retcode,"setMode"); return false; }
+    }
+    return true;
 }
 
 
 bool rigControl::setPTT(bool on)
 {
-  int retcode;
-  ptt_t ptt;
-  if(on) ptt=RIG_PTT_ON; else ptt=RIG_PTT_OFF;
-  if(!rigControlEnabled) return false;
-  retcode = rig_set_ptt (my_rig, RIG_VFO_CURR,ptt);
-  if (retcode != RIG_OK ) {errorMessage(retcode,"setPTT"); return false; }
-  return true;
+    int retcode;
+    ptt_t ptt;
+    if(on) ptt=RIG_PTT_ON; else ptt=RIG_PTT_OFF;
+    if(!rigControlEnabled) return false;
+    retcode = rig_set_ptt (my_rig, RIG_VFO_CURR,ptt);
+    if (retcode != RIG_OK ) {errorMessage(retcode,"setPTT"); return false; }
+    return true;
 }
 
 
 
 void  rigControl::errorMessage(int errorCode,QString command)
 {
-  QMessageBox::information(0,"Cat interface",QString("Error in connection: %1\n%2").arg(QString(rigerror(errorCode))).arg(command));
+    QMessageBox::information(0,"Cat interface",QString("Error in connection: %1\n%2").arg(QString(rigerror(errorCode))).arg(command));
 }
 
 void rigControl::getRadioList()
 {
-  if(!radiolistLoaded)
+    if(!radiolistLoaded)
     {
-      capsList.clear();
-      rig_load_all_backends();
-      rig_list_foreach(collect,0);
-      qSort(capsList.begin(),capsList.end(),model_Sort);
-      radiolistLoaded=true;
+        capsList.clear();
+        rig_load_all_backends();
+        rig_list_foreach(collect,0);
+        qSort(capsList.begin(),capsList.end(),model_Sort);
+        radiolistLoaded=true;
     }
 }
 
 bool rigControl::getRadioList(QComboBox *cb)
 {
-  int i;
-  if(capsList.count()==0) return false;
-  QStringList sl;
-  for (i=0;i<capsList.count();i++)
+    int i;
+    if(capsList.count()==0) return false;
+    QStringList sl;
+    for (i=0;i<capsList.count();i++)
     {
-      QString t;
-      t= QString::number(capsList.at(i)->rig_model);
-      t=t.rightJustified(5,' ')+" ";
-      t+= capsList.at(i)->mfg_name;
-      t+=",";
-      t+=capsList.at(i)->model_name;
-      sl << t;
+        QString t;
+        t= QString::number(capsList.at(i)->rig_model);
+        t=t.rightJustified(5,' ')+" ";
+        t+= capsList.at(i)->mfg_name;
+        t+=",";
+        t+=capsList.at(i)->model_name;
+        sl << t;
     }
-  cb->addItems(sl);
-  return true;
+    cb->addItems(sl);
+    return true;
 }
 
 int rigControl::getModelNumber(int idx)
 {
-  if(idx<0) return 0;
-  return capsList.at(idx)->rig_model;
+    if(idx<0) return 0;
+    return capsList.at(idx)->rig_model;
 }
 
 int rigControl::getRadioModelIndex()
 {
-  int i;
-  QString t=catParams.radioModel;
-  t=t.remove(0,5);
-  t=t.simplified();
-  QStringList sl=t.split(",");
-  if(sl.count()==1) sl.append("");
-  for(i=0;i<capsList.count();i++)
+    int i;
+    QString t=catParams.radioModel;
+    t=t.remove(0,5);
+    t=t.simplified();
+    QStringList sl=t.split(",");
+    if(sl.count()==1) sl.append("");
+    for(i=0;i<capsList.count();i++)
     {
-      if((capsList.at(i)->mfg_name==sl.at(0)) && (capsList.at(i)->model_name==sl.at(1)))
+        if((capsList.at(i)->mfg_name==sl.at(0)) && (capsList.at(i)->model_name==sl.at(1)))
         {
-          return i;
+            return i;
         }
     }
-  return -1;
+    return -1;
 }
 
 bool model_Sort(const rig_caps *caps1,const rig_caps *caps2)
 {
-  if(caps1->mfg_name==caps2->mfg_name)
+    if(caps1->mfg_name==caps2->mfg_name)
     {
-      if (QString::compare(caps1->model_name,caps2->model_name)<0) return true;
-      return false;
+        if (QString::compare(caps1->model_name,caps2->model_name)<0) return true;
+        return false;
     }
-  if (QString::compare(caps1->mfg_name,caps2->mfg_name)<0) return true;
-  return false;
+    if (QString::compare(caps1->mfg_name,caps2->mfg_name)<0) return true;
+    return false;
 }
 
 void rigControl::activatePTT(bool b)
 {
-  int modemlines;
-  if(catParams.enableSerialPTT)
+    int modemlines;
+    if(catParams.enableSerialPTT)
     {
-      if (catParams.pttSerialPort.isEmpty()) return;
-      if(serialP==0)
+        if (catParams.pttSerialPort.isEmpty()) return;
+        if(serialP==0)
         {
-          serialP=::open(catParams.pttSerialPort.toLatin1().data(),O_RDWR);
-          if (serialP<=0)
+            serialP=::open(catParams.pttSerialPort.toLatin1().data(),O_RDWR);
+            if (serialP<=0)
             {
-              QMessageBox::warning(txWidgetPtr,"Serial Port Error",
-                                   QString("Unable to open serial port %1\ncheck Options->Configuration\n"
-                                           "make sure that you have read/write permission\nIf you do not have a serial port,\n"
-                                           "then disable -Serial PTT- option in the configuration").arg(catParams.pttSerialPort) ,
-                                   QMessageBox::Ok,0 );
-              return;
+                QMessageBox::warning(txWidgetPtr,"Serial Port Error",
+                                     QString("Unable to open serial port %1\ncheck Options->Configuration\n"
+                                             "make sure that you have read/write permission\nIf you do not have a serial port,\n"
+                                             "then disable -Serial PTT- option in the configuration").arg(catParams.pttSerialPort) ,
+                                     QMessageBox::Ok,0 );
+                return;
             }
-          else
+            else
             {
-              ioctl(serialP,TIOCMGET,&modemlines);
-              modemlines &= ~TIOCM_DTR;
-              modemlines &= ~TIOCM_RTS;
-              if(catParams.activeDTR) modemlines &= ~TIOCM_DTR;
-              if(catParams.activeRTS)modemlines &= ~TIOCM_RTS;
-              if(catParams.nactiveDTR) modemlines |= ~TIOCM_DTR;
-              if(catParams.nactiveRTS)modemlines |= ~TIOCM_RTS;
-              ioctl(serialP,TIOCMSET,&modemlines);
+                ioctl(serialP,TIOCMGET,&modemlines);
+                if(catParams.activeDTR) modemlines &= ~TIOCM_DTR;
+                if(catParams.activeRTS)modemlines &= ~TIOCM_RTS;
+                if(catParams.nactiveDTR) modemlines |= ~TIOCM_DTR;
+                if(catParams.nactiveRTS)modemlines |= ~TIOCM_RTS;
+                ioctl(serialP,TIOCMSET,&modemlines);
             }
         }
-      if(serialP>0)
+        if(serialP>0)
         {
-          if(b)
+            if(b)
             {
-              ioctl(serialP,TIOCMGET,&modemlines);
-              if(catParams.activeDTR) modemlines |= TIOCM_DTR;
-              if(catParams.activeRTS)modemlines |= TIOCM_RTS;
-              if(catParams.nactiveDTR) modemlines &= ~TIOCM_DTR;
-              if(catParams.nactiveRTS)modemlines &= ~TIOCM_RTS;
-              ioctl(serialP,TIOCMSET,&modemlines);
-              //ioctl(serial,TIOCMBIS,&t);
+                ioctl(serialP,TIOCMGET,&modemlines);
+                if(catParams.activeDTR) modemlines |= TIOCM_DTR;
+                if(catParams.activeRTS)modemlines |= TIOCM_RTS;
+                if(catParams.nactiveDTR) modemlines &= ~TIOCM_DTR;
+                if(catParams.nactiveRTS)modemlines &= ~TIOCM_RTS;
+                ioctl(serialP,TIOCMSET,&modemlines);
+                //ioctl(serial,TIOCMBIS,&t);
             }
-          else
+            else
             {
-              ioctl(serialP,TIOCMGET,&modemlines);
-              if(catParams.activeDTR) modemlines &= ~TIOCM_DTR;
-              if(catParams.activeRTS) modemlines &= ~TIOCM_RTS;
-              if(catParams.nactiveDTR) modemlines |= ~TIOCM_DTR;
-              if(catParams.nactiveRTS)modemlines |= ~TIOCM_RTS;
-              ioctl(serialP,TIOCMSET,&modemlines);
-              //	ioctl(serial,TIOCMBIC,&t);
+                ioctl(serialP,TIOCMGET,&modemlines);
+                if(catParams.activeDTR) modemlines &= ~TIOCM_DTR;
+                if(catParams.activeRTS) modemlines &= ~TIOCM_RTS;
+                if(catParams.nactiveDTR) modemlines |= ~TIOCM_DTR;
+                if(catParams.nactiveRTS)modemlines |= ~TIOCM_RTS;
+                ioctl(serialP,TIOCMSET,&modemlines);
+                //	ioctl(serial,TIOCMBIC,&t);
 
             }
         }
     }
-  else if(catParams.enableXMLRPC)
+    else if(catParams.enableXMLRPC)
     {
-      xmlIntfPtr->activatePTT(b);
+        xmlIntfPtr->activatePTT(b);
     }
-  else rigController->setPTT(b); // does nothing if rigController is disabled
-  mainWindowPtr->setPTT(b);
-  if(b)
+    else rigControllerPtr->setPTT(b); // does nothing if rigController is disabled
+    mainWindowPtr->setPTT(b);
+    if(b)
     {
-      addToLog("dispatcher: PTT activated",LOGDISPAT);
+        addToLog("dispatcher: PTT activated",LOGDISPATCH);
     }
-  else
+    else
     {
-      addToLog("dispatcher: PTT deactivated",LOGDISPAT);
+        addToLog("dispatcher: PTT deactivated",LOGDISPATCH);
     }
 }
 
 
+int  rigControl::rawCommand(QByteArray ba)
+{
+    int i;
+    bool result;
+    char rxBuffer[100];
+
+    QString command="w ";
+    QByteArray cmdBa;
+    if(!rigControlEnabled) return 0;
+    struct rig_state *rs;
+    rs = &my_rig->state;
+    // check if backend via rigctld
+    if(catParams.radioModelNumber==2)
+    {
+        // we need to send this as a command string
+        if(additionalCommandHex)
+        {
+            for(i=0;i<ba.count();i++)
+            {
+
+                command+="\\0x";
+                command+=QString::number((unsigned char)ba.at(i),16);
+            }
+        }
+        else
+        {
+          command+=ba;
+        }
+
+        command+="\n";
+        cmdBa=command.toLatin1();
+        result=write_block(&rs->rigport,cmdBa.constData(), cmdBa.count());
+
+    }
+    else
+    {
+         result=write_block(&rs->rigport,ba.constData(), ba.count());
+    }
+    read_block(&rs->rigport,rxBuffer,99);
+    return result;
 
+}
diff --git a/qsstv/rig/rigcontrol.h b/qsstv/rig/rigcontrol.h
index 1cf1f78..3ae16b8 100644
--- a/qsstv/rig/rigcontrol.h
+++ b/qsstv/rig/rigcontrol.h
@@ -1,27 +1,56 @@
 #ifndef RIGCONTROL_H
 #define RIGCONTROL_H
+
+#include <hamlib/rig.h>
+#include "xmlinterface.h"
+
 #include <QObject>
 #include <QComboBox>
-#include <hamlib/rig.h>
-#include "rigparams.h"
-#include "xmlrpc/xmlinterface.h"
+
+extern "C" int write_block(hamlib_port_t *p, const char *txbuffer, size_t count);
+extern "C" int read_block(hamlib_port_t *p, char *rxbuffer, size_t count);
+
 
 bool model_Sort(const rig_caps *caps1,const rig_caps *caps2);
 
+struct scatParams
+{
+  QString configLabel;
+  QString serialPort; /**<  serial port device*/
+  QString radioModel;
+  int radioModelNumber;
+  QString civAddress;
+  int baudrate; /**<  serial port baudrate*/
+  QString parity;
+  int stopbits;
+  int databits;
+  QString handshake;
+  bool enableCAT;
+  bool enableSerialPTT;
+  QString pttSerialPort;
+  bool activeRTS;
+  bool activeDTR;
+  bool nactiveRTS;
+  bool nactiveDTR;
+  ptt_type_t pttType;
+  bool enableXMLRPC;
+  int XMLRPCPort;
+  double txOnDelay;
+
+};
 
 class rigControl: public QObject
 {
-	Q_OBJECT
+  Q_OBJECT
 public:
   rigControl(int radioIndex);
-	~rigControl();
-	bool init();
-	bool enabled() {return rigControlEnabled;}
-	bool getFrequency(double &frequency);
-	bool setFrequency(double frequency);
-	bool getMode(QString &mode);
+  ~rigControl();
+  bool init();
+  bool enabled() {return rigControlEnabled;}
+  bool getFrequency(double &frequency);
+  bool setFrequency(double frequency);
+  bool getMode(QString &mode);
   bool setMode(QString mode);
-  bool setPTT(bool On);
   int getModelNumber(int idx);
   int getRadioModelIndex();
   bool getRadioList(QComboBox *cb);
@@ -29,29 +58,31 @@ public:
   scatParams* params() {return &catParams;}
   void activatePTT(bool b);
   double getTxDelay() {return catParams.txOnDelay;}
+  int rawCommand(QByteArray ba);
   QString initError;
 
-
 private:
- 	hamlib_port_t myport;
+  hamlib_port_t myport;
   RIG *my_rig;            // handle to rig (nstance)
-	freq_t freq;            // frequency  
-	rmode_t rmode;          // radio mode of operation 
-	pbwidth_t width;
-	vfo_t vfo;              // vfo selection 
-	int strength;           // S-Meter level 
-	int retcode;            // generic return code from functions 
-	rig_model_t myrig_model;
-	bool rigControlEnabled;
+  freq_t freq;            // frequency
+  rmode_t rmode;          // radio mode of operation
+  pbwidth_t width;
+  vfo_t vfo;              // vfo selection
+  int strength;           // S-Meter level
+  int retcode;            // generic return code from functions
+  rig_model_t myrig_model;
+  bool rigControlEnabled;
   void errorMessage(int errorCode,QString command);
   void getRadioList();
   scatParams catParams;
   int serialP;
+  bool setPTT(bool On);
+  double lastFrequency;
+  QStringList xmlModes;
+
 
 
 };
 
-extern rigControl *rigControllerR1;
-extern rigControl *rigControllerR2;
-extern rigControl *rigController;
+
 #endif
diff --git a/qsstv/rig/rigcontrolform.cpp b/qsstv/rig/rigcontrolform.cpp
index ebe9989..150ef21 100644
--- a/qsstv/rig/rigcontrolform.cpp
+++ b/qsstv/rig/rigcontrolform.cpp
@@ -1,6 +1,6 @@
 #include "rigcontrolform.h"
+#include "appglobal.h"
 #include "ui_rigcontrolform.h"
-#include "qsstvglobal.h"
 #include "configparams.h"
 #include "utils/supportfunctions.h"
 #include "rigparams.h"
diff --git a/qsstv/rig/rigparams.h b/qsstv/rig/rigparams.h
deleted file mode 100644
index 14d0841..0000000
--- a/qsstv/rig/rigparams.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef RIGPARAMS_H
-#define RIGPARAMS_H
-#include <QString>
-#include <hamlib/rig.h>
-
-
-struct scatParams
-{
-  QString configLabel;
-  QString serialPort; /**<  serial port device*/
-  QString radioModel;
-  int radioModelNumber;
-  QString civAddress;
-  int baudrate; /**<  serial port baudrate*/
-  QString parity;
-  int stopbits;
-  int databits;
-  QString handshake;
-  bool enableCAT;
-  bool enableSerialPTT;
-  QString pttSerialPort;
-  bool activeRTS;
-  bool activeDTR;
-  bool nactiveRTS;
-  bool nactiveDTR;
-  ptt_type_t pttType;
-  bool enableXMLRPC;
-  int XMLRPCPort;
-  double txOnDelay;
-};
-
-#endif // RIGPARAMS_H
diff --git a/qsstv/rxfunctions.cpp b/qsstv/rxfunctions.cpp
deleted file mode 100644
index 2fe8c64..0000000
--- a/qsstv/rxfunctions.cpp
+++ /dev/null
@@ -1,466 +0,0 @@
-#include "rxfunctions.h"
-#include "qsstvglobal.h"
-#include "configparams.h"
-#include "rxwidget.h"
-#include "sound/soundio.h"
-#include "dsp/filterparam.h"
-#include "dsp/filter.h"
-#include "dsp/downsamplefilter.h"
-#ifndef QT_NO_DEBUG
-#include "scope/scopeview.h"
-#include "scope/scopeoffset.h"
-#endif
-#include "configparams.h"
-#include "utils/supportfunctions.h"
-#include "dispatcher.h"
-#include "sstv/modes/modes.h"
-
-#include "drmrx/drm.h"
-#include "drmrx/drmproto.h"
-#include "drmrx/demodulator.h"
-
-#define DRMNEW
-
-const QString stateStr[rxFunctions::WAIT+1]=
-{
-  "Hunting",
-  "SlantAdjust",
-  "Processing",
-  "Restart",
-  "Sync Lost",
-  "End",
-  "Wait"
-};
-
-rxFunctions::rxFunctions(QObject *parent) :
-  QThread(parent)
-{
-  rxState=RXIDLE;
-  downSampleFilter=NULL;
-  rxFilter=NULL;
-  syncFilter=NULL;
-  dataInputPtr=new drmDataInput(RXSTRIPE);
-  currentMode=0;
-
-#ifndef QT_NO_DEBUG
-  scopeViewerData->setCurveName("Volume",SCDATA1);
-  scopeViewerData->setCurveName("FM Demod",SCDATA2);
-  scopeViewerData->setCurveName("raw Input",SCDATA3);
-  scopeViewerData->setCurveName("none",SCDATA4);
-  scopeViewerData->setAxisTitles("Samples","int","demod");
-#endif
-  demodulatorPtr=new demodulator;
-
-}
-
-rxFunctions::~rxFunctions()
-{
-  if(downSampleFilter==NULL) delete downSampleFilter;
-  if(rxFilter==NULL) delete rxFilter;
-  if(syncFilter==NULL) delete syncFilter;
-}
-
-
-void rxFunctions::run()
-{
-  addToLog("starting rxfunctions run",LOGRXFUNC);
-  int count;
-  bool done=false;
-  init();
-  addToLog("end init rxfunctions run",LOGRXFUNC);
-  abort=false;
-  while(!abort)
-    {
-      switch(rxState)
-        {
-        case RXIDLE:
-          msleep(200);
-        break;
-        case RXRUNNING:
-          if((count=soundIOPtr->rxBuffer.count())<SAMPLINGSTRIPE)
-            {
-              msleep((250*RXSTRIPE)/rxClock);
-              if(!soundIOPtr->isCapturing())
-                {
-                  rxState=RXINIT;
-                }
-            }
-          else
-            {
-              //              addToLog(QString("LoadTempBuf count=%1").arg(count),LOGRXFUNC);
-              soundIOPtr->rxBuffer.copyNoCheck(tempBuf,SAMPLINGSTRIPE);
-              //              addToLog("LoadTempBuf",LOGRXFUNC);
-              downSampleFilter->downSample4(tempBuf);
-              displayFFTEvent* ce = new displayFFTEvent(downSampleFilter->filteredDataPtr());
-              ce->waitFor(&done);
-              QApplication::postEvent(dispatcherPtr, ce);
-              while(!done) {usleep(10);}
-
-              switch (transmissionModeIndex)
-                {
-                case DRM:
-                  runDRM();
-                break;
-                case SSTV:
-                  rxHoldingBuffer.putNoCheck(downSampleFilter->filteredDataPtr(),RXSTRIPE);
-                  bufferCounter++;
-                  getData();
-                  processSSTV();
-                  sampleCounter+=RXSTRIPE;
-                  rxHoldingBuffer.skip(RXSTRIPE);
-                  demodBuffer.skip(RXSTRIPE);
-                break;
-                  //                case FAX:
-                  //                break;
-                case NOMODE:
-                break;
-                }
-            }
-        break;
-        case RXINIT:
-          if(transmissionModeIndex==SSTV) syncProc.init(); //reset meters
-          rxState=RXIDLE;
-        break;
-
-        }
-    }
-  abort=false;
-}
-
-void rxFunctions::init()
-{
-  //  rxMode=rxModeIndex;
-  setFilters(rxWidgetPtr->getFilterIndex()); // setup SSTV Filters
-  avgSNR=0;
-  if(transmissionModeIndex==DRM)
-    {
-      n = DRMBUFSIZE;
-      /* initialisations */
-      demodulatorPtr->init();
-      dataInputPtr->init(RXSTRIPE);
-      initGetmode( n / 4);
-      rRation = 1.000;
-      samplerate_offset_estimation = 0.0;
-      runstate = RUN_STATE_POWER_ON;		/* POWER_ON */
-      channel_decoding();
-      runstate = RUN_STATE_INIT;		/* INIT */
-      channel_decoding();
-      runstate = RUN_STATE_FIRST;			/* FIRSTRUN */
-      runstate = RUN_STATE_NORMAL;			/* NORMAL RUN */
-    }
-  else
-    {
-      SSTVState=HUNTING;
-      syncProc.init();
-    }
-  if(downSampleFilter==NULL)  downSampleFilter=new downsampleFilter(SAMPLINGSTRIPE,downSampleFilterParam,DSAMPLEFILTERLEN,false);
-  else downSampleFilter->init();
-  sampleCounter=0;
-  bufferCounter=0;
-  rxHoldingBuffer.reset();
-}
-
-void rxFunctions::getData()
-{
-  //  addToLog(QString("GetData readIndex: %1,sampleCounter: %2").arg(rxHoldingBuffer.getReadIndex()).arg(sampleCounter),LOGRXFUNC);
-  rxFilter->processFM(rxHoldingBuffer.readPointer());
-  demodBuffer.putNoCheck(rxFilter->filteredDataPtr(),RXSTRIPE);
-  syncFilter->processFM(rxHoldingBuffer.readPointer());
-  syncProc.process();
-  displaySyncEvent* ce;
-  ce = new displaySyncEvent(syncProc.syncQuality,(rxFilter->volumePtr()[0]-500)/500);
-  QApplication::postEvent(dispatcherPtr, ce);
-
-
-
-
-  //  addToLog("EndFilter",LOGPERFORM);
-
-#ifndef QT_NO_DEBUG
-  scopeViewerData->addData(SCDATA3,rxHoldingBuffer.readPointer(),sampleCounter,RXSTRIPE);
-  scopeViewerData->addData(SCDATA2,demodBuffer.readPointer(),sampleCounter,RXSTRIPE);
-  scopeViewerData->addData(SCDATA1,rxFilter->volumePtr(),sampleCounter,RXSTRIPE);
-#endif
-
-}
-
-#ifndef QT_NO_DEBUG
-
-unsigned int rxFunctions::setOffset(unsigned int offset,bool ask)
-{
-  if(ask)
-    {
-      scopeOffset so;
-      so.setOffset(offset);
-      if(so.exec()==QDialog::Accepted)
-        {
-          xOffset=so.getOffset()*1000;
-        }
-    }
-  else
-    {
-      xOffset=offset*1000;
-    }
-  syncProc.setOffset(xOffset);
-  scopeViewerData->setOffset(xOffset);
-  syncProc.setOffset(xOffset);
-  return xOffset/1000;
-}
-#endif
-
-void rxFunctions::processSSTV()
-{
-  rxSSTVStatusEvent *stce;
-  endImageRXEvent *endce;
-  bool done=false;
-  int block;
-  unsigned long sampleCounterLatch;
-  switch(SSTVState)
-    {
-    case HUNTING:
-      if(syncProc.isInSync()==0)
-        {
-          stce= new rxSSTVStatusEvent(QString("No sync"));
-          QApplication::postEvent( dispatcherPtr, stce );  // Qt will delete it when done
-          break; // no sync
-        }
-      if(!create(syncProc.getMode(),syncProc.getNewClock())) break;
-      stce= new rxSSTVStatusEvent(QString("Receiving ")+getSSTVModeNameLong(syncProc.getMode()));
-      lastUsedMode=getSSTVModeNameShort(syncProc.getMode());
-      QApplication::postEvent( dispatcherPtr, stce );  // Qt will delete it when done
-    case SLANTADJUST:
-      syncPosition=syncProc.getSyncPosition();
-      if(syncProc.isInSync()==1)
-        {
-          syncPosition=currentMode->adjustSyncPosition(syncPosition); // only execute if no retrace
-          addToLog(QString("rxFunctions: adjusted syncPosition= %1").arg(syncPosition),LOGRXFUNC);
-        }
-      sampleCounterLatch=sampleCounter; //remember where we've got
-      addToLog(QString("rxFunctions: sampleCounterLatch= %1").arg(sampleCounterLatch),LOGRXFUNC);
-      block=(syncPosition)/RXSTRIPE;
-      demodBuffer.rewind(sampleCounter-block*RXSTRIPE);
-      addToLog(QString("sc_rewind: block=%1,rewind= %2").arg(block).arg(sampleCounter-block*RXSTRIPE+RXSTRIPE),LOGRXFUNC);
-      sampleCounter=block*RXSTRIPE;
-      currentMode->setRxSampleCounter(sampleCounter);
-      currentMode->redrawFast(true);
-      currentMode->process(demodBuffer.readPointer(),syncPosition-sampleCounter,true);
-      addToLog(QString("rxFunctions: currentMode pos:=%1").arg(syncPosition-sampleCounter),LOGRXFUNC);
-      //      addToLog(QString("after Current mode set: %1,sampleCounter: %2").arg(rxHoldingBuffer.getReadIndex()).arg(sampleCounter),LOGRXFUNC);
-      while(sampleCounter<sampleCounterLatch)
-        {
-          demodBuffer.skip(RXSTRIPE);
-          sampleCounter+=RXSTRIPE;
-          //          addToLog(QString("loop readIndex: %1,sampleCounter: %2").arg(rxHoldingBuffer.getReadIndex()).arg(sampleCounter),LOGRXFUNC);
-          currentMode->process(demodBuffer.readPointer());
-        }
-      addToLog(QString("end loop readIndex: %1,sampleCounter: %2").arg(rxHoldingBuffer.getReadIndex()).arg(sampleCounter),LOGRXFUNC);
-      currentMode->redrawFast(false);
-      setState(PROCESSING);
-
-    break;
-    case PROCESSING:
-
-      if(currentMode->process(demodBuffer.readPointer())==modeBase::MBENDOFIMAGE)
-        {
-          setState(END);
-        }
-      if(syncProc.hasRetrace())
-        {
-          setState(END);
-        }
-      if(syncProc.isInSync()==0)
-        {
-          setState(END);
-        }
-      else if(syncProc.hasNewClock())
-        {
-          currentMode->init(syncProc.getNewClock());
-          setState(SLANTADJUST);
-        }
-
-    break;
-    case RESTART:
-      block=(int) ceil((rxClock*0.3)/RXSTRIPE)+1; // rewind to position before the last detected retrace, + one because we will skip 1 on return of getData()
-      addToLog(QString("rxFunction: retraceVertical: count=%1").arg(block*RXSTRIPE),LOGRXFUNC);
-      rxHoldingBuffer.rewind(block*RXSTRIPE);
-      init();
-      sampleCounter=-RXSTRIPE; // will be incremented (will be 0) when returning from this function
-    break;
-    case SYNCLOST:
-        addToLog(QString("rxFunction: synclost"),LOGRXFUNC);
-    case END:
-      addToLog("rxFunc state END",LOGRXFUNC);
-      endce = new endImageRXEvent();
-      endce->waitFor(&done);
-      QApplication::postEvent(dispatcherPtr, endce);
-      while(!done) { msleep(10);}
-      setState(RESTART);
-    break;
-    case WAIT:
-
-    break;
-    }
-}
-
-void rxFunctions::setFilters(int fIndex)
-{
-  if(rxFilter==NULL) rxFilter= new filter(RXSTRIPE,filterStruct[fIndex].filterPtr,RXNUMTAPS,filterStruct[fIndex].centerFrequency,rxClock/SUBSAMPLINGRATIO,true,0.001);
-  else rxFilter->setFilterParams(filterStruct[fIndex].filterPtr,RXNUMTAPS,filterStruct[fIndex].centerFrequency,rxClock/SUBSAMPLINGRATIO,true,0.001);
-  if(syncFilter==NULL) syncFilter= new filter(RXSTRIPE,wide1200BP,RXNUMTAPS,1200,rxClock/SUBSAMPLINGRATIO,true,1);
-  syncProc.setFilters(rxFilter,syncFilter);
-}
-
-void rxFunctions::stopAndWait()
-{
-
-  if(!isRunning()) return;
-  rxState=RXINIT;
-  while(rxState!=RXIDLE)
-    {
-      if(!isRunning()) return; // to avoid race conditions
-      qApp->processEvents();
-    }
-}
-
-bool  rxFunctions::create(esstvMode m,DSPFLOAT clock)
-{
-  bool done=false;
-  if(currentMode) delete currentMode;
-  currentMode=0;
-  switch (m)
-    {
-    case M1:
-    case M2:
-      currentMode=new modeGBR(m,RXSTRIPE,false);
-    break;
-    case S1:
-    case S2:
-    case SDX:
-      currentMode=new modeGBR2(m,RXSTRIPE,false);
-    break;
-    case R36:
-      currentMode=new modeRobot1(m,RXSTRIPE,false);
-    break;
-    case R24:
-    case R72:
-      currentMode=new modeRobot2(m,RXSTRIPE,false);
-    break;
-    case SC2_60:
-    case SC2_120:
-    case SC2_180:
-    case P3:
-    case P5:
-    case P7:
-      currentMode=new modeRGB(m,RXSTRIPE,false);
-    break;
-    case FAX480:
-    case BW8:
-    case BW12:
-      currentMode=new modeBW(m,RXSTRIPE,false);
-    break;
-    case AVT24:
-    case AVT90:
-    case AVT94:
-      currentMode=new modeAVT(m,RXSTRIPE,false);
-    break;
-    case PD50:
-    case PD90:
-    case PD120:
-    case PD160:
-    case PD180:
-    case PD240:
-    case PD290:
-    case MP73:
-    case MP115:
-    case MP140:
-    case MP175:
-      currentMode=new modePD(m,RXSTRIPE,false);
-    break;
-    default:
-      m=NOTVALID;
-    break;
-    }
-  if (m!=NOTVALID)
-    {
-      initializeSSTVParametersIndex(m,false);
-      QString s=getSSTVModeNameLong(m);
-      addToLog("rxFunction:create RX mode",LOGRXFUNC);
-      currentMode->init(clock);
-      startImageRXEvent* ce = new startImageRXEvent(QSize(currentMode->imagePixels(),currentMode->imageLines()));
-      ce->waitFor(&done);
-      QApplication::postEvent(dispatcherPtr, ce);
-      while(!done) { msleep(10);}
-      return true;
-    }
-  return false;
-}
-
-void rxFunctions::startRX()
-{
-  init();
-  rxState=RXRUNNING;
-}
-
-void rxFunctions::setState(eSSTVState st)
-{
-  addToLog(QString("rxfunc: set SSTVState: from %1 to %2").arg(stateStr[SSTVState]).arg (stateStr[st]),LOGRXFUNC);
-  SSTVState=st;
-
-}
-
-void rxFunctions::retraceVertical(void)
-{
-  setState(RESTART);
-}
-
-bool rxFunctions::saveOK()
-{
-  if(currentMode==0)
-    {
-      addToLog("saveOK called with currentMode==0",LOGRXFUNC);
-      return false;
-    }
-
-  if(currentMode->receivedLines()>(currentMode->imageLines()/3)) return true;
-  return false;
-}
-
-#define RATIONAVG 0.01
-void rxFunctions::runDRM()
-{
-  bool done=false;
-  DSPFLOAT temp;
-
-  displayDRMStatEvent *ce1;
-  displayDRMInfoEvent *ce2 ;
-  temp=WMERFAC;
-  if(temp<0) temp=0;
-  if(demodulatorPtr->isFrameSync())
-    {
-      avgSNR=(1-0.05)*avgSNR+0.05*temp;
-      ce1 = new displayDRMStatEvent(avgSNR,downSampleFilter->avgVolume);
-    }
-  else
-    {
-      ce1 = new displayDRMStatEvent(0,downSampleFilter->avgVolume);
-    }
-  QApplication::postEvent(dispatcherPtr, ce1);
-
-  while(input_samples_buffer_request ==0)
-    {
-      demodulatorPtr->demodulate(resamp_signal,0);
-    }
-  im=0;
-  im=dataInputPtr->getData(downSampleFilter->filteredDataPtr(),resamp_signal,rRation);
-  //  arrayDump("resam",resamp_signal,RXSTRIPE,true);
-  if(im==0)
-    {
-      msleep(10);
-      return;
-    }
-  demodulatorPtr->demodulate(resamp_signal,im);
-  ce2 = new displayDRMInfoEvent;
-  ce2->waitFor(&done);
-  QApplication::postEvent(dispatcherPtr, ce2);
-  while(!done) { usleep(10);}
-}
diff --git a/qsstv/rxfunctions.h b/qsstv/rxfunctions.h
deleted file mode 100644
index 599718a..0000000
--- a/qsstv/rxfunctions.h
+++ /dev/null
@@ -1,74 +0,0 @@
-#ifndef RXFUNCTIONS_H
-#define RXFUNCTIONS_H
-
-#include <QThread>
-#include "qsstvdefs.h"
-#include "sstv/syncprocessor.h"
-#include "utils/buffermanag.h"
-#include "drmrx/drmdefs.h"
-#include "drmrx/drmdatainput.h"
-#include "drmrx/sourcedecoder.h"
-
-
-class filter;
-class downsampleFilter;
-class modeBase;
-class demodulator;
-
-
-class rxFunctions : public QThread
-{
-  Q_OBJECT
-public:
-  enum erxState {RXIDLE,RXRUNNING,RXINIT};
-  enum eSSTVState {HUNTING,SLANTADJUST,PROCESSING,RESTART,SYNCLOST,END,WAIT};
-  explicit rxFunctions(QObject *parent = 0);
-  ~rxFunctions();
-  void init();
-  void run();
-  void stopAndWait();
-  void retraceVertical(void);
-  void startRX();
-  QString getModeString (void){ return lastUsedMode;}
-  bool saveOK();
-#ifndef QT_NO_DEBUG
-  unsigned int setOffset(unsigned int offset, bool ask);
-#endif
-signals:
-  
-public slots:
-
-private:
-  downsampleFilter *downSampleFilter;
-  filter *rxFilter;
-  filter *syncFilter;
-  unsigned int sampleCounter;
-  void setFilters(int index);
-  void setState(eSSTVState st);
-  void getData();
-  void processSSTV();
-  bool create(esstvMode m,DSPFLOAT clock);
-
-  void runDRM();
-
-  unsigned int bufferCounter;
-  syncProcessor syncProc;
-  erxState rxState;
-  eSSTVState SSTVState;
-  modeBase *currentMode;
-  bool abort;
-  QString lastUsedMode;
-  unsigned long syncPosition;
-  buffer<DSPFLOAT,22> rxHoldingBuffer;  // 2^22= 4194304, divided by samplingrate 12000 gives 349 seconds buffering
-  buffer<int,22> demodBuffer;  // 2^22= 4194304, divided by samplingrate 12000 gives 349 seconds buffering
-  unsigned int xOffset;
-  // DRM
-  float rRation;
-  float resamp_signal[2 * DRMBUFSIZE];
-  int n,im;
-  drmDataInput *dataInputPtr;
-  short int tempBuf[SAMPLINGSTRIPE];
-
-};
-
-#endif // RXFUNCTIONS_H
diff --git a/qsstv/rxwidget.cpp b/qsstv/rxwidget.cpp
deleted file mode 100644
index 16d9a06..0000000
--- a/qsstv/rxwidget.cpp
+++ /dev/null
@@ -1,260 +0,0 @@
-#include "rxwidget.h"
-#include "txwidget.h"
-#include "qsstvglobal.h"
-#include "utils/supportfunctions.h"
-#include "ui_rxwidget.h"
-#include "sstv/sstvparam.h"
-#include "dsp/filterparam.h"
-#include "sound/soundio.h"
-#include "configparams.h"
-#include "dispatcher.h"
-#include "mainwindow.h"
-
-
-rxWidget *rxWidgetPtr;
-
-spectrumWidget *rxWidget::fftDisplayPtr()
-{
-  return ui->spectrumFrame;
-}
-
-vuMeter *rxWidget::vMeterPtr()
-{
-   return ui->vuWidget;
-}
-
-vuMeter *rxWidget::sMeterPtr()
-{
-   return ui->syncWidget;
-}
-
-rxWidget::rxWidget(QWidget *parent) :
-  QWidget(parent),
-  ui(new Ui::rxWidget)
-{
-  int i;
-  ui->setupUi(this);
-  rxFunctionsPtr=new rxFunctions();
-  ui->syncWidget->setHorizontal(false);
-  ui->syncWidget->setColors(Qt::red,QColor(255,165,0),Qt::green);
-  ui->syncWidget->setMaximum(10.);
-  ui->syncWidget->setValue(0.);
-  ui->syncWidget->setLabelText("S");
-
-  ui->vuWidget->setHorizontal(true);
-  ui->vuWidget->setLabelText("V");
-  ui->vuWidget->setColors(QColor(255,50,0),Qt::green,Qt::red);
-  ui->vuWidget->setMaximum(10.);
-  ui->vuWidget->setValue(0.);
-  imageViewerPtr=ui->imageFrame;
-  imageViewerPtr->createImage(QSize(320,256),QColor(0,0,128));
-  imageViewerPtr->setType(imageViewer::RXIMG);
-
-  ui->sstvModeComboBox->addItem("Auto");
-  for(i=0;i<NUMSSTVMODES-1;i++)
-    {
-      ui->sstvModeComboBox->addItem(getSSTVModeNameLong((esstvMode)i));
-    }
-  for(i=0;i<NUMRXFILTERS;i++)
-    {
-      ui->filterComboBox->addItem(filterStruct[i].filterName);
-    }
-
-  for(i=0;i<NUMSENSITIVITIES;i++)
-    {
-      ui->squelchComboBox->addItem(squelchStr[i]);
-    }
-
-  connect(ui->startToolButton, SIGNAL(clicked()),SLOT(slotStart()));
-  connect(ui->stopToolButton, SIGNAL(clicked()),SLOT(slotStop()));
-  connect(ui->autoSlantAdjustCheckBox,SIGNAL(clicked()),SLOT(slotGetParams()));
-  connect(ui->autoSaveCheckBox,SIGNAL(clicked()),SLOT(slotGetParams()));
-  connect(ui->saveToolButton, SIGNAL(clicked()),SLOT(slotSaveImage()));
-  connect(ui->squelchComboBox,SIGNAL(currentIndexChanged(int)),SLOT(slotGetParams()));
-  connect(ui->settingsTableWidget,SIGNAL(currentChanged(int)),this, SLOT(slotTransmissionMode(int)));
-}
-
-rxWidget::~rxWidget()
-{
-  rxFunctionsPtr->stopAndWait();
-  delete ui;
-}
-
-void rxWidget::init()
-{
-  splashStr+=QString( "Setting up RX" ).rightJustified(25,' ')+"\n";
-  splashPtr->showMessage ( splashStr ,Qt::AlignLeft,Qt::white);
-  qApp->processEvents();
-  readSettings();
-  rxFunctionsPtr->start();
-}
-
-
-void rxWidget::slotStart()
-{
-  getParams();
-  dispatcherPtr->startRX(true);
-}
-
-void rxWidget::slotStop()
-{
-  dispatcherPtr->startRX(false);
-}
-
-void rxWidget::start(bool st)
-{
-  if(st)
-    {
-      rxFunctionsPtr->stopAndWait();
-      soundIOPtr->startCapture();
-      rxFunctionsPtr->startRX();
-      addToLog("starting rxfunction run",LOGRXMAIN);
-    }
-  else
-    {
-      soundIOPtr->idle();
-      writeSettings();
-      ui->spectrumFrame->writeSettings();
-      rxFunctionsPtr->stopAndWait();
-    }
-}
-
-
-void rxWidget::readSettings()
-{
-  QSettings qSettings;
-  qSettings.beginGroup("RX");
-  useVIS=qSettings.value("useVIS",false).toBool();
-  autoSlantAdjust=qSettings.value("autoSlantAdjust",false).toBool();
-  autoSave=qSettings.value("autoSave",true).toBool();
-  squelch=qSettings.value("squelch",1).toInt();
-  filterIndex=(qSettings.value("filterIndex",0)).toInt();
-  setParams();
-  qSettings.endGroup();
-}
-
-void rxWidget::writeSettings()
-{
-  QSettings qSettings;
-  qSettings.beginGroup("RX");
-  getParams();
-  qSettings.setValue( "useVIS",useVIS);
-  qSettings.setValue( "autoSlantAdjust",autoSlantAdjust);
-  qSettings.setValue( "autoSave",autoSave);
-  qSettings.setValue( "squelch",squelch);
-  qSettings.setValue( "filterIndex", filterIndex);
-  qSettings.endGroup();
-}
-
-void rxWidget::getParams()
-{
-  getValue(useVIS,ui->useVISCheckBox);
-  getValue(autoSlantAdjust,ui->autoSlantAdjustCheckBox);
-  getValue(autoSave,ui->autoSaveCheckBox);
-  getIndex(squelch,ui->squelchComboBox);
-  getIndex(filterIndex,ui->filterComboBox);
-  if(filterIndex<0) filterIndex=0;
-}
-
-void rxWidget::setParams()
-{
-  setValue(useVIS,ui->useVISCheckBox);
-  setValue(autoSlantAdjust,ui->autoSlantAdjustCheckBox);
-  setValue(autoSave,ui->autoSaveCheckBox);
-  setIndex(squelch,ui->squelchComboBox);
-  setIndex(filterIndex,ui->filterComboBox);
-}
-
-void rxWidget::setSSTVStatusText(QString txt)
-{
-  ui->sstvStatusLineEdit->setText(txt);
-}
-
-void rxWidget::setDRMStatusText(QString txt)
-{
-  ui->drmStatusLineEdit->setText(txt);
-}
-
-
-void  rxWidget::setFilterIndex(int index)
-{
-
-  ui->filterComboBox->setCurrentIndex(index);
-
-}
-
-int rxWidget::getFilterIndex()
-{
-  return ui->filterComboBox->currentIndex();
-}
-
-void  rxWidget::slotGetParams()
-{
-  getParams();
-}
-
-void rxWidget::setSettingsTab()
-{
-
-  int i;
-  if((transmissionModeIndex>=0)&&(transmissionModeIndex<NOMODE))
-    {
-      for(i=0;i<NOMODE;i++)
-        {
-          if(i!=transmissionModeIndex) ui->settingsTableWidget->widget(i)->setEnabled(false);
-        }
-      ui->settingsTableWidget->widget(transmissionModeIndex)->setEnabled(true);
-      ui->settingsTableWidget->setCurrentIndex(transmissionModeIndex);
-    }
-  if(transmissionModeIndex==DRM)
-    {
-      ui->syncWidget->setColors(QColor(0,90,0),QColor(0,190,0),Qt::green);
-      ui->syncWidget->setMaximum(25.);
-      ui->syncWidget->setMinimum(5.);
-      ui->syncWidget->setValue(0.);
-      ui->vuWidget->setColors(QColor(255,50,0),Qt::green,Qt::red);
-      ui->vuWidget->setMaximum(40.);
-      ui->vuWidget->setMinimum(18.);
-      ui->vuWidget->setValue(0.);
-      ui->spectrumFrame->displaySettings(true,true);
-    }
-  else
-    {
-      ui->syncWidget->setColors(Qt::red,QColor(255,165,0),Qt::green);
-      ui->syncWidget->setMaximum(10.);
-      ui->syncWidget->setMinimum(0.);
-      ui->syncWidget->setValue(0.);
-      ui->vuWidget->setColors(QColor(255,50,0),Qt::green,Qt::red);
-      ui->vuWidget->setMaximum(10.);
-      ui->vuWidget->setMinimum(0.);
-      ui->vuWidget->setValue(0.);
-      ui->spectrumFrame->displaySettings(false,false);
-    }
-}
-
-void rxWidget::slotTransmissionMode(int rxtxMode)
-{
-  transmissionModeIndex=(etransmissionMode)rxtxMode;
-  start(false);
-  setSettingsTab();
-  txWidgetPtr->setSettingsTab();
-  if(transmissionModeIndex==DRM)
-    {
-      mainWindowPtr->setBSRPushButton(true);
-    }
-  else
-    {
-      mainWindowPtr->setBSRPushButton(true);
-    }
-   start(true);
-}
-
-void rxWidget::slotSaveImage()
-{
-    dirDialog  dd(this);
-    QString filename;
-    filename=dd.saveFileName(rxImagesPath,"*",defaultImageFormat);
-    if(filename.isEmpty()) return;
-    imageViewerPtr->save(filename,defaultImageFormat,true);
-}
-
diff --git a/qsstv/rxwidget.ui b/qsstv/rxwidget.ui
deleted file mode 100644
index af0beea..0000000
--- a/qsstv/rxwidget.ui
+++ /dev/null
@@ -1,877 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>rxWidget</class>
- <widget class="QWidget" name="rxWidget">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>914</width>
-    <height>494</height>
-   </rect>
-  </property>
-  <property name="font">
-   <font>
-    <family>Ubuntu Mono</family>
-    <pointsize>9</pointsize>
-    <weight>50</weight>
-    <italic>false</italic>
-    <bold>false</bold>
-   </font>
-  </property>
-  <property name="windowTitle">
-   <string>Form</string>
-  </property>
-  <layout class="QHBoxLayout" name="horizontalLayout">
-   <item>
-    <layout class="QVBoxLayout" name="verticalLayout_4" stretch="0,0">
-     <item>
-      <layout class="QHBoxLayout" name="horizontalLayout_3">
-       <item>
-        <widget class="QToolButton" name="startToolButton">
-         <property name="toolTip">
-          <string>Start receiver</string>
-         </property>
-         <property name="statusTip">
-          <string>Status Start receiver</string>
-         </property>
-         <property name="text">
-          <string>...</string>
-         </property>
-         <property name="icon">
-          <iconset resource="qsstv.qrc">
-           <normaloff>:/icons/start.png</normaloff>:/icons/start.png</iconset>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <widget class="QToolButton" name="stopToolButton">
-         <property name="toolTip">
-          <string>Stop receiver</string>
-         </property>
-         <property name="statusTip">
-          <string>Stop receiver</string>
-         </property>
-         <property name="text">
-          <string>...</string>
-         </property>
-         <property name="icon">
-          <iconset resource="qsstv.qrc">
-           <normaloff>:/icons/stop.png</normaloff>:/icons/stop.png</iconset>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <widget class="QToolButton" name="resyncToolButton">
-         <property name="toolTip">
-          <string>Restart receiver</string>
-         </property>
-         <property name="statusTip">
-          <string>Restart receiver</string>
-         </property>
-         <property name="text">
-          <string>...</string>
-         </property>
-         <property name="icon">
-          <iconset resource="qsstv.qrc">
-           <normaloff>:/icons/replay.png</normaloff>:/icons/replay.png</iconset>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <widget class="QToolButton" name="saveToolButton">
-         <property name="toolTip">
-          <string>Save image</string>
-         </property>
-         <property name="statusTip">
-          <string>Save Image</string>
-         </property>
-         <property name="text">
-          <string>...</string>
-         </property>
-         <property name="icon">
-          <iconset resource="qsstv.qrc">
-           <normaloff>:/icons/filesave.png</normaloff>:/icons/filesave.png</iconset>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <spacer name="horizontalSpacer">
-         <property name="orientation">
-          <enum>Qt::Horizontal</enum>
-         </property>
-         <property name="sizeHint" stdset="0">
-          <size>
-           <width>40</width>
-           <height>20</height>
-          </size>
-         </property>
-        </spacer>
-       </item>
-      </layout>
-     </item>
-     <item>
-      <widget class="imageViewer" name="imageFrame" native="true">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
-         <horstretch>1</horstretch>
-         <verstretch>1</verstretch>
-        </sizepolicy>
-       </property>
-       <property name="minimumSize">
-        <size>
-         <width>580</width>
-         <height>360</height>
-        </size>
-       </property>
-       <property name="maximumSize">
-        <size>
-         <width>1200</width>
-         <height>800</height>
-        </size>
-       </property>
-      </widget>
-     </item>
-    </layout>
-   </item>
-   <item>
-    <layout class="QVBoxLayout" name="verticalLayout_5">
-     <property name="spacing">
-      <number>2</number>
-     </property>
-     <item>
-      <widget class="vuMeter" name="syncWidget" native="true">
-       <property name="minimumSize">
-        <size>
-         <width>18</width>
-         <height>0</height>
-        </size>
-       </property>
-       <property name="maximumSize">
-        <size>
-         <width>18</width>
-         <height>16777215</height>
-        </size>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <widget class="vuMeter" name="vuWidget" native="true">
-       <property name="minimumSize">
-        <size>
-         <width>18</width>
-         <height>0</height>
-        </size>
-       </property>
-       <property name="maximumSize">
-        <size>
-         <width>18</width>
-         <height>16777215</height>
-        </size>
-       </property>
-      </widget>
-     </item>
-    </layout>
-   </item>
-   <item>
-    <layout class="QVBoxLayout" name="verticalLayout_6" stretch="0,1">
-     <property name="spacing">
-      <number>1</number>
-     </property>
-     <item>
-      <layout class="QVBoxLayout" name="verticalLayout_3" stretch="0">
-       <property name="spacing">
-        <number>0</number>
-       </property>
-       <item>
-        <widget class="QTabWidget" name="settingsTableWidget">
-         <property name="enabled">
-          <bool>true</bool>
-         </property>
-         <property name="minimumSize">
-          <size>
-           <width>0</width>
-           <height>0</height>
-          </size>
-         </property>
-         <property name="maximumSize">
-          <size>
-           <width>16777215</width>
-           <height>16777215</height>
-          </size>
-         </property>
-         <property name="currentIndex">
-          <number>0</number>
-         </property>
-         <widget class="QWidget" name="sstvTab">
-          <attribute name="title">
-           <string>SSTV</string>
-          </attribute>
-          <layout class="QVBoxLayout" name="verticalLayout_2">
-           <property name="spacing">
-            <number>1</number>
-           </property>
-           <property name="leftMargin">
-            <number>1</number>
-           </property>
-           <property name="topMargin">
-            <number>1</number>
-           </property>
-           <property name="rightMargin">
-            <number>1</number>
-           </property>
-           <property name="bottomMargin">
-            <number>1</number>
-           </property>
-           <item>
-            <layout class="QGridLayout" name="gridLayout">
-             <property name="spacing">
-              <number>2</number>
-             </property>
-             <item row="0" column="0">
-              <widget class="QCheckBox" name="useVISCheckBox">
-               <property name="toolTip">
-                <string>Use VIS Code to start</string>
-               </property>
-               <property name="statusTip">
-                <string>Use VIS Code to start</string>
-               </property>
-               <property name="text">
-                <string>Use VIS</string>
-               </property>
-              </widget>
-             </item>
-             <item row="0" column="1">
-              <widget class="QLabel" name="filterLabel">
-               <property name="text">
-                <string>Filter</string>
-               </property>
-               <property name="alignment">
-                <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-               </property>
-              </widget>
-             </item>
-             <item row="0" column="2">
-              <widget class="QComboBox" name="filterComboBox">
-               <property name="minimumSize">
-                <size>
-                 <width>110</width>
-                 <height>0</height>
-                </size>
-               </property>
-               <property name="toolTip">
-                <string>Reception filter</string>
-               </property>
-               <property name="statusTip">
-                <string>Reception filter</string>
-               </property>
-              </widget>
-             </item>
-             <item row="1" column="0">
-              <widget class="QCheckBox" name="autoSlantAdjustCheckBox">
-               <property name="toolTip">
-                <string>Correct slant automatically</string>
-               </property>
-               <property name="statusTip">
-                <string>Correct slant automatically</string>
-               </property>
-               <property name="text">
-                <string>Auto Slant</string>
-               </property>
-              </widget>
-             </item>
-             <item row="1" column="1">
-              <widget class="QLabel" name="squelchLabel">
-               <property name="toolTip">
-                <string>Sensitivity - Higher is more sensitive</string>
-               </property>
-               <property name="statusTip">
-                <string>Sensitivity - Higher is more sensitive</string>
-               </property>
-               <property name="text">
-                <string>Sensitivity</string>
-               </property>
-               <property name="alignment">
-                <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-               </property>
-              </widget>
-             </item>
-             <item row="2" column="0">
-              <widget class="QCheckBox" name="autoSaveCheckBox">
-               <property name="toolTip">
-                <string>Save image when complete</string>
-               </property>
-               <property name="statusTip">
-                <string>Save image when complete</string>
-               </property>
-               <property name="text">
-                <string>Autosave</string>
-               </property>
-              </widget>
-             </item>
-             <item row="2" column="1">
-              <widget class="QLabel" name="label">
-               <property name="text">
-                <string>Mode</string>
-               </property>
-               <property name="alignment">
-                <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-               </property>
-              </widget>
-             </item>
-             <item row="2" column="2">
-              <widget class="QComboBox" name="sstvModeComboBox"/>
-             </item>
-             <item row="1" column="2">
-              <widget class="QComboBox" name="squelchComboBox"/>
-             </item>
-            </layout>
-           </item>
-           <item>
-            <widget class="QLabel" name="sstvStatusLineEdit">
-             <property name="minimumSize">
-              <size>
-               <width>0</width>
-               <height>25</height>
-              </size>
-             </property>
-             <property name="frameShape">
-              <enum>QFrame::Panel</enum>
-             </property>
-             <property name="frameShadow">
-              <enum>QFrame::Sunken</enum>
-             </property>
-             <property name="lineWidth">
-              <number>3</number>
-             </property>
-             <property name="text">
-              <string/>
-             </property>
-            </widget>
-           </item>
-           <item>
-            <spacer name="verticalSpacer">
-             <property name="orientation">
-              <enum>Qt::Vertical</enum>
-             </property>
-             <property name="sizeHint" stdset="0">
-              <size>
-               <width>17</width>
-               <height>0</height>
-              </size>
-             </property>
-            </spacer>
-           </item>
-          </layout>
-         </widget>
-         <widget class="QWidget" name="drmTab">
-          <attribute name="title">
-           <string>DRM</string>
-          </attribute>
-          <layout class="QVBoxLayout" name="verticalLayout" stretch="1,0,1">
-           <property name="spacing">
-            <number>1</number>
-           </property>
-           <property name="leftMargin">
-            <number>1</number>
-           </property>
-           <property name="topMargin">
-            <number>1</number>
-           </property>
-           <property name="rightMargin">
-            <number>1</number>
-           </property>
-           <property name="bottomMargin">
-            <number>1</number>
-           </property>
-           <item>
-            <layout class="QVBoxLayout" name="drmLayout1" stretch="1">
-             <property name="spacing">
-              <number>1</number>
-             </property>
-             <item>
-              <widget class="drmStatusFrame" name="drmStatusWidget">
-               <property name="frameShape">
-                <enum>QFrame::StyledPanel</enum>
-               </property>
-               <property name="frameShadow">
-                <enum>QFrame::Raised</enum>
-               </property>
-              </widget>
-             </item>
-            </layout>
-           </item>
-           <item>
-            <widget class="QLabel" name="drmStatusLineEdit">
-             <property name="minimumSize">
-              <size>
-               <width>0</width>
-               <height>20</height>
-              </size>
-             </property>
-             <property name="font">
-              <font>
-               <pointsize>8</pointsize>
-              </font>
-             </property>
-             <property name="frameShape">
-              <enum>QFrame::Panel</enum>
-             </property>
-             <property name="frameShadow">
-              <enum>QFrame::Sunken</enum>
-             </property>
-             <property name="lineWidth">
-              <number>2</number>
-             </property>
-             <property name="text">
-              <string/>
-             </property>
-            </widget>
-           </item>
-           <item>
-            <layout class="QHBoxLayout" name="horizontalLayout_2">
-             <item>
-              <layout class="QVBoxLayout" name="drmLayout4" stretch="0,1">
-               <property name="spacing">
-                <number>1</number>
-               </property>
-               <item>
-                <widget class="QLabel" name="drmFACLabel">
-                 <property name="text">
-                  <string>FAC</string>
-                 </property>
-                 <property name="alignment">
-                  <set>Qt::AlignCenter</set>
-                 </property>
-                </widget>
-               </item>
-               <item>
-                <widget class="drmConstellationFrame" name="drmFACWidget">
-                 <property name="minimumSize">
-                  <size>
-                   <width>0</width>
-                   <height>80</height>
-                  </size>
-                 </property>
-                 <property name="maximumSize">
-                  <size>
-                   <width>16777215</width>
-                   <height>120</height>
-                  </size>
-                 </property>
-                 <property name="palette">
-                  <palette>
-                   <active>
-                    <colorrole role="WindowText">
-                     <brush brushstyle="SolidPattern">
-                      <color alpha="255">
-                       <red>76</red>
-                       <green>76</green>
-                       <blue>76</blue>
-                      </color>
-                     </brush>
-                    </colorrole>
-                    <colorrole role="Light">
-                     <brush brushstyle="SolidPattern">
-                      <color alpha="255">
-                       <red>197</red>
-                       <green>197</green>
-                       <blue>197</blue>
-                      </color>
-                     </brush>
-                    </colorrole>
-                    <colorrole role="Dark">
-                     <brush brushstyle="SolidPattern">
-                      <color alpha="255">
-                       <red>0</red>
-                       <green>0</green>
-                       <blue>0</blue>
-                      </color>
-                     </brush>
-                    </colorrole>
-                    <colorrole role="Text">
-                     <brush brushstyle="SolidPattern">
-                      <color alpha="255">
-                       <red>60</red>
-                       <green>60</green>
-                       <blue>60</blue>
-                      </color>
-                     </brush>
-                    </colorrole>
-                    <colorrole role="ButtonText">
-                     <brush brushstyle="SolidPattern">
-                      <color alpha="255">
-                       <red>76</red>
-                       <green>76</green>
-                       <blue>76</blue>
-                      </color>
-                     </brush>
-                    </colorrole>
-                   </active>
-                   <inactive>
-                    <colorrole role="WindowText">
-                     <brush brushstyle="SolidPattern">
-                      <color alpha="255">
-                       <red>76</red>
-                       <green>76</green>
-                       <blue>76</blue>
-                      </color>
-                     </brush>
-                    </colorrole>
-                    <colorrole role="Light">
-                     <brush brushstyle="SolidPattern">
-                      <color alpha="255">
-                       <red>197</red>
-                       <green>197</green>
-                       <blue>197</blue>
-                      </color>
-                     </brush>
-                    </colorrole>
-                    <colorrole role="Dark">
-                     <brush brushstyle="SolidPattern">
-                      <color alpha="255">
-                       <red>0</red>
-                       <green>0</green>
-                       <blue>0</blue>
-                      </color>
-                     </brush>
-                    </colorrole>
-                    <colorrole role="Text">
-                     <brush brushstyle="SolidPattern">
-                      <color alpha="255">
-                       <red>60</red>
-                       <green>60</green>
-                       <blue>60</blue>
-                      </color>
-                     </brush>
-                    </colorrole>
-                    <colorrole role="ButtonText">
-                     <brush brushstyle="SolidPattern">
-                      <color alpha="255">
-                       <red>76</red>
-                       <green>76</green>
-                       <blue>76</blue>
-                      </color>
-                     </brush>
-                    </colorrole>
-                   </inactive>
-                   <disabled>
-                    <colorrole role="WindowText">
-                     <brush brushstyle="SolidPattern">
-                      <color alpha="255">
-                       <red>0</red>
-                       <green>0</green>
-                       <blue>0</blue>
-                      </color>
-                     </brush>
-                    </colorrole>
-                    <colorrole role="Light">
-                     <brush brushstyle="SolidPattern">
-                      <color alpha="255">
-                       <red>197</red>
-                       <green>197</green>
-                       <blue>197</blue>
-                      </color>
-                     </brush>
-                    </colorrole>
-                    <colorrole role="Dark">
-                     <brush brushstyle="SolidPattern">
-                      <color alpha="255">
-                       <red>0</red>
-                       <green>0</green>
-                       <blue>0</blue>
-                      </color>
-                     </brush>
-                    </colorrole>
-                    <colorrole role="Text">
-                     <brush brushstyle="SolidPattern">
-                      <color alpha="255">
-                       <red>0</red>
-                       <green>0</green>
-                       <blue>0</blue>
-                      </color>
-                     </brush>
-                    </colorrole>
-                    <colorrole role="ButtonText">
-                     <brush brushstyle="SolidPattern">
-                      <color alpha="255">
-                       <red>0</red>
-                       <green>0</green>
-                       <blue>0</blue>
-                      </color>
-                     </brush>
-                    </colorrole>
-                   </disabled>
-                  </palette>
-                 </property>
-                 <property name="frameShape">
-                  <enum>QFrame::Panel</enum>
-                 </property>
-                 <property name="frameShadow">
-                  <enum>QFrame::Sunken</enum>
-                 </property>
-                 <property name="lineWidth">
-                  <number>3</number>
-                 </property>
-                </widget>
-               </item>
-              </layout>
-             </item>
-             <item>
-              <layout class="QVBoxLayout" name="drmLayout3" stretch="0,1">
-               <property name="spacing">
-                <number>1</number>
-               </property>
-               <item>
-                <widget class="QLabel" name="drmMSCLabel">
-                 <property name="text">
-                  <string>MSC</string>
-                 </property>
-                 <property name="alignment">
-                  <set>Qt::AlignCenter</set>
-                 </property>
-                </widget>
-               </item>
-               <item>
-                <widget class="drmConstellationFrame" name="drmMSCWidget">
-                 <property name="minimumSize">
-                  <size>
-                   <width>0</width>
-                   <height>80</height>
-                  </size>
-                 </property>
-                 <property name="maximumSize">
-                  <size>
-                   <width>16777215</width>
-                   <height>120</height>
-                  </size>
-                 </property>
-                 <property name="palette">
-                  <palette>
-                   <active>
-                    <colorrole role="WindowText">
-                     <brush brushstyle="SolidPattern">
-                      <color alpha="255">
-                       <red>76</red>
-                       <green>76</green>
-                       <blue>76</blue>
-                      </color>
-                     </brush>
-                    </colorrole>
-                    <colorrole role="Light">
-                     <brush brushstyle="SolidPattern">
-                      <color alpha="255">
-                       <red>197</red>
-                       <green>197</green>
-                       <blue>197</blue>
-                      </color>
-                     </brush>
-                    </colorrole>
-                    <colorrole role="Dark">
-                     <brush brushstyle="SolidPattern">
-                      <color alpha="255">
-                       <red>0</red>
-                       <green>0</green>
-                       <blue>0</blue>
-                      </color>
-                     </brush>
-                    </colorrole>
-                    <colorrole role="Text">
-                     <brush brushstyle="SolidPattern">
-                      <color alpha="255">
-                       <red>60</red>
-                       <green>60</green>
-                       <blue>60</blue>
-                      </color>
-                     </brush>
-                    </colorrole>
-                    <colorrole role="ButtonText">
-                     <brush brushstyle="SolidPattern">
-                      <color alpha="255">
-                       <red>76</red>
-                       <green>76</green>
-                       <blue>76</blue>
-                      </color>
-                     </brush>
-                    </colorrole>
-                   </active>
-                   <inactive>
-                    <colorrole role="WindowText">
-                     <brush brushstyle="SolidPattern">
-                      <color alpha="255">
-                       <red>76</red>
-                       <green>76</green>
-                       <blue>76</blue>
-                      </color>
-                     </brush>
-                    </colorrole>
-                    <colorrole role="Light">
-                     <brush brushstyle="SolidPattern">
-                      <color alpha="255">
-                       <red>197</red>
-                       <green>197</green>
-                       <blue>197</blue>
-                      </color>
-                     </brush>
-                    </colorrole>
-                    <colorrole role="Dark">
-                     <brush brushstyle="SolidPattern">
-                      <color alpha="255">
-                       <red>0</red>
-                       <green>0</green>
-                       <blue>0</blue>
-                      </color>
-                     </brush>
-                    </colorrole>
-                    <colorrole role="Text">
-                     <brush brushstyle="SolidPattern">
-                      <color alpha="255">
-                       <red>60</red>
-                       <green>60</green>
-                       <blue>60</blue>
-                      </color>
-                     </brush>
-                    </colorrole>
-                    <colorrole role="ButtonText">
-                     <brush brushstyle="SolidPattern">
-                      <color alpha="255">
-                       <red>76</red>
-                       <green>76</green>
-                       <blue>76</blue>
-                      </color>
-                     </brush>
-                    </colorrole>
-                   </inactive>
-                   <disabled>
-                    <colorrole role="WindowText">
-                     <brush brushstyle="SolidPattern">
-                      <color alpha="255">
-                       <red>0</red>
-                       <green>0</green>
-                       <blue>0</blue>
-                      </color>
-                     </brush>
-                    </colorrole>
-                    <colorrole role="Light">
-                     <brush brushstyle="SolidPattern">
-                      <color alpha="255">
-                       <red>197</red>
-                       <green>197</green>
-                       <blue>197</blue>
-                      </color>
-                     </brush>
-                    </colorrole>
-                    <colorrole role="Dark">
-                     <brush brushstyle="SolidPattern">
-                      <color alpha="255">
-                       <red>0</red>
-                       <green>0</green>
-                       <blue>0</blue>
-                      </color>
-                     </brush>
-                    </colorrole>
-                    <colorrole role="Text">
-                     <brush brushstyle="SolidPattern">
-                      <color alpha="255">
-                       <red>0</red>
-                       <green>0</green>
-                       <blue>0</blue>
-                      </color>
-                     </brush>
-                    </colorrole>
-                    <colorrole role="ButtonText">
-                     <brush brushstyle="SolidPattern">
-                      <color alpha="255">
-                       <red>0</red>
-                       <green>0</green>
-                       <blue>0</blue>
-                      </color>
-                     </brush>
-                    </colorrole>
-                   </disabled>
-                  </palette>
-                 </property>
-                 <property name="frameShape">
-                  <enum>QFrame::Panel</enum>
-                 </property>
-                 <property name="frameShadow">
-                  <enum>QFrame::Sunken</enum>
-                 </property>
-                 <property name="lineWidth">
-                  <number>3</number>
-                 </property>
-                </widget>
-               </item>
-              </layout>
-             </item>
-            </layout>
-           </item>
-          </layout>
-         </widget>
-        </widget>
-       </item>
-      </layout>
-     </item>
-     <item>
-      <widget class="spectrumWidget" name="spectrumFrame" native="true">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
-         <horstretch>0</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
-       </property>
-       <property name="minimumSize">
-        <size>
-         <width>100</width>
-         <height>80</height>
-        </size>
-       </property>
-       <property name="maximumSize">
-        <size>
-         <width>1000</width>
-         <height>1000</height>
-        </size>
-       </property>
-      </widget>
-     </item>
-    </layout>
-   </item>
-  </layout>
- </widget>
- <customwidgets>
-  <customwidget>
-   <class>imageViewer</class>
-   <extends>QWidget</extends>
-   <header>widgets/imageviewer.h</header>
-   <container>1</container>
-  </customwidget>
-  <customwidget>
-   <class>vuMeter</class>
-   <extends>QWidget</extends>
-   <header>widgets/vumeter.h</header>
-   <container>1</container>
-  </customwidget>
-  <customwidget>
-   <class>spectrumWidget</class>
-   <extends>QWidget</extends>
-   <header>widgets/spectrumwidget.h</header>
-   <container>1</container>
-  </customwidget>
-  <customwidget>
-   <class>drmStatusFrame</class>
-   <extends>QFrame</extends>
-   <header>drmrx/drmstatusframe.h</header>
-   <container>1</container>
-  </customwidget>
-  <customwidget>
-   <class>drmConstellationFrame</class>
-   <extends>QFrame</extends>
-   <header>drmrx/drmconstellationframe.h</header>
-   <container>1</container>
-  </customwidget>
- </customwidgets>
- <resources>
-  <include location="qsstv.qrc"/>
- </resources>
- <connections/>
-</ui>
diff --git a/qsstv/scope/scopeoffset.cpp b/qsstv/scope/scopeoffset.cpp
index 6990e46..0995eda 100644
--- a/qsstv/scope/scopeoffset.cpp
+++ b/qsstv/scope/scopeoffset.cpp
@@ -1,6 +1,8 @@
 #include "scopeoffset.h"
 #include "ui_scopeoffset.h"
 
+uint dataScopeOffset;
+
 scopeOffset::scopeOffset(QWidget *parent) :
   QDialog(parent),
   ui(new Ui::scopeOffset)
diff --git a/qsstv/scope/scopeoffset.h b/qsstv/scope/scopeoffset.h
index 1321a5a..7266abc 100644
--- a/qsstv/scope/scopeoffset.h
+++ b/qsstv/scope/scopeoffset.h
@@ -3,6 +3,8 @@
 
 #include <QDialog>
 
+extern uint dataScopeOffset;
+
 namespace Ui {
   class scopeOffset;
   }
diff --git a/qsstv/scope/scopeplot.cpp b/qsstv/scope/scopeplot.cpp
index 7115371..7bdb6f7 100644
--- a/qsstv/scope/scopeplot.cpp
+++ b/qsstv/scope/scopeplot.cpp
@@ -506,7 +506,6 @@ void scopePlot::pickerMoved(const QPointF &pos)
 
 void scopePlot::pickerSelected(const QPointF  &pos)
 {
-  // qDebug() << "selected" << toggleMarker;
   if (!toggleMarker)
     {
       marker1->setValue(pos);
diff --git a/qsstv/scope/scopeview.cpp b/qsstv/scope/scopeview.cpp
index b6c510b..1868f57 100644
--- a/qsstv/scope/scopeview.cpp
+++ b/qsstv/scope/scopeview.cpp
@@ -46,6 +46,15 @@ scopeView::~scopeView()
 
 void scopeView::init()
 {
+  setCurveName("data1",SCDATA1);
+  setCurveName("data2",SCDATA2);
+  setCurveName("data3",SCDATA3);
+  setCurveName("data4",SCDATA4);
+  clear();
+}
+
+void scopeView::clear()
+{
   int i;
   index=0;
   for (i=0;i<SCOPEMAXDATA;i++)
@@ -55,11 +64,6 @@ void scopeView::init()
       array3[i]=0.;
       array4[i]=0.;
     }
-  setCurveName("data1",SCDATA1);
-  setCurveName("data2",SCDATA2);
-  setCurveName("data3",SCDATA3);
-  setCurveName("data4",SCDATA4);
-
 }
 
 void scopeView::setOffset (int xoffset)
@@ -71,7 +75,7 @@ void scopeView::setOffset (int xoffset)
 void scopeView::addData(ecurve Idx,double *data,unsigned int position,unsigned int len)
 {
   unsigned int i,j;
-  double *ar;
+  double *ar=NULL;
   if(position<xOffset) return;
   switch(Idx)
     {
@@ -93,7 +97,7 @@ void scopeView::addData(ecurve Idx,double *data,unsigned int position,unsigned i
 void scopeView::addData(ecurve Idx,float *data,unsigned int position,unsigned int len)
 {
   unsigned int i,j;
-  double *ar;
+  double *ar=NULL;
   if(position<xOffset) return;
   switch(Idx)
     {
@@ -116,7 +120,7 @@ void scopeView::addData(ecurve Idx,float *data,unsigned int position,unsigned in
 void scopeView::addData(ecurve Idx, qint8 *data, unsigned int position, unsigned int len)
 {
   unsigned int i,j;
-  double *ar;
+  double *ar=NULL;
   if(position<xOffset) return;
   switch(Idx)
     {
@@ -137,7 +141,7 @@ void scopeView::addData(ecurve Idx, qint8 *data, unsigned int position, unsigned
 void scopeView::addData(ecurve Idx,quint8 *data, unsigned int position, unsigned int len)
 {
   unsigned int i,j;
-  double *ar;
+  double *ar=NULL;
   if(position<xOffset) return;
   switch(Idx)
     {
@@ -159,7 +163,7 @@ void scopeView::addData(ecurve Idx,quint8 *data, unsigned int position, unsigned
 void scopeView::addData(ecurve Idx,qint16 *data,unsigned int position,unsigned int len)
 {
   unsigned int i,j;
-  double *ar;
+  double *ar=NULL;
   if(position<xOffset) return;
   switch(Idx)
     {
@@ -181,7 +185,7 @@ void scopeView::addData(ecurve Idx,qint16 *data,unsigned int position,unsigned i
 void scopeView::addData(ecurve Idx,quint16 *data,unsigned int position,unsigned int len)
 {
   unsigned int i,j;
-  double *ar;
+  double *ar=NULL;
   if(position<xOffset) return;
   switch(Idx)
     {
@@ -204,7 +208,7 @@ void scopeView::addData(ecurve Idx,quint16 *data,unsigned int position,unsigned
 void scopeView::addData(ecurve Idx,qint32 *data,unsigned int position,unsigned int len)
 {
   unsigned int i,j;
-  double *ar;
+  double *ar=NULL;
   if(position<xOffset) return;
   switch(Idx)
     {
@@ -226,7 +230,7 @@ void scopeView::addData(ecurve Idx,qint32 *data,unsigned int position,unsigned i
 void scopeView::addData(ecurve Idx,quint32 *data,unsigned int position,unsigned int len)
 {
   unsigned int i,j;
-  double *ar;
+  double *ar=NULL;
   if(position<xOffset) return;
   switch(Idx)
     {
diff --git a/qsstv/scope/scopeview.h b/qsstv/scope/scopeview.h
index cec3279..74540d4 100644
--- a/qsstv/scope/scopeview.h
+++ b/qsstv/scope/scopeview.h
@@ -30,12 +30,12 @@
  ***************************************************************************/
 #ifndef SCOPEVIEW_H
 #define SCOPEVIEW_H
-#include "qsstvglobal.h"
+#include "appglobal.h"
 #include <QString>
 
 #include "scopeplot.h"
 
-#define SCOPEMAXDATA	200000
+#define SCOPEMAXDATA	300000
 /**
 	@author Johan Maes <on4qz at telenet.be>
 */
@@ -49,6 +49,7 @@ public:
   scopeView(QString title);
   ~scopeView();
   void init();
+  void clear();
   void setOffset (int xoffset);
 
   void addData(ecurve Idx,double  *data,unsigned int position,unsigned int len);
diff --git a/qsstv/sound/calibration.cpp b/qsstv/sound/calibration.cpp
index 4576dc3..c6e00c7 100644
--- a/qsstv/sound/calibration.cpp
+++ b/qsstv/sound/calibration.cpp
@@ -21,20 +21,21 @@
 #include "calibration.h"
 #include "ui_calibration.h"
 #include <QApplication>
-#include "qsstvglobal.h"
-#include "sound/soundio.h"
+#include "appglobal.h"
+#include "soundbase.h"
+#include "dispatcher.h"
 #include <math.h>
 #include "QMessageBox"
 #include <QPushButton>
 
 
-#define ITERATIONS 100
+#define ITERATIONS 8000
 
 
 /**
  * \class calibration
  *
- * Check first if ntp is running and it is synchronised. A dialog window will appear and show the progress ofr the RX and TX clocks.
+ * Check first if ntp is running and it is synchronised. A dialog window will appear and show the progress of the RX and TX clocks.
  * About 10000 blocks of data will be read/written to calculate the exact timing. If the OK button is pressed, the clocks will be saved for later use.
  *
  **/
@@ -46,9 +47,7 @@
  *
  * @param parent parent widget pointer
  */
-calibration::calibration(QWidget *parent) :
-  QDialog(parent),
-  ui(new Ui::calibration)
+calibration::calibration(QWidget *parent) : QDialog(parent),  ui(new Ui::calibration)
 {
   ui->setupUi(this);
   init();
@@ -82,11 +81,11 @@ int calibration::exec()
   if(!start(false)) return QDialog::Rejected;
   ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
   while(!stopped)
-    {
-      qApp->processEvents();
-    }
- if(!canceled) return QDialog::Accepted;
- return QDialog::Rejected;
+  {
+    qApp->processEvents();
+  }
+  if(!canceled) return QDialog::Accepted;
+  return QDialog::Rejected;
 }
 
 
@@ -140,70 +139,62 @@ void calibration::hasFinished(int result)
 bool calibration::start(bool isRX)
 {
   unsigned int i;
-  double clock=48000;
-  int frames;
-  int framesDone=-1;
-  int elapsed;
-  QString blockStr;
-  if(isRX)
-    {
-      blockStr="blockRX: ";
-    }
-  else
-    {
-      blockStr="blockTX: ";
-    }
-
-  if(!soundIOPtr->startCalibration(isRX))
-    {
-      QMessageBox::critical(this,"Calibration Error","Souncard not active");
-      return false;
-    }
-  for(i=0;i<ITERATIONS;)
+  double clock=0;
+  unsigned int frames;
+  double elapsedTime;
+  double elapsed=0;
+
+  if(!soundIOPtr->calibrate(isRX))
+  {
+    QMessageBox::critical(this,"Calibration Error","Souncard not active");
+    return false;
+  }
+  for(i=0;(i<ITERATIONS)&&(!stopped);)
+  {
+    qApp->processEvents();
+    if(soundIOPtr->calibrationCount(frames,elapsedTime))
     {
-      qApp->processEvents();
-      if(!soundIOPtr->isRunning()) return false;
-      elapsed=soundIOPtr->calibrationCount(frames);
-      if((frames%50==0)&&(frames>0)&&(frames!=framesDone))
+      i++;
+      logFilePtr->addToAux(QString("%1\t%2\t%3").arg(frames).arg(elapsedTime).arg(elapsedTime-elapsed));
+      elapsed=elapsedTime;
+      if(i%2==0)
         {
-          i++;
-          framesDone=frames;
-          clock=((double)frames*1000.*PERIODSIZE)/((double)elapsed);
-          if(isRX)
-            {
-              display(clock,ui->rxLCD);
-              ui->rxProgress->setValue(i);
-            }
-          else
-            {
-              display(clock,ui->txLCD);
-              ui->txProgress->setValue(i);
-            }
+        clock=((double)frames*CALIBRATIONSIZE)/(elapsedTime); // debug joma
+        if(isRX)
+        {
+          display((int) round(clock),ui->rxLCD);
+          ui->rxProgress->setValue(i);
         }
-     }
-  soundIOPtr->idle();
-  if(isRX)
-    {
-      rxCardClock=clock;
+        else
+        {
+          display((int) round(clock),ui->txLCD);
+          ui->txProgress->setValue(i);
+        }
+      }
     }
+    else
+      {
+        usleep(10000);
+      }
+  }
+  dispatcherPtr->idleAll();
+  if(isRX)
+  {
+    rxCardClock=clock;
+  }
   else
-    {
-      txCardClock=clock;
-    }
+  {
+    txCardClock=clock;
+  }
   return true;
 }
 
 
-void calibration::display(double value,QLCDNumber *dspl)
+void calibration::display(int value,QLCDNumber *dspl)
 {
-  QString tmp=QString::number(value,'g',7);
-  switch(tmp.length())
-    {
-    case 5: tmp+=".00"; break;
-    case 6: tmp+="00"; break;
-    case 7: tmp+="0"; break;
-    }
-   dspl->display(tmp);
+//  QString tmp=QString::number(value,'g',6);
+//  if(tmp.length()==5) tmp+=".0";
+  dspl->display(value);
 }
 
 
diff --git a/qsstv/sound/calibration.h b/qsstv/sound/calibration.h
index fad9f3e..9cee3a2 100644
--- a/qsstv/sound/calibration.h
+++ b/qsstv/sound/calibration.h
@@ -42,7 +42,7 @@ private:
   bool stopped;
   void init();
   bool start(bool isRX);
-  void display(double value,QLCDNumber *dspl);
+  void display(int value,QLCDNumber *dspl);
   bool canceled;
 };
 
diff --git a/qsstv/sound/calibration.ui b/qsstv/sound/calibration.ui
index dc392cf..dbea928 100644
--- a/qsstv/sound/calibration.ui
+++ b/qsstv/sound/calibration.ui
@@ -321,6 +321,9 @@
        <property name="autoFillBackground">
         <bool>true</bool>
        </property>
+       <property name="frameShape">
+        <enum>QFrame::NoFrame</enum>
+       </property>
        <property name="lineWidth">
         <number>2</number>
        </property>
@@ -330,11 +333,8 @@
        <property name="smallDecimalPoint">
         <bool>false</bool>
        </property>
-       <property name="numDigits">
-        <number>8</number>
-       </property>
        <property name="digitCount">
-        <number>8</number>
+        <number>5</number>
        </property>
        <property name="segmentStyle">
         <enum>QLCDNumber::Filled</enum>
@@ -653,9 +653,15 @@
          </disabled>
         </palette>
        </property>
+       <property name="layoutDirection">
+        <enum>Qt::LeftToRight</enum>
+       </property>
        <property name="autoFillBackground">
         <bool>true</bool>
        </property>
+       <property name="frameShape">
+        <enum>QFrame::NoFrame</enum>
+       </property>
        <property name="lineWidth">
         <number>2</number>
        </property>
@@ -665,11 +671,8 @@
        <property name="smallDecimalPoint">
         <bool>false</bool>
        </property>
-       <property name="numDigits">
-        <number>8</number>
-       </property>
        <property name="digitCount">
-        <number>8</number>
+        <number>5</number>
        </property>
        <property name="segmentStyle">
         <enum>QLCDNumber::Filled</enum>
@@ -685,6 +688,13 @@
     </layout>
    </item>
    <item>
+    <widget class="QLabel" name="label">
+     <property name="text">
+      <string>Only used for SSTV. This takes several minutes,. Please be patient. </string>
+     </property>
+    </widget>
+   </item>
+   <item>
     <spacer name="verticalSpacer">
      <property name="orientation">
       <enum>Qt::Vertical</enum>
diff --git a/qsstv/sound/calibrationform.ui b/qsstv/sound/calibrationform.ui
deleted file mode 100644
index 791266d..0000000
--- a/qsstv/sound/calibrationform.ui
+++ /dev/null
@@ -1,127 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>CalibrationForm</class>
- <widget class="QDialog" name="CalibrationForm">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>345</width>
-    <height>96</height>
-   </rect>
-  </property>
-  <property name="sizePolicy">
-   <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
-    <horstretch>0</horstretch>
-    <verstretch>0</verstretch>
-   </sizepolicy>
-  </property>
-  <property name="maximumSize">
-   <size>
-    <width>16777215</width>
-    <height>110</height>
-   </size>
-  </property>
-  <property name="windowTitle">
-   <string>Calibration</string>
-  </property>
-  <layout class="QVBoxLayout" name="verticallAYOUT">
-   <item>
-    <layout class="QHBoxLayout" name="horizontalLayout">
-     <item>
-      <widget class="QLabel" name="rxLabel">
-       <property name="minimumSize">
-        <size>
-         <width>150</width>
-         <height>0</height>
-        </size>
-       </property>
-       <property name="text">
-        <string>RX</string>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <widget class="QProgressBar" name="rxProgressBar">
-       <property name="value">
-        <number>24</number>
-       </property>
-      </widget>
-     </item>
-    </layout>
-   </item>
-   <item>
-    <layout class="QHBoxLayout" name="horizontalLayout_2">
-     <item>
-      <widget class="QLabel" name="txLabel">
-       <property name="minimumSize">
-        <size>
-         <width>150</width>
-         <height>0</height>
-        </size>
-       </property>
-       <property name="text">
-        <string>TX</string>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <widget class="QProgressBar" name="txProgressBar">
-       <property name="value">
-        <number>24</number>
-       </property>
-      </widget>
-     </item>
-    </layout>
-   </item>
-   <item>
-    <widget class="QDialogButtonBox" name="buttonBox">
-     <property name="orientation">
-      <enum>Qt::Horizontal</enum>
-     </property>
-     <property name="standardButtons">
-      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
-     </property>
-     <property name="centerButtons">
-      <bool>true</bool>
-     </property>
-    </widget>
-   </item>
-  </layout>
- </widget>
- <resources/>
- <connections>
-  <connection>
-   <sender>buttonBox</sender>
-   <signal>accepted()</signal>
-   <receiver>CalibrationForm</receiver>
-   <slot>accept()</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>248</x>
-     <y>254</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>157</x>
-     <y>274</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
-   <sender>buttonBox</sender>
-   <signal>rejected()</signal>
-   <receiver>CalibrationForm</receiver>
-   <slot>reject()</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>316</x>
-     <y>260</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>286</x>
-     <y>274</y>
-    </hint>
-   </hints>
-  </connection>
- </connections>
-</ui>
diff --git a/qsstv/sound/resampler.cpp b/qsstv/sound/resampler.cpp
deleted file mode 100644
index fba536d..0000000
--- a/qsstv/sound/resampler.cpp
+++ /dev/null
@@ -1,146 +0,0 @@
-/**************************************************************************
-*   Copyright (C) 2000-2012 by Johan Maes                                 *
-*   on4qz at telenet.be                                                      *
-*   http://users.telenet.be/on4qz                                         *
-*                                                                         *
-*   Based on software from                                                *
-*   Technische Universitaet Darmstadt, Institut fuer Nachrichtentechnik   *
-*   Author(s):                                                            *
-*   Volker Fischer                                                        *
-*                                                                         *
-*   This program is free software; you can redistribute it and/or modify  *
-*   it under the terms of the GNU General Public License as published by  *
-*   the Free Software Foundation; either version 2 of the License, or     *
-*   (at your option) any later version.                                   *
-*                                                                         *
-*   This program is distributed in the hope that it will be useful,       *
-*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
-*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
-*   GNU General Public License for more details.                          *
-*                                                                         *
-*   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.,                                       *
-*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
-***************************************************************************/
-#include "resampler.h"
-#include "qsstvglobal.h"
-#include "sound/soundio.h"
-
-/**
- * @brief Resample routine for arbitrary sample-rate conversions
- *
- * Resample routine for arbitrary sample-rate conversions in a low range (for
- * frequency offset correction).
- * The algorithm is based on a polyphase structure. We upsample the input
- * signal with a factor INTERP_DECIM_I_D and calculate two successive samples
- * whereby we perform a linear interpolation between these two samples to get
- * an arbitraty sample grid.
- *
- * @param prInput input buffer data (e.g. soundcard)
- * @param prOutput output buffer (resampled data)
- * @param rRation  conversion ratio
- * @return int
- */
-
-resampler::resampler()
-{
-  resamplerBuffer=NULL;
-}
-
-resampler::~resampler()
-{
-  if(resamplerBuffer!=NULL) delete  resamplerBuffer;
-}
-
-
-/**
- * @brief resample the audio data
- *
- * When this function is called, there is already enough data in the sound carad buffers
- *
- * @param rRation the resample ratio
- */
-void resampler::resample(DSPFLOAT rRation, DSPFLOAT *inputBuffer)
-{
-  unsigned int i;
-
-  /* Move old data from the end to the history part of the buffer and add new data (shift register) */
-  for (i = 0; i < iHistorySize; i++) resamplerBuffer[i] = resamplerBuffer[i + iInputBlockSize];
-  for (i = 0; i < iInputBlockSize; i++)  resamplerBuffer[i + iHistorySize] = inputBuffer[i];
-
-  /* Sample-interval of new sample frequency in relation to interpolated  sample-interval */
-  rTStep = (DSPFLOAT) INTERP_DECIM_I_D / rRation;
-
-	/* Init output counter */
-	int im = 0;
-//    if (input_samples_buffer_request == 0)	/* no resampling needed, just copy */
-
-      {
-        im = iInputBlockSize;
-        for (i = 0; i < iInputBlockSize; i++) rxBuffer.put(resamplerBuffer[i + iHistorySize]);
-        return ;
-      }
-
-	/* Main loop */
-	do
-	{
-		/* Quantize output-time to interpolated time-index */
-    const int ik = (int) rtOut;
-
-
-		/* Calculate convolutions for the two interpolation-taps ------------ */
-		/* Phase for the linear interpolation-taps */
-		const int ip1 = ik % INTERP_DECIM_I_D;
-		const int ip2 = (ik + 1) % INTERP_DECIM_I_D;
-
-		/* Sample positions in input vector */
-		const int in1 = (int) (ik / INTERP_DECIM_I_D);
-		const int in2 = (int) ((ik + 1) / INTERP_DECIM_I_D);
-
-		/* Convolution */
-    DSPFLOAT ry1 = (DSPFLOAT) 0.0;
-    DSPFLOAT ry2 = (DSPFLOAT) 0.0;
-		for (int i = 0; i < RES_FILT_NUM_TAPS_PER_PHASE; i++)
-		{
-      ry1 += fResTaps1To1[ip1][i] * resamplerBuffer[in1 - i];
-      ry2 += fResTaps1To1[ip2][i] * resamplerBuffer[in2 - i];
-		}
-
-
-		/* Linear interpolation --------------------------------------------- */
-		/* Get numbers after the comma */
-    const DSPFLOAT rxInt = rtOut - (int) rtOut;
-    rxBuffer.put((ry2 - ry1) * rxInt + ry1);
-		/* Increase output counter */
-		im++;
-
-		/* Increase output-time and index one step */
-		rtOut = rtOut + rTStep;
-	} 
-	while (rtOut < rBlockDuration);
-
-	/* Set rtOut back */
-	rtOut -= iInputBlockSize * INTERP_DECIM_I_D;
-}
-
-void resampler::init(int blocksize)
-{
-  unsigned int i;
-  iInputBlockSize = blocksize;
-
-  /* History size must be one sample larger, because we use always TWO convolutions */
-	iHistorySize = RES_FILT_NUM_TAPS_PER_PHASE + 1;
-
-	/* Calculate block duration */
-  rBlockDuration = (iInputBlockSize + RES_FILT_NUM_TAPS_PER_PHASE) * INTERP_DECIM_I_D;
-
-	/* Allocate memory for internal buffer, clear sample history */
-  resamplerBuffer= new DSPFLOAT[iInputBlockSize + iHistorySize];
-  for(i=0;i<(iInputBlockSize + iHistorySize);i++) resamplerBuffer[i]= 0;
-	/* Init absolute time for output stream (at the end of the history part) */
-  rtOut = (DSPFLOAT) RES_FILT_NUM_TAPS_PER_PHASE * INTERP_DECIM_I_D;
-  rxBuffer.reset();
-}
-
-
diff --git a/qsstv/sound/resampler.cpp_new b/qsstv/sound/resampler.cpp_new
deleted file mode 100644
index d35c4cf..0000000
--- a/qsstv/sound/resampler.cpp_new
+++ /dev/null
@@ -1,147 +0,0 @@
-/**************************************************************************
-*   Copyright (C) 2000-2012 by Johan Maes                                 *
-*   on4qz at telenet.be                                                      *
-*   http://users.telenet.be/on4qz                                         *
-*                                                                         *
-*   Based on software from                                                *
-*   Technische Universitaet Darmstadt, Institut fuer Nachrichtentechnik   *
-*   Author(s):                                                            *
-*   Volker Fischer                                                        *
-*                                                                         *
-*   This program is free software; you can redistribute it and/or modify  *
-*   it under the terms of the GNU General Public License as published by  *
-*   the Free Software Foundation; either version 2 of the License, or     *
-*   (at your option) any later version.                                   *
-*                                                                         *
-*   This program is distributed in the hope that it will be useful,       *
-*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
-*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
-*   GNU General Public License for more details.                          *
-*                                                                         *
-*   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.,                                       *
-*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
-***************************************************************************/
-#include "resampler.h"
-#include "qsstvglobal.h"
-#include "sound/soundio.h"
-
-/**
- * @brief Resample routine for arbitrary sample-rate conversions
- *
- * Resample routine for arbitrary sample-rate conversions in a low range (for
- * frequency offset correction).
- * The algorithm is based on a polyphase structure. We upsample the input
- * signal with a factor INTERP_DECIM_I_D and calculate two successive samples
- * whereby we perform a linear interpolation between these two samples to get
- * an arbitraty sample grid.
- *
- * @param prInput input buffer data (e.g. soundcard)
- * @param prOutput output buffer (resampled data)
- * @param rRation  conversion ratio
- * @return int
- */
-
-resampler::resampler()
-{
-  resamplerBuffer=NULL;
-}
-
-resampler::~resampler()
-{
-  if(resamplerBuffer!=NULL) delete  resamplerBuffer;
-}
-
-
-/**
- * @brief resample the audio data
- *
- * When this function is called, there is already enough data in the sound carad buffers
- *
- * @param rRation the resample ratio
- */
-void resampler::resample(DSPFLOAT rRation, short int *inputBuffer)
-{
-  unsigned int i;
-
-  /* Move old data from the end to the history part of the buffer and add new data (shift register) */
-  for (i = 0; i < iHistorySize; i++) resamplerBuffer[i] = resamplerBuffer[i + iInputBlockSize];
-  for (i = 0; i < iInputBlockSize; i++)  resamplerBuffer[i + iHistorySize] = (DSPFLOAT) inputBuffer[i];
-
-  /* Sample-interval of new sample frequency in relation to interpolated  sample-interval */
-  rTStep = (DSPFLOAT) INTERP_DECIM_I_D / rRation;
-
-	/* Init output counter */
-	int im = 0;
-  if(rRation==1)
-//    if (input_samples_buffer_request == 0)	/* no resampling needed, just copy */
-
-      {
-        im = iInputBlockSize;
-        for (i = 0; i < iInputBlockSize; i++) rxBuffer.put(resamplerBuffer[i + iHistorySize]);
-        return ;
-      }
-
-	/* Main loop */
-	do
-	{
-		/* Quantize output-time to interpolated time-index */
-    const int ik = (int) rtOut;
-
-
-		/* Calculate convolutions for the two interpolation-taps ------------ */
-		/* Phase for the linear interpolation-taps */
-		const int ip1 = ik % INTERP_DECIM_I_D;
-		const int ip2 = (ik + 1) % INTERP_DECIM_I_D;
-
-		/* Sample positions in input vector */
-		const int in1 = (int) (ik / INTERP_DECIM_I_D);
-		const int in2 = (int) ((ik + 1) / INTERP_DECIM_I_D);
-
-		/* Convolution */
-    DSPFLOAT ry1 = (DSPFLOAT) 0.0;
-    DSPFLOAT ry2 = (DSPFLOAT) 0.0;
-		for (int i = 0; i < RES_FILT_NUM_TAPS_PER_PHASE; i++)
-		{
-      ry1 += fResTaps1To1[ip1][i] * resamplerBuffer[in1 - i];
-      ry2 += fResTaps1To1[ip2][i] * resamplerBuffer[in2 - i];
-		}
-
-
-		/* Linear interpolation --------------------------------------------- */
-		/* Get numbers after the comma */
-    const DSPFLOAT rxInt = rtOut - (int) rtOut;
-    rxBuffer.put((ry2 - ry1) * rxInt + ry1);
-		/* Increase output counter */
-		im++;
-
-		/* Increase output-time and index one step */
-		rtOut = rtOut + rTStep;
-	} 
-	while (rtOut < rBlockDuration);
-
-	/* Set rtOut back */
-	rtOut -= iInputBlockSize * INTERP_DECIM_I_D;
-}
-
-void resampler::init(int blocksize)
-{
-  unsigned int i;
-  iInputBlockSize = blocksize;
-
-  /* History size must be one sample larger, because we use always TWO convolutions */
-	iHistorySize = RES_FILT_NUM_TAPS_PER_PHASE + 1;
-
-	/* Calculate block duration */
-  rBlockDuration = (iInputBlockSize + RES_FILT_NUM_TAPS_PER_PHASE) * INTERP_DECIM_I_D;
-
-	/* Allocate memory for internal buffer, clear sample history */
-  resamplerBuffer= new DSPFLOAT[iInputBlockSize + iHistorySize];
-  for(i=0;i<(iInputBlockSize + iHistorySize);i++) resamplerBuffer[i]= 0;
-	/* Init absolute time for output stream (at the end of the history part) */
-  rtOut = (DSPFLOAT) RES_FILT_NUM_TAPS_PER_PHASE * INTERP_DECIM_I_D;
-  rxBuffer.reset();
-}
-
-
diff --git a/qsstv/sound/resampler.h b/qsstv/sound/resampler.h
deleted file mode 100644
index b95f9fb..0000000
--- a/qsstv/sound/resampler.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#ifndef RESAMPLER_H
-#define RESAMPLER_H
-
-#include "resamplefilter.h"
-#include "qsstvdefs.h"
-#include "utils/buffermanag.h"
-
-
-/* Classes ********************************************************************/
-class resampler
-{
-public:
-  resampler();
-  ~resampler();
-  void init(int blocksize);
-  void resample(DSPFLOAT rRation, DSPFLOAT *inputBuffer);
-  buffer<DSPFLOAT,16> rxBuffer;
-protected:
-  DSPFLOAT *resamplerBuffer;
-  DSPFLOAT rTStep;
-  DSPFLOAT rtOut;
-  DSPFLOAT rBlockDuration;
-  unsigned int	iHistorySize;
-  unsigned int iInputBlockSize;
-
-};
-
-#endif
diff --git a/qsstv/sound/soundalsa.cpp b/qsstv/sound/soundalsa.cpp
new file mode 100644
index 0000000..b069c0d
--- /dev/null
+++ b/qsstv/sound/soundalsa.cpp
@@ -0,0 +1,341 @@
+#include "soundalsa.h"
+#include "configparams.h"
+
+
+soundAlsa::soundAlsa()
+{
+  captureHandle=NULL;
+  playbackHandle=NULL;
+}
+
+soundAlsa::~soundAlsa()
+{
+
+}
+
+void soundAlsa::closeDevices()
+{
+  if(captureHandle!=NULL) snd_pcm_close(captureHandle);
+  captureHandle=NULL;
+  if(playbackHandle!=NULL) snd_pcm_close(playbackHandle);
+  playbackHandle=NULL;
+
+}
+
+bool soundAlsa::init(int samplerate)
+{
+  int iteration=0;
+  soundDriverOK=false;
+  sampleRate=samplerate;
+  int err;
+  QString tempDevice;
+  tempDevice=outputAudioDevice.left(outputAudioDevice.indexOf(" "));
+  for(iteration=0;iteration<20;iteration++)
+  {
+    err = snd_pcm_open(&playbackHandle,tempDevice.toLatin1().data(), SND_PCM_STREAM_PLAYBACK,0); //open in blocking mode
+    if (err==-EBUSY)
+      {
+        msleep(500);
+        continue;// give it another try
+      }
+    else
+    {
+      if(!alsaErrorHandler(err,"Unable to open "+outputAudioDevice)) return false;
+      break;
+    }
+  }
+  if(!alsaErrorHandler(err,"Unable to open "+outputAudioDevice)) return false;
+  tempDevice=inputAudioDevice.left(inputAudioDevice.indexOf(" "));
+  err = snd_pcm_open(&captureHandle,tempDevice.toLatin1().data(), SND_PCM_STREAM_CAPTURE, 0);
+  if(!alsaErrorHandler(err,"Unable to open "+inputAudioDevice)) return false;
+  snd_pcm_hw_params_malloc ( &hwparams );
+  snd_pcm_sw_params_malloc ( &swparams );
+
+  if(setupSoundParams(true))
+  {
+    if(setupSoundParams(false)) soundDriverOK=true;
+  }
+  snd_pcm_hw_params_free ( hwparams );
+  snd_pcm_sw_params_free ( swparams );
+  return soundDriverOK;
+}
+
+void soundAlsa::prepareCapture()
+{
+  int err;
+
+  if((err=snd_pcm_prepare (captureHandle)) < 0)
+  {
+    alsaErrorHandler(err,"Unable to prepare "+inputAudioDevice);
+  }
+  if((err=snd_pcm_start (captureHandle))< 0)
+  {
+    alsaErrorHandler(err,"Unable to start "+inputAudioDevice);
+  }
+}
+
+void soundAlsa::preparePlayback()
+{
+  snd_pcm_prepare (playbackHandle);
+}
+
+int soundAlsa::read(int &countAvailable)
+{
+  int i,count;
+//  addToLog("1",LOGPERFORM);
+   countAvailable=snd_pcm_avail(captureHandle); // check for available frames
+  if(countAvailable>=DOWNSAMPLESIZE)
+  {
+    addToLog(QString("countAV %1").arg(countAvailable),LOGPERFORM);
+    count = snd_pcm_readi(captureHandle, tempRXBuffer,DOWNSAMPLESIZE);
+    addToLog(QString("3 %1").arg(count),LOGPERFORM);
+    //we have enough data to read;
+    if ( count < 0 )
+    {
+      if ( count != -EAGAIN )
+      {
+        if ( count == -EPIPE )
+        {
+          // Overrun
+          snd_pcm_prepare (captureHandle );
+          snd_pcm_start (captureHandle);
+          errorOut() << "Overrun";
+        }
+        else
+        {
+          snd_pcm_drop (captureHandle );
+          errorOut() <<"Overrun , reason: "<< count << "Stopping device";
+        }
+      }
+      addToLog("soundIO: sound eagain",LOGSOUND);
+      return 0;
+    }
+    if(count!=DOWNSAMPLESIZE)
+    {
+       errorOut() <<"Partial read "<< count ;
+      return 0;
+    }
+    if (isStereo)
+    {
+      for(i=1;i<DOWNSAMPLESIZE;i++)
+      {
+        tempRXBuffer[i]=tempRXBuffer[2*i];
+      }
+    }
+    return DOWNSAMPLESIZE;
+  }
+  return 0;
+}
+
+int soundAlsa::write(uint numFrames)
+{
+  int error,framesWritten;
+  if((framesWritten =  snd_pcm_writei ( playbackHandle, tempTXBuffer, numFrames))<0)
+  {
+    alsaErrorHandler(framesWritten,"Error in writing to "+inputAudioDevice);
+    if ( framesWritten ==  -EAGAIN )
+      {
+         return -1;
+      }
+     else if ( framesWritten == -EPIPE )
+      {
+        /* underrun */
+        error = snd_pcm_prepare (playbackHandle);
+        if ( error < 0 )
+          {
+            alsaErrorHandler(framesWritten,"Can't recover from underrun, prepare failed");
+            snd_pcm_drop (playbackHandle);
+          }
+        }
+     else
+          {
+            alsaErrorHandler(framesWritten,"Unhandled error in playback");
+            snd_pcm_drop (playbackHandle );
+          }
+    return -1;
+  }
+  if(framesWritten!=(int)numFrames)
+  {
+    errorHandler("Sound write error",QString("Frames written = %1").arg(framesWritten));
+  }
+  return framesWritten;
+}
+
+
+void soundAlsa::flushCapture()
+{
+  int countAvailable,count;
+  snd_pcm_readi(captureHandle, tempRXBuffer,DOWNSAMPLESIZE); // dummy read
+  countAvailable=snd_pcm_avail(captureHandle); // check for available frames
+//  addToLog(QString("counts available %1").arg(countAvailable),LOGPERFORM);
+  while(countAvailable>=DOWNSAMPLESIZE)
+  {
+    count=snd_pcm_readi(captureHandle, tempRXBuffer,DOWNSAMPLESIZE);
+    countAvailable-=count;
+  }
+//  countAvailable=snd_pcm_avail(captureHandle); // check for available frames
+//  addToLog(QString("counts available %1").arg(countAvailable),LOGPERFORM);
+}
+
+void soundAlsa::flushPlayback()
+{
+
+}
+
+bool soundAlsa::setupSoundParams(bool isCapture)
+{
+  int err;
+  int dir=0;
+  snd_pcm_t *handle;
+  isStereo=false;
+
+  playbackPeriodSize=PERIODSIZE;
+  playbackBufferSize=BUFFERSIZE;
+  capturePeriodSize=PERIODSIZE;
+  captureBufferSize=PERIODSIZE*2;
+
+
+  if(isCapture) handle=captureHandle;
+  else handle=playbackHandle;
+
+  /* Choose all parameters */
+  err = snd_pcm_hw_params_any ( handle, hwparams );
+  if(!alsaErrorHandler(err,"Broken configuration : no configurations available"))
+  {
+    return false;
+  }
+
+
+  /* Set the interleaved read/write format */
+  err = snd_pcm_hw_params_set_access ( handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED );
+  if(!alsaErrorHandler(err,"Access type not available : ")) return false;
+
+  /* Set the sample format */
+  err = snd_pcm_hw_params_set_format ( handle, hwparams, SND_PCM_FORMAT_S16_LE );
+  if(!alsaErrorHandler(err,"Sample format Float not available : ")) return false;
+  /* Set the count of channels */
+  if(isCapture)
+  {
+    err=snd_pcm_hw_params_get_channels_min(hwparams,&minChannelsCapture);
+    err=snd_pcm_hw_params_get_channels_max(hwparams,&maxChannelsCapture);
+    err = snd_pcm_hw_params_set_channels ( handle, hwparams, minChannelsCapture);
+    if(!alsaErrorHandler(err,"Channels count not correct; " )) return false;
+  }
+  else
+  {
+
+    err=snd_pcm_hw_params_get_channels_min(hwparams,&minChannelsPlayback);
+    err=snd_pcm_hw_params_get_channels_max(hwparams,&maxChannelsPlayback);
+    err = snd_pcm_hw_params_set_channels ( handle, hwparams, 2); //allways stereo output
+    if(!alsaErrorHandler(err,"Channels count not correct; " ))
+    {
+      return false;
+    }
+  }
+
+  err = snd_pcm_hw_params_set_rate ( handle, hwparams, sampleRate, 0 );
+  if(!alsaErrorHandler(err,QString("Samplerate %1 not available").arg(sampleRate))) return false;
+
+  if(isCapture)
+  {
+    err = snd_pcm_hw_params_set_period_size_near ( handle, hwparams, &capturePeriodSize, &dir );
+    if(!alsaErrorHandler(err,QString("Unable to set period size %1 for capture").arg(capturePeriodSize))) return false;
+    err = snd_pcm_hw_params_set_buffer_size_near ( handle, hwparams, &captureBufferSize );
+    if(!alsaErrorHandler(err,QString("Unable to set buffersize %1 for capture").arg(captureBufferSize))) return false;
+  }
+  else
+  {
+    err = snd_pcm_hw_params_set_period_size_near ( handle, hwparams, &playbackPeriodSize, &dir );
+    if(!alsaErrorHandler(err,QString("Unable to set period size %1 for playback").arg(playbackPeriodSize))) return false;
+    err = snd_pcm_hw_params_set_buffer_size_near ( handle, hwparams, &playbackBufferSize );
+    if(!alsaErrorHandler(err,QString("Unable to set buffersize %1 for playback").arg(playbackBufferSize))) return false;
+  }
+  err = snd_pcm_hw_params ( handle, hwparams );
+  if(isCapture)
+  {
+    if(!alsaErrorHandler(err,QString("Unable to set hw params for capture:"))) return false;
+  }
+  else
+  {
+    if(!alsaErrorHandler(err,QString("Unable to set hw params for playback:"))) return false;
+  }
+
+  /* Get the current swparams */
+  err = snd_pcm_sw_params_current ( handle, swparams );
+  if(!alsaErrorHandler(err,"Unable to determine current swparams")) return false;
+  err = snd_pcm_sw_params_set_start_threshold ( handle, swparams, 128);
+  if(!alsaErrorHandler(err,"Unable to set start threshold mode")) return false;
+  /* Write the parameters to the record/playback device */
+  err = snd_pcm_sw_params ( handle, swparams );
+  if(!alsaErrorHandler(err,"Unable to set sw params for output")) return false;
+  if(minChannelsCapture==STEREOCHANNEL) isStereo=true;
+  return true;
+}
+
+bool soundAlsa::alsaErrorHandler(int err,QString info)
+{
+  if(err<0)
+  {
+    errorHandler(info,QString ( snd_strerror ( err )));
+    return false;
+  }
+  return true;
+}
+
+
+void getCardList(QStringList &alsaInputList, QStringList &alsaOutputList)
+{
+  bool isOutput,isInput;
+  QString deviceName;
+  QString deviceDescription;
+  void **hints, **n;
+  char *name, *descr,  *io;
+
+  alsaInputList.clear();
+  alsaOutputList.clear();
+
+
+  if (snd_device_name_hint(-1, "pcm", &hints) < 0)  return;
+  n = hints;
+  while (*n != NULL)
+  {
+    isInput=isOutput=true;
+    io    = snd_device_name_get_hint(*n, "IOID");
+    if(io!=NULL)
+    {
+      if (strcmp(io, "Input") == 0) isOutput=false;
+      if (strcmp(io, "Output") == 0) isInput=false;
+    }
+    name   = snd_device_name_get_hint(*n, "NAME");
+    descr  = snd_device_name_get_hint(*n, "DESC");
+    deviceName=QString(name);
+    if (descr!=NULL)
+    {
+      deviceDescription=QString(descr).split("\n").at(0);
+    }
+
+    if(
+       !deviceName.contains("surround",Qt::CaseInsensitive)
+       && !deviceName.contains("dmix",Qt::CaseInsensitive)
+       && !deviceName.contains("front",Qt::CaseInsensitive)
+       && !deviceName.contains("plughw",Qt::CaseInsensitive)
+       && !deviceName.contains("null",Qt::CaseInsensitive)
+       && !deviceName.contains("hdmi",Qt::CaseInsensitive)
+       && !deviceName.contains("sysdefault",Qt::CaseInsensitive)
+       && !deviceName.contains("dsnoop",Qt::CaseInsensitive)
+
+
+       )
+    {
+      if(isInput)  alsaInputList.append(deviceName + " -- " +deviceDescription);
+      if(isOutput) alsaOutputList.append(deviceName+ " -- " +deviceDescription);
+    }
+
+    if (name != NULL)  free(name);
+    if (descr != NULL) free(descr);
+    if (io != NULL)    free(io);
+    n++;
+  }
+  snd_device_name_free_hint(hints);
+}
+
diff --git a/qsstv/sound/soundalsa.h b/qsstv/sound/soundalsa.h
new file mode 100644
index 0000000..0dd6f5c
--- /dev/null
+++ b/qsstv/sound/soundalsa.h
@@ -0,0 +1,44 @@
+#ifndef SOUNDALSA_H
+#define SOUNDALSA_H
+
+
+#include "soundbase.h"
+#include <alsa/asoundlib.h>
+
+void getCardList(QStringList &alsaInputList, QStringList &alsaOutputList);
+
+class soundAlsa:public soundBase
+{
+
+public:
+  soundAlsa();
+  ~soundAlsa();
+  bool init(int samplerate);
+  void prepareCapture();
+  void preparePlayback();
+  int read(int &countAvailable);
+  int write(uint numFrames);
+
+protected:
+  void flushCapture();
+  void flushPlayback();
+  void closeDevices();
+
+private:
+  bool setupSoundParams(bool isCapture);
+  bool alsaErrorHandler(int err,QString Info);
+  snd_pcm_uframes_t playbackPeriodSize;
+  snd_pcm_uframes_t playbackBufferSize;
+  snd_pcm_uframes_t capturePeriodSize;
+  snd_pcm_uframes_t captureBufferSize;
+  snd_pcm_hw_params_t *hwparams;
+  snd_pcm_sw_params_t *swparams;
+  snd_pcm_t      *playbackHandle;
+  snd_pcm_t      *captureHandle;
+  unsigned int minChannelsCapture;
+  unsigned int maxChannelsCapture;
+  unsigned int minChannelsPlayback;
+  unsigned int maxChannelsPlayback;
+};
+
+#endif // SOUNDALSA_H
diff --git a/qsstv/sound/soundbase.cpp b/qsstv/sound/soundbase.cpp
new file mode 100644
index 0000000..96b9f41
--- /dev/null
+++ b/qsstv/sound/soundbase.cpp
@@ -0,0 +1,431 @@
+#include "soundbase.h"
+#include "logging.h"
+#include "configparams.h"
+#include "arraydumper.h"
+
+#include <QDebug>
+#include <QApplication>
+#include <unistd.h>
+#include <time.h>
+#include <sys/time.h>
+
+
+
+const QString captureStateStr[soundBase::CPEND+1]=
+{
+  "Capture Init",
+  "Capture Starting",
+  "Capture Running",
+  "Capture Calibrate Starting",
+  "Capture Calibrate Wait",
+  "Capture Calibrate",
+  "Capture End"
+};
+
+
+const QString playbackStateStr[soundBase::PBEND+1]=
+{
+  "Playback Init",
+  "Playback Starting",
+  "Playback Running",
+  "Playback Calibrate 1",
+  "Playback Calibrate 2",
+  "Playback End"
+};
+
+
+
+soundBase::soundBase(QObject *parent) : QThread(parent)
+{
+  captureState=CPINIT;
+  playbackState=PBINIT;
+  downsampleFilterPtr=new downsampleFilter(DOWNSAMPLESIZE,true);
+}
+
+
+void soundBase::run()
+{
+  stopThread=false;
+  unsigned int delay=0;  //todo check use of delay
+  while(!stopThread)
+  {
+    if((captureState==CPINIT) &&   (playbackState==PBINIT))
+      {
+        msleep(100);
+        continue;
+      }
+    switch (captureState)
+    {
+      case CPINIT:
+      break;
+      case CPSTARTING:
+        prepareCapture();
+        flushCapture();
+        rxBuffer.reset(); //clear the rxBuffer
+        rxVolumeBuffer.reset();
+        switchCaptureState(CPRUNNING);
+      break;
+      case CPRUNNING:
+        if (capture()==0) msleep(1);
+      break;
+      case CPCALIBRATESTART:
+        prepareCapture();
+        flushCapture();
+        switchCaptureState(CPCALIBRATEWAIT);
+      break;
+      case CPCALIBRATEWAIT:
+        if(captureCalibration(true)==0) msleep(0);
+      break;
+      case CPCALIBRATE:
+        if(captureCalibration(false)==0) msleep(0);
+      break;
+      case CPEND:
+        switchCaptureState(CPINIT);
+      break;
+    }
+    switch(playbackState)
+    {
+      case PBINIT:
+      break;
+      case PBSTARTING:
+        preparePlayback();
+        flushPlayback();
+        prebuf=true;
+        if (play()==0) msleep(10);
+        else
+        {
+          prebuf=false;
+          switchPlaybackState(PBRUNNING);
+          addToLog("playback started",LOGPERFORM);
+        }
+      break;
+      case PBRUNNING:
+        if (play()==0)
+        {
+          addToLog(QString("playback stopped: delay=%1").arg(delay),LOGPERFORM);
+          msleep(delay);
+          waveOut.close();
+          addToLog("playback stopped",LOGPERFORM);
+          switchPlaybackState(PBINIT);
+        }
+        msleep(0);
+      break;
+      case PBCALIBRATESTART:
+        {
+          preparePlayback();
+          flushPlayback();
+          switchPlaybackState(PBCALIBRATEWAIT);
+        }
+      break;
+      case PBCALIBRATEWAIT:
+        {
+          if(playbackCalibration(true)==0)
+            {
+              msleep(0);
+            }
+        }
+      break;
+      case PBCALIBRATE:
+        {
+          if(playbackCalibration(false)==0)
+            {
+              msleep(0);
+            }
+        }
+      break;
+      case PBEND:
+        switchPlaybackState(PBINIT);
+      break;
+    }
+  }
+}
+
+int soundBase::capture()
+{
+  int count=0;
+  if(rxBuffer.spaceLeft()<RXSTRIPE) return 0;
+  if(soundRoutingInput==SNDINFROMFILE)
+  {
+    count=waveIn.read((qint16*)tempRXBuffer,DOWNSAMPLESIZE);
+    //delay to give realtime feeling
+    if(count<0)
+    {
+      // we have an error in reading the wav file
+      waveIn.close();
+      switchCaptureState(CPINIT);
+    }
+    else if(count==0)
+    {
+      switchCaptureState(CPEND);
+    }
+//    msleep((1000*count)/sampleRate);
+    msleep((100*count)/sampleRate);
+  }
+  else if(soundDriverOK)
+  {
+    // read from soundcard
+    count=read(countAvailable);
+    if(count==0) return 0;
+    if(count !=DOWNSAMPLESIZE)
+    {
+      switchCaptureState(CPINIT);
+    }
+  }
+  downsampleFilterPtr->downSample4(tempRXBuffer);
+  volume=downsampleFilterPtr->avgVolumeDb;
+  rxBuffer.putNoCheck(downsampleFilterPtr->filteredDataPtr(),RXSTRIPE);
+  rxVolumeBuffer.putNoCheck(downsampleFilterPtr->getVolumePtr(),RXSTRIPE);
+  return count;
+}
+
+int soundBase::captureCalibration(bool leadIn)
+{
+  int count;
+  count=read(countAvailable);
+
+  if(count==0) return 0;
+  if(leadIn)
+  {
+    leadInCounter++;
+    if(leadInCounter==CALIBRATIONLEADIN)
+    {
+      stopwatch.start();
+      mutex.lock();
+      clock_gettime(CLOCK_MONOTONIC,&ts);
+      ustartcalibrationTime=(double)ts.tv_sec +(double)ts.tv_nsec / 1000000000.0;
+      calibrationFrames=0;
+      mutex.unlock();
+      switchCaptureState(CPCALIBRATE);
+    }
+  }
+  else
+  {
+    mutex.lock();
+    calibrationFrames++;
+    calibrationTime=stopwatch.elapsed();
+    clock_gettime(CLOCK_MONOTONIC,&ts);
+    ucalibrationTime=(double)ts.tv_sec +(double)ts.tv_nsec / 1000000000.0 -ustartcalibrationTime;
+    mutex.unlock();
+    //logFilePtr->addToAux(QString("%1\t%2\t%3").arg(countAvailable).arg(calibrationFrames).arg(calibrationTime) );
+  }
+  addToLog(QString("read report count:%1 available %2 elapsed qtime %3, time: %4").arg(count).arg(countAvailable).arg(calibrationTime).arg(ucalibrationTime),LOGSOUND);
+  return count;
+}
+
+bool soundBase::calibrate(bool isCapture)
+{
+  if (!soundDriverOK) return false;
+  switchCaptureState(CPINIT);
+  switchPlaybackState(PBINIT);
+  calibrationFrames=0;
+  calibrationTime=0;
+  ucalibrationTime=0;
+  leadInCounter=0;
+  if (!isRunning()) start();
+  if (isCapture)
+  {
+    switchCaptureState(CPCALIBRATESTART);
+  }
+  else
+  {
+    txBuffer.fill(0);
+    switchPlaybackState(PBCALIBRATESTART);
+  }
+  return true;
+}
+
+int soundBase::playbackCalibration(bool leadIn)
+{
+  int count;
+//  count=write(DOWNSAMPLESIZE);
+  count=write(CALIBRATIONSIZE);  // debug joma
+  addToLog(QString("calib count %1").arg(count),LOGCALIB);
+  if(leadIn)
+  {
+    leadInCounter++;
+    if(leadInCounter==CALIBRATIONLEADIN)
+    {
+//      stopwatch.start();
+      mutex.lock();
+      clock_gettime(CLOCK_MONOTONIC,&ts);
+      ustartcalibrationTime=(double)ts.tv_sec +(double)ts.tv_nsec / 1000000000.0;
+      addToLog(QString("calib start time %1").arg(ustartcalibrationTime),LOGCALIB);
+      calibrationFrames=0;
+      mutex.unlock();
+      switchPlaybackState(PBCALIBRATE);
+    }
+  }
+  else
+  {
+    mutex.lock();
+    calibrationFrames++;
+    clock_gettime(CLOCK_MONOTONIC,&ts);
+    ucalibrationTime=(double)ts.tv_sec +(double)ts.tv_nsec / 1000000000.0 -ustartcalibrationTime;
+    mutex.unlock();
+//    addToLog(QString("calib time %1 frames %2").arg(ucalibrationTime).arg(calibrationFrames),LOGCALIB);
+    //logFilePtr->addToAux(QString("%1\t%2\t%3").arg(countAvailable).arg(calibrationFrames).arg(calibrationTime) );
+  }
+  return count;
+}
+
+bool soundBase::calibrationCount(unsigned int &frames, double &elapsedTime)
+{
+  mutex.lock();
+  frames=calibrationFrames;
+  elapsedTime=ucalibrationTime;
+  mutex.unlock();
+  if(frames==prevFrames) return false;
+  prevFrames=frames;
+//  addToLog(QString("calib ok time %1 frames %2").arg(elapsedTime).arg(frames),LOGCALIB);
+  return true;
+}
+
+
+void soundBase::idleTX()
+{
+  waveOut.closeFile();
+  waveIn.closeFile();
+  playbackState=PBINIT;
+}
+
+void soundBase::idleRX()
+{
+  waveOut.closeFile();
+  waveIn.closeFile();
+  captureState=CPINIT;
+}
+
+
+void soundBase::stopSoundThread()
+{
+  idleRX();
+  idleTX();
+  stopThread=true;
+  while(isRunning())
+  {
+    QApplication::processEvents();
+  }
+  closeDevices();
+}
+
+
+bool soundBase::startCapture()
+{
+  switchPlaybackState(PBINIT);
+  soundIOPtr->rxBuffer.reset();
+  soundIOPtr->rxVolumeBuffer.reset();
+  downsampleFilterPtr->init();
+  switch(soundRoutingInput)
+  {
+    case SNDINFROMFILE:
+      if(!waveIn.openFileForRead("",true))
+      {
+        errorHandler("File not opened","");
+        return false;
+      }
+    break;
+    case SNDINCARDTOFILE:
+      {
+        if(!soundDriverOK)
+          {
+            errorHandler("No valid sound device (see configuration)","");
+            return false;
+          }
+        if(!waveOut.openFileForWrite("",true,true)) // always output stereo
+        {
+          errorHandler("File not opened","");
+          return false;
+        }
+      }
+    break;
+    case SNDINCARD:
+      if(!soundDriverOK)
+        {
+          errorHandler("No valid sound device (see configuration)","");
+          return false;
+        }
+    break;
+  }
+  switchCaptureState(CPSTARTING);
+  return true;
+}
+
+int soundBase::play()
+{
+  unsigned int numFrames;
+  int framesWritten;
+  if(prebuf)
+    {
+      if(txBuffer.count()<(DOWNSAMPLESIZE*8))
+        {
+          return 0;
+        }
+    }
+  if((numFrames=txBuffer.count())>=DOWNSAMPLESIZE) numFrames=DOWNSAMPLESIZE;
+  if(numFrames>0)
+    {
+      framesWritten=0;
+    }
+  if(soundRoutingOutput==SNDOUTTOFILE)  // output the wav-file
+  {
+
+    if(storedFrames<=(ulong)recordingSize*1048576L)
+    {
+      waveOut.write((quint16*)txBuffer.readPointer(),numFrames,true); //always stereo
+      storedFrames+=numFrames;
+    }
+  }
+  txBuffer.copyNoCheck(tempTXBuffer,numFrames);
+  addToLog(QString("frames to write: %1 at %2 buffered:%3").arg(numFrames).arg(txBuffer.getReadIndex()).arg(txBuffer.count()),LOGSOUND);
+  framesWritten=write(numFrames);
+  addToLog(QString("frames written: %1").arg(framesWritten),LOGSOUND);
+  if(framesWritten<0)
+    {
+      addToLog("Sound write error",LOGSOUND);
+    }
+  return numFrames;
+}
+
+bool soundBase::startPlayback()
+{
+  switchCaptureState(CPINIT);
+  if(!soundDriverOK)
+    {
+      errorHandler("No valid sound device (see configuration)","");
+      return false;
+    }
+  storedFrames=0;
+  soundIOPtr->txBuffer.reset();
+  if(soundRoutingOutput==SNDOUTTOFILE)
+  {
+
+    if(!waveOut.openFileForWrite("",true,true)) // indicate stereo
+    {
+      errorHandler("File not opened","");
+      return false;
+    }
+  }
+  playbackState=PBSTARTING;
+
+  addToLog(QString("start playback, txbuffercount: %1").arg(txBuffer.count()),LOGSOUND);
+  return true;
+}
+
+
+void soundBase::errorHandler(QString title, QString info)
+{
+  addToLog(title+" "+info,LOGSOUND);
+  lastErrorStr=title+" "+info;
+}
+
+void soundBase::switchCaptureState(ecaptureState cs)
+{
+  addToLog(QString("Switching from captureState %1 to %2").arg(captureStateStr[captureState]).arg(captureStateStr[cs]),LOGSOUND);
+  captureState=cs;
+}
+
+void soundBase::switchPlaybackState(eplaybackState ps)
+{
+  addToLog(QString("Switching from playbackState %1 to %2").arg(playbackStateStr[playbackState]).arg(playbackStateStr[ps]),LOGSOUND);
+  playbackState=ps;
+}
diff --git a/qsstv/sound/soundbase.h b/qsstv/sound/soundbase.h
new file mode 100644
index 0000000..07f9e80
--- /dev/null
+++ b/qsstv/sound/soundbase.h
@@ -0,0 +1,120 @@
+#ifndef SOUNDBASE_H
+#define SOUNDBASE_H
+
+#include "appglobal.h"
+#include "wavio.h"
+#include "buffermanag.h"
+#include "downsamplefilter.h"
+
+
+#include <QThread>
+#include <QMutex>
+
+#define BYTESPOWER 18
+
+
+//WWV WWVH             2500.0, 5000.0, 10000.0
+
+//·      GBR                           60.0 kHz
+
+//·      RWM                          4996.0, 9996.0, 14996.0
+
+//·      CHU                            7335.0
+
+
+
+#define PERIODSIZE (DOWNSAMPLESIZE)
+#define BUFFERSIZE (8*DOWNSAMPLESIZE*2)
+#define CALIBRATIONSIZE (PERIODSIZE)
+#define CALIBRATIONLEADIN 20
+
+
+class soundBase : public QThread
+{
+  Q_OBJECT
+
+public:
+  enum edataSrc{SNDINCARD,SNDINFROMFILE,SNDINCARDTOFILE};
+  enum edataDst{SNDOUTCARD,SNDOUTTOFILE};
+  enum eplaybackState{PBINIT,PBSTARTING,PBRUNNING,PBCALIBRATESTART,PBCALIBRATEWAIT,PBCALIBRATE,PBEND};
+  enum ecaptureState{CPINIT,CPSTARTING,CPRUNNING,CPCALIBRATESTART,CPCALIBRATEWAIT,CPCALIBRATE,CPEND};
+
+  explicit soundBase(QObject *parent = 0);
+  virtual bool init(int samplerate)=0;
+  void run();
+  void idleRX();
+  void idleTX();
+  void stopSoundThread();
+  virtual void getCardList() {;}
+
+  bool startCapture();
+  bool startPlayback();
+  buffer<FILTERPARAMTYPE,BYTESPOWER> rxBuffer;
+  buffer<unsigned int,BYTESPOWER> rxVolumeBuffer;
+  buffer<SOUNDFRAME,16> txBuffer;
+  double getVolumeDb(){return volume;}
+  uint *getVolumePtr() {return downsampleFilterPtr->getVolumePtr();}
+  const QString getLastError() { return lastErrorStr;}
+  bool isPlaying() {return playbackState!=PBINIT;}
+  bool isCapturing() {return captureState!=CPINIT;}
+
+  bool calibrate(bool isCapture);
+  bool calibrationCount(unsigned int &frames, double &elapsedTime);
+  int countAvailable;
+signals:
+
+public slots:
+
+protected:
+  bool soundDriverOK;
+  bool isStereo;
+  int capture();
+  int play();
+
+  virtual int read(int &countAvailable)=0;
+  virtual int write(uint numFrames)=0;
+  virtual void flushCapture()=0;
+  virtual void flushPlayback()=0;
+  virtual void prepareCapture() {;}
+  virtual void preparePlayback() {;}
+  virtual void closeDevices()=0;
+
+
+  int sampleRate;
+  qint16 tempRXBuffer[DOWNSAMPLESIZE*2]; // in some cases the hardware interface is stereo
+  quint32 tempTXBuffer[DOWNSAMPLESIZE];
+  bool stopThread;
+  eplaybackState playbackState;
+  ecaptureState  captureState;
+
+
+  wavIO waveIn;
+  wavIO waveOut;
+  void errorHandler(QString title,QString info);
+  void switchCaptureState(ecaptureState cs);
+  void switchPlaybackState(eplaybackState ps);
+
+
+private:
+  downsampleFilter *downsampleFilterPtr;
+  double volume;
+//  uint intVolume;
+  int captureCalibration(bool leadIn);
+  int playbackCalibration(bool leadIn);
+  QMutex mutex;
+  QTime stopwatch;
+  unsigned int calibrationFrames;
+  unsigned int leadInCounter;
+  int calibrationTime;
+  double ucalibrationTime;
+  double ustartcalibrationTime;
+  struct timespec ts;
+  QString lastErrorStr;
+  quint64 storedFrames;
+  bool prebuf;
+  unsigned int prevFrames;
+
+
+};
+
+#endif // SOUNDBASE_H
diff --git a/qsstv/sound/soundcontrol.cpp b/qsstv/sound/soundcontrol.cpp
deleted file mode 100644
index 42a19f8..0000000
--- a/qsstv/sound/soundcontrol.cpp
+++ /dev/null
@@ -1,120 +0,0 @@
-/**************************************************************************
-*   Copyright (C) 2000-2012 by Johan Maes                                 *
-*   on4qz at telenet.be                                                      *
-*   http://users.telenet.be/on4qz                                         *
-*                                                                         *
-*   This program is free software; you can redistribute it and/or modify  *
-*   it under the terms of the GNU General Public License as published by  *
-*   the Free Software Foundation; either version 2 of the License, or     *
-*   (at your option) any later version.                                   *
-*                                                                         *
-*   This program is distributed in the hope that it will be useful,       *
-*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
-*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
-*   GNU General Public License for more details.                          *
-*                                                                         *
-*   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.,                                       *
-*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
-***************************************************************************/
-#include "soundcontrol.h"
-#include "ui_soundcontrol.h"
-#include "configparams.h"
-#include "utils/supportfunctions.h"
-#include "soundio.h"
-#include <QSettings>
-
-soundControl::soundControl(QWidget *parent) :
-  QWidget(parent),
-  ui(new Ui::soundControl)
-{
-  QStringList *inputPCMList, *outputPCMList;
-  ui->setupUi(this);
-  soundIOPtr->listCards(); //get input devices
-  inputPCMList=soundIOPtr->getPCMNamList(true);
-  ui->inputPCMNameComboBox->addItems(*inputPCMList);
-  outputPCMList=soundIOPtr->getPCMNamList(false);
-  ui->outputPCMNameComboBox->addItems(*outputPCMList);
-  changed=false;
-}
-
-
-soundControl::~soundControl()
-{
-  delete ui;
-}
-
-void soundControl::readSettings()
-{
-  QSettings qSettings;
-  qSettings.beginGroup("Sound");
-  rxClock=qSettings.value("rxclock",BASESAMPLERATE).toDouble();
-  txClock=qSettings.value("txclock",BASESAMPLERATE).toDouble();
-  if(fabs(1-rxClock/BASESAMPLERATE)>0.002) rxClock=BASESAMPLERATE;
-  if(fabs(1-txClock/BASESAMPLERATE)>0.002) txClock=BASESAMPLERATE;
-  inputAudioDeviceIndex=qSettings.value("inputAudioDeviceIndex",0).toInt();
-  outputAudioDeviceIndex=qSettings.value("outputAudioDeviceIndex",0).toInt();
-  soundIOPtr->soundRoutingInput=  (soundIO::edataSrc)qSettings.value("soundRoutingInput",  0 ).toInt();
-  soundIOPtr->soundRoutingOutput= (soundIO::edataDst)qSettings.value("soundRoutingOutput", 0 ).toInt();
-  soundIOPtr->recordingSize= qSettings.value("recordingSize", 100 ).toInt();
-  qSettings.endGroup();
-  setParams();
-}
-
-void soundControl::writeSettings()
-{
-  getParams();
-  QSettings qSettings;
-  qSettings.beginGroup("Sound");
-  qSettings.setValue("rxclock",rxClock);
-  qSettings.setValue("txclock",txClock);
-  qSettings.setValue("inputAudioDeviceIndex",inputAudioDeviceIndex);
-  qSettings.setValue("outputAudioDeviceIndex",outputAudioDeviceIndex);
-  qSettings.setValue ("soundRoutingInput", soundIOPtr->soundRoutingInput );
-  qSettings.setValue ("soundRoutingOutput",soundIOPtr->soundRoutingOutput );
-  qSettings.setValue ("recordingSize",soundIOPtr->recordingSize );
-  qSettings.endGroup();
-}
-
-
-void soundControl::setParams()
-{
-  setValue(rxClock,ui->inputClockLineEdit,9);
-  setValue(txClock,ui->outputClockLineEdit,9);
-  setIndex(inputAudioDeviceIndex,ui->inputPCMNameComboBox);
-  setIndex(outputAudioDeviceIndex,ui->outputPCMNameComboBox);
-  soundIOPtr->inputAudioDevice=ui->inputPCMNameComboBox->currentText();
-  soundIOPtr->outputAudioDevice=ui->outputPCMNameComboBox->currentText();
-
-  if(soundIOPtr->soundRoutingInput==soundIO::SNDINCARD) ui->inFromCard->setChecked(true);
-  else if (soundIOPtr->soundRoutingInput==soundIO::SNDINFILE) ui->inFromFile->setChecked(true);
-  else ui->inRecordFromCard->setChecked(true);
-
-  if(soundIOPtr->soundRoutingOutput==soundIO::SNDOUTCARD) ui->outToCard->setChecked(true);
-  else ui->outRecord->setChecked(true);
-  setValue(soundIOPtr->recordingSize,ui->mbSpinBox);
-}
-
-void soundControl::getParams()
-{
-  changed=false;
-  int savedInputIdx=inputAudioDeviceIndex;
-  int savedOutputIdx=outputAudioDeviceIndex;
-  getValue(rxClock,ui->inputClockLineEdit);
-  getValue(txClock,ui->inputClockLineEdit);
-
-  getIndex(inputAudioDeviceIndex,ui->inputPCMNameComboBox);
-  getIndex(outputAudioDeviceIndex,ui->outputPCMNameComboBox);
-
-  if (ui->inFromCard->isChecked()) soundIOPtr->soundRoutingInput=soundIO::SNDINCARD;
-  else if(ui->inFromFile->isChecked()) soundIOPtr->soundRoutingInput=soundIO::SNDINFILE;
-  else soundIOPtr->soundRoutingInput=soundIO::SNDINCARDTOFILE;
-
-  if (ui->outToCard->isChecked()) soundIOPtr->soundRoutingOutput=soundIO::SNDOUTCARD;
-  else soundIOPtr->soundRoutingOutput=soundIO::SNDOUTTOFILE;
-  getValue(soundIOPtr->recordingSize,ui->mbSpinBox);
-  if(savedInputIdx!=inputAudioDeviceIndex) changed=true;
-  if(savedOutputIdx!=outputAudioDeviceIndex) changed=true;
-}
-
diff --git a/qsstv/sound/soundcontrol.h b/qsstv/sound/soundcontrol.h
deleted file mode 100644
index a0a2cec..0000000
--- a/qsstv/sound/soundcontrol.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef SOUNDCONTROL_H
-#define SOUNDCONTROL_H
-
-#include <QWidget>
-
-namespace Ui {
-  class soundControl;
-  }
-
-class soundControl : public QWidget
-{
-  Q_OBJECT
-  
-public:
-  explicit soundControl(QWidget *parent = 0);
-  ~soundControl();
-  void readSettings();
-  void writeSettings();
-  void setParams();
-  bool needsRestart() { return changed;}
-
-
-private:
-  Ui::soundControl *ui;
-  int inputAudioDeviceIndex;
-  int outputAudioDeviceIndex;
-  bool changed;
-  void getParams();
-};
-
-#endif // SOUNDCONTROL_H
diff --git a/qsstv/sound/soundio.cpp b/qsstv/sound/soundio.cpp
deleted file mode 100644
index e8ac009..0000000
--- a/qsstv/sound/soundio.cpp
+++ /dev/null
@@ -1,855 +0,0 @@
-/**************************************************************************
-*   Copyright (C) 2000-2012 by Johan Maes                                 *
-*   on4qz at telenet.be                                                      *
-*   http://users.telenet.be/on4qz                                         *
-*                                                                         *
-*   This program is free software; you can redistribute it and/or modify  *
-*   it under the terms of the GNU General Public License as published by  *
-*   the Free Software Foundation; either version 2 of the License, or     *
-*   (at your option) any later version.                                   *
-*                                                                         *
-*   This program is distributed in the hope that it will be useful,       *
-*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
-*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
-*   GNU General Public License for more details.                          *
-*                                                                         *
-*   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.,                                       *
-*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
-***************************************************************************/
-#include "soundio.h"
-#include "qsstvglobal.h"
-#include"soundcontrol.h"
-#include <QDebug>
-#include <QApplication>
-#include <stdio.h>
-#include <unistd.h>
-#include "utils/supportfunctions.h"
-//#include "scope/scopeview.h"
-#include <sys/time.h>
-#include <sys/timex.h>
-
-
-soundIO *soundIOPtr;
-
-
-static const unsigned int rates[] =
-{
-  5512,
-  8000,
-  11025,
-  16000,
-  22050,
-  32000,
-  44100,
-  48000,
-  64000,
-  88200,
-  96000,
-  176400,
-  192000,
-};
-
-
-soundIO::soundIO(int s)
-{
-  setSamplerate(s);
-  soundOK=false;
-
-}
-
-
-void soundIO::setSamplerate(int s)
-{
-  samplerate=s;
-}
-
-void  soundIO::run()
-{
-  unsigned int delay;
-  delay=((playbackBufferSize*1000)/samplerate);
-  abort=false;
-  playbackState=PBINIT;
-  captureState=CPINIT;
-  if(!soundOK) return;
-  while(!abort)
-    {
-      switch(playbackState)
-        {
-        case PBINIT:
-          txBuffer.reset();
-          detectedPlaybackState= PBINIT;
-        break;
-        case PBSTARTING:
-          if (play()==0) msleep(10);
-          else
-            {
-              playbackState=PBRUNNING;
-              addToLog("playback started",LOGPERFORM);
-            }
-          detectedPlaybackState= PBSTARTING;
-        break;
-        case PBRUNNING:
-          if (play()==0)
-            {
-               addToLog(QString("playback stopped: delay=%1").arg(delay),LOGPERFORM);
-               msleep(delay);
-               waveOut.close();
-               addToLog("playback stopped",LOGPERFORM);
-               emit playbackStopped();
-               playbackState=PBINIT;
-            }
-          detectedPlaybackState= PBRUNNING;
-        break;
-        case PBCALIBRATE1:
-          {
-            detectedPlaybackState= PBCALIBRATE1;
-            if (playbackCalibration()!=0)
-              {
-                playbackState=PBCALIBRATE2;
-              }
-          }
-        break;
-        case PBCALIBRATE2:
-          {
-            if (playbackCalibration()==0) break;
-            detectedPlaybackState= PBCALIBRATE2;
-          }
-          break;
-       }
-      switch(captureState)
-        {
-        case CPINIT:
-//          rxBuffer.reset();
-          detectedCaptureState=CPINIT;
-        break;
-        case CPSTARTING:
-          rxBuffer.reset(); //clear the rxBuffer
-          snd_pcm_prepare (captureHandle );
-          snd_pcm_start (captureHandle);
-          detectedCaptureState=CPSTARTING;
-          captureState=CPRUNNING;
-        break;
-        case CPRUNNING:
-          if (capture()==0) msleep(60);
-          detectedCaptureState=CPRUNNING;
-        break;
-        case CPCALIBRATE:
-          {
-            if (captureCalibration()==0) msleep(0);
-            detectedCaptureState= CPCALIBRATE;
-          }
-          break;
-        case CPEND:
-          msleep(1000);
-          captureState=CPINIT;
-         break;
-       }
-      if((captureState==CPINIT) &&(playbackState==PBINIT))   msleep(200);
-    }
-  abort=false;
-  playbackState=PBINIT;
-  captureState=CPINIT;
-}
-
-
-double soundIO::getPlaybackStartupTime()
-{
-  return (double)playbackBufferSize/BASESAMPLERATE;
-}
-
-
-
-/**
- * @brief play sound from txBuffer
- *
- * The sound is controlled by soundRoutingOutput (via configuration).
- * - SNDOUTCARD  sound to card only
- * - SNDOUTTOFILE sound to card and saved in wav file
- * - SNDOUTFILETOCARD sound from wav file to card
- *
- * @return number of frames sent.
- *
- * The readIndex must always be a multiple of 2*PERIODSIZE because we don't check the txBuffer for wrap-around.
- *
- */
-
-int soundIO::play()
-{
- unsigned int numFrames,restFrames;
- int framesWritten,error;
-  addToLog(QString("readIndex: %1,writeIndex: %2 count: %3").arg(txBuffer.getReadIndex()).arg(txBuffer.getWriteIndex()).arg(txBuffer.count()),LOGSOUND);
-  if(playbackState==PBSTARTING)
-    {
-      // prefill buffers to the max
-      if((numFrames=txBuffer.count())<playbackBufferSize) return 0;
-      addToLog(QString("start numFrame: %1").arg(numFrames),LOGSOUND);
-      numFrames=playbackBufferSize;
-    }
-  else
-    {
-      if((numFrames=txBuffer.count())>=(2*PERIODSIZE))
-        {
-          numFrames=2*PERIODSIZE;
-        }
-    }
-
-  if(soundRoutingOutput==SNDOUTTOFILE)
-    {
-      if(storedFrames<=(ulong)recordingSize*1048576L)
-        {
-          waveOut.write((quint16*)txBuffer.readPointer(),numFrames,isStereo);
-          storedFrames+=numFrames;
-//          msleep(10); // give some processingtime
-//          return numFrames;
-        }
-    }
-  restFrames=numFrames;
-  while(restFrames)
-    {
-      framesWritten =  snd_pcm_writei ( playbackHandle, txBuffer.readPointer(), restFrames);
-//      arrayDump(QString("sio %1").arg(frameCounter++),txBuffer.readPointer(),32,true);
-      if(framesWritten<0)
-        {
-          if ( framesWritten ==  -EAGAIN )
-            {
-              return -1;
-            }
-          else if ( framesWritten == -EPIPE )
-            {
-              /* underrun */
-              errorHandler(framesWritten,QString("Underrun recovery for %1").arg(numFrames));
-              error = snd_pcm_prepare (playbackHandle);
-              if ( error < 0 )
-                {
-                  errorHandler(framesWritten,"Can't recover from underrun, prepare failed");
-                  snd_pcm_drop (playbackHandle);
-                }
-            }
-          else
-            {
-              errorHandler(framesWritten,"Unhandled error in playback");
-              snd_pcm_drop (playbackHandle );
-            }
-        }
-      else
-        {
-          addToLog(QString("framesWritten:%1").arg(framesWritten),LOGSOUND);
-          txBuffer.skip(framesWritten);
-          if(restFrames!=numFrames)
-            {
-              addToLog(QString("restFrames: %1; framesWritten %2").arg(restFrames).arg(framesWritten),LOGSOUND);
-            }
-          msleep(10);
-          restFrames-=framesWritten;
-        }
-    }
-  return numFrames;
-}
-
-int soundIO::playbackCalibration()
-{
-  int numFrames,framesWritten;
-  if(playbackState==PBCALIBRATE1)
-    {
-      numFrames=playbackBufferSize;
-      framesWritten =  snd_pcm_writei ( playbackHandle, txBuffer.readPointer(), numFrames);
-      calibrationFrames=0;
-      return numFrames;
-    }
-  else
-    {
-      numFrames=1*PERIODSIZE;
-    }
-  framesWritten =  snd_pcm_writei ( playbackHandle, txBuffer.readPointer(), numFrames);
-  if(numFrames!=framesWritten)
-    {
-       framesWritten =  snd_pcm_writei ( playbackHandle, txBuffer.readPointer(), numFrames-framesWritten);
-    }
-  else
-    {
-
-    }
-  mutex.lock();
-  calibrationFrames+=1;
-  calibrationTime=stopwatch.elapsed();
-  if(calibrationFrames==CALIBRATIONLEADIN)
-    {
-      stopwatch.start();
-      addToLog("start calrx",LOGCAM);
-    }
-  mutex.unlock();
-  return numFrames;
-}
-
-/**
- * @brief capture sound to rxBuffer
- *
- * The sound recording is controlled by soundRoutingInput (via configuration).
- *
- * - SNDINCARD sound from card
- * - SNDINFILE sound from a wav file
- * - SNDINCARDTOFILE sound from card and recording to wav file
- *
- * @return number of frames recorded.
- */
-
-int soundIO::capture()
-{
-  int count;
-  QString debugStr;
-  if(rxBuffer.spaceLeft()<PERIODSIZE) return 0;
-  if(soundRoutingInput==SNDINFILE)
-    {
-      count=waveIn.read((quint32*)tempRXBuffer,PERIODSIZE);
-     //delay to give realtime feeling
-      msleep((100*count)/samplerate);
-      if(count<=0)
-        {
-          waveIn.close();
-          captureState=CPEND;
-          return 0;
-        }
-    }
-  else
-    {
-      count=snd_pcm_avail(captureHandle); // check for available frames
-//      addToLog(QString("countcheck %1 ").arg(count),LOGSOUND);
-
-      if(count>=PERIODSIZE)
-        {
-          count = snd_pcm_readi(captureHandle, tempRXBuffer,PERIODSIZE);
-        }
-      if ( count < 0 )
-        {
-          if ( count != -EAGAIN )
-            {
-              if ( count == -EPIPE )
-                {
-                  // Overrun
-                  snd_pcm_prepare (captureHandle );
-                  snd_pcm_start (captureHandle);
-                  qDebug()<< "Overrun";
-                }
-              else
-                {
-                  snd_pcm_drop (captureHandle );
-                  qDebug()<<"Overrun , reason: "<< count << "Stopping device";
-                }
-            }
-          addToLog("soundIO: sound eagain",LOGSOUND);
-          return 0;
-        }
-      if(count!=PERIODSIZE)
-        {
-          return 0;
-        }
-      else
-        {
-          if(soundRoutingInput==SNDINCARDTOFILE)
-            {
-              if(storedFrames<=(ulong)recordingSize*1048576L)
-                {
-                  addToLog(QString("writen %1 tofile").arg(count),LOGSOUND);
-                  waveOut.write((quint16*)tempRXBuffer,count,isStereo);
-                  storedFrames+=count;
-                }
-              else
-                {
-                  captureState=CPINIT;
-                }
-            }
-        }
-    }
-//  addToLog(QString("rxBuffercount: %1").arg(count),LOGSOUND);
-
-  if((isStereo) || (soundRoutingInput==SNDINFILE))
-    {
-      for(int i=0;i<count;i++)
-        {
-          tempRXBuffer[i]=tempRXBuffer[2*i];  // setup as mono channel
-        }
-     }
-  rxBuffer.putNoCheck(tempRXBuffer,count);
-//  addToLog(QString("in buffer count: %1").arg(rxBuffer.count()),LOGSOUND);
-  return count;
-}
-
-int soundIO::captureCalibration()
-{
-  int count;
-  addToLog("calibration",LOGSOUND);
-  count = snd_pcm_readi( captureHandle, tempRXBuffer,PERIODSIZE);
-//  addToLog(QString("calibration count: %1").arg(count),LOGSOUND);
-  if (count==PERIODSIZE)
-    {
-//      addToLog("calibration 2",LOGSOUND);
-      mutex.lock();
-      calibrationFrames++;
-      calibrationTime=stopwatch.elapsed();
-      if(calibrationFrames==CALIBRATIONLEADIN)
-        {
-          stopwatch.start();
-        }
-      mutex.unlock();
-    }
-  else if(count>=0)
-    {
-
-      count = snd_pcm_readi( captureHandle, tempRXBuffer,PERIODSIZE-count);
-      mutex.lock();
-      calibrationFrames++;
-      calibrationTime=stopwatch.elapsed();
-      mutex.unlock();
-
-    }
-  else
-    {
-      calibrationFrames=0; // restart calibration
-      qDebug() << "restarting calibration";
-      if ( count != -EAGAIN )
-        {
-          if ( count == -EPIPE )
-            {
-              // Overrun
-              snd_pcm_prepare (captureHandle );
-              snd_pcm_start (captureHandle);
-              qDebug() << "Overrun";
-            }
-          else
-            {
-              snd_pcm_drop (captureHandle );
-              qDebug()<<"Overrun , reason: "<< count << "Stopping device";
-            }
-        }
-      addToLog("soundIO: sound eagain",LOGSOUND);
-      return 0;
-    }
-
-  return count;
-}
-
-/**
- * @brief Initialisation of the soundcard hardware in full-duplex
- *
- * This function must be called before using the soundcard and after the configuration has been loaded
- *@return bool true if call was succesfull
- */
-
-bool soundIO::init()
-{
-  int err;
-  QString tempDevice;
-  lastError.clear();
-  if(soundOK)
-    {
-     // we have to stop thread first
-      stopAndWait();
-      snd_pcm_close(playbackHandle);
-      snd_pcm_close(captureHandle);
-    }
-  soundOK=false;
-  tempDevice=outputAudioDevice.left(outputAudioDevice.indexOf(" "));
-  err = snd_pcm_open(&playbackHandle,tempDevice.toLatin1().data(), SND_PCM_STREAM_PLAYBACK,0); //open in blocking mode
-  if(!errorHandler(err,"Unable to open "+outputAudioDevice)) return false;
-  tempDevice=inputAudioDevice.left(inputAudioDevice.indexOf(" "));
-  err = snd_pcm_open(&captureHandle,tempDevice.toLatin1().data(), SND_PCM_STREAM_CAPTURE, 0);
-  if(!errorHandler(err,"Unable to open "+inputAudioDevice)) return false;
-  snd_pcm_hw_params_malloc ( &hwparams );
-  snd_pcm_sw_params_malloc ( &swparams );
-  if(setupSoundParams(true))
-    {
-      if(setupSoundParams(false)) soundOK=true;
-    }
-
-  snd_pcm_hw_params_free ( hwparams );
-  snd_pcm_sw_params_free ( swparams );
-   return soundOK;
-}
-
-bool soundIO::stoppedPlaying()
-{
-  if(playbackState==PBINIT)
-    {
-      return true;
-    }
-  else
-    {
-      return false;
-    }
-}
-
-bool soundIO::setupSoundParams(bool isCapture)
-{
-  int err;
-  int dir=0;
-  snd_pcm_t *handle;
-
-  playbackPeriodSize=PERIODSIZE;
-  playbackBufferSize=BUFFERSIZE;
-  capturePeriodSize=PERIODSIZE;
-  captureBufferSize=BUFFERSIZE;
-
-  if(isCapture) handle=captureHandle;
-  else handle=playbackHandle;
-
-  /* Choose all parameters */
-  err = snd_pcm_hw_params_any ( handle, hwparams );
-  if(!errorHandler(err,"Broken configuration : no configurations available")) return false;
-
-  /* Set the interleaved read/write format */
-  err = snd_pcm_hw_params_set_access ( handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED );
-  if(!errorHandler(err,"Access type not available : ")) return false;
-
-  /* Set the sample format */
-  err = snd_pcm_hw_params_set_format ( handle, hwparams, SND_PCM_FORMAT_S16_LE );
-  if(!errorHandler(err,"Sample format Float not available : ")) return false;
-  /* Set the count of channels */
-  if(isCapture)
-    {
-      err=snd_pcm_hw_params_get_channels_min(hwparams,&minChannelsCapture);
-      err=snd_pcm_hw_params_get_channels_max(hwparams,&maxChannelsCapture);
-      err = snd_pcm_hw_params_set_channels ( handle, hwparams, minChannelsCapture);
-      if(!errorHandler(err,"Channels count not correct; " )) return false;
-     }
-  else
-    {
-
-      err=snd_pcm_hw_params_get_channels_min(hwparams,&minChannelsPlayback);
-      err=snd_pcm_hw_params_get_channels_max(hwparams,&maxChannelsPlayback);
-      err = snd_pcm_hw_params_set_channels ( handle, hwparams, 2); //allways stereo output
-      if(!errorHandler(err,"Channels count not correct; " ))
-        {
-          return false;
-        }
-    }
-
-  err = snd_pcm_hw_params_set_rate ( handle, hwparams, samplerate, 0 );
-  if(!errorHandler(err,QString("Samplerate %1 not available").arg(samplerate))) return false;
-
-  if(isCapture)
-    {
-      err = snd_pcm_hw_params_set_period_size_near ( handle, hwparams, &capturePeriodSize, &dir );
-      if(!errorHandler(err,QString("Unable to set period size %1 for capture").arg(capturePeriodSize))) return false;
-      err = snd_pcm_hw_params_set_buffer_size_near ( handle, hwparams, &captureBufferSize );
-      if(!errorHandler(err,QString("Unable to set buffersize %1 for capture").arg(captureBufferSize))) return false;
-    }
-  else
-    {
-      err = snd_pcm_hw_params_set_period_size_near ( handle, hwparams, &playbackPeriodSize, &dir );
-      if(!errorHandler(err,QString("Unable to set period size %1 for playback").arg(playbackPeriodSize))) return false;
-      err = snd_pcm_hw_params_set_buffer_size_near ( handle, hwparams, &playbackBufferSize );
-      if(!errorHandler(err,QString("Unable to set buffersize %1 for playback").arg(playbackBufferSize))) return false;
-    }
-  err = snd_pcm_hw_params ( handle, hwparams );
-  if(isCapture)
-    {
-      if(!errorHandler(err,QString("Unable to set hw params for capture:"))) return false;
-    }
-  else
-    {
-      if(!errorHandler(err,QString("Unable to set hw params for playback:"))) return false;
-    }
-
-  /* Get the current swparams */
-  err = snd_pcm_sw_params_current ( handle, swparams );
-  if(!errorHandler(err,"Unable to determine current swparams")) return false;
-  err = snd_pcm_sw_params_set_start_threshold ( handle, swparams, 2048 );
-  if(!errorHandler(err,"Unable to set start threshold mode")) return false;
-   /* Write the parameters to the record/playback device */
-  err = snd_pcm_sw_params ( handle, swparams );
-  if(!errorHandler(err,"Unable to set sw params for output")) return false;
-  return true;
- }
-
-bool soundIO::listCards()
-{
-  int  err;
-  int  cardNum, totalCards;
-  char   str[64];
-  snd_ctl_card_info_t *cardInfo;
-  int      devNum;
-//  int totalDevices;
-  snd_pcm_info_t *pcmInfo;
-  snd_ctl_t *cardHandle;
-  inputPCMNameList << "default";
-  outputPCMNameList << "default";
-
-  // No cards found yet
-  totalCards = 0;
-
-  // Start with first card
-  cardNum = -1;
-
-  for (;;)
-    {
-
-      // Get next sound card's card number. When "cardNum" == -1, then ALSA fetches the first card
-      if ((err = snd_card_next(&cardNum)) < 0)
-        {
-          qDebug() << "Can't get the next card number:" << snd_strerror(err);
-          return false;
-        }
-
-      if (cardNum < 0) break; // No more cards? ALSA sets "cardNum" to -1 if so
-      sprintf(str, "hw:%i", cardNum);
-      if ((err = snd_ctl_open(&cardHandle, str, 0)) < 0)
-        {
-          qDebug() << "Can't open card "<< cardNum << snd_strerror(err);
-          continue;
-        }
-      // We need to get a snd_ctl_card_info_t. Just alloc it on the stack
-      snd_ctl_card_info_alloca(&cardInfo);
-
-      // Tell ALSA to fill in our snd_ctl_card_info_t with info about this card
-      if ((err = snd_ctl_card_info(cardHandle, cardInfo)) >= 0)
-        qDebug() << "Card " << cardNum << "name: " << snd_ctl_card_info_get_name(cardInfo);
-//      totalDevices = 0;
-      devNum = -1; // Start with the first wave device on this card
-      for (;;)
-        {
-          if ((err = snd_ctl_pcm_next_device(cardHandle, &devNum)) < 0)  // Get the number of the next wave device on this card
-            {
-              qDebug()<< "Can't get next wave device number: " << snd_strerror(err);
-              break;
-            }
-
-          // No more wave devices on this card? ALSA sets "devNum" to -1 if so.
-          // NOTE: It's possible that this sound card may have no wave devices on it
-          // at all, for example if it's only a MIDI card
-          if (devNum < 0) break;
-          // To get some info about the subdevices of this wave device (on the card), we need a
-          // snd_pcm_info_t, so let's allocate one on the stack
-          snd_pcm_info_alloca(&pcmInfo);
-          memset(pcmInfo, 0, snd_pcm_info_sizeof());
-
-          // Tell ALSA which device (number) we want info about
-          snd_pcm_info_set_device(pcmInfo, devNum);
-          // Get info on the wave outs of this device
-          getDevices(cardHandle,cardNum,devNum,pcmInfo, SND_PCM_STREAM_PLAYBACK);
-          getDevices(cardHandle,cardNum,devNum,pcmInfo, SND_PCM_STREAM_CAPTURE);
-        }
-      ++totalCards;
-      // Close the card's control interface after we're done with it
-      snd_ctl_close(cardHandle);
-//      qDebug() << "Found:" << totalDevices << " digital audio devices on card " <<  cardNum;
-    }
-
-//  qDebug() << "ALSA found cards" << totalCards;
-
-  // ALSA allocates some mem to load its config file when we call
-  // snd_card_next. Now that we're done getting the info, let's tell ALSA
-  // to unload the info and free up that mem
-  snd_config_update_free_global();
-  return true;
-}
-
-
-void soundIO::getDevices(snd_ctl_t *cardHandle,int cardNum,int devNum,snd_pcm_info_t *pcmInfo, snd_pcm_stream_t direction)
-{
-  int  err;
-  int i= -1;
-  int subDevCount = 1;
-  snd_pcm_info_set_stream(pcmInfo, direction);
-
-
-  // More subdevices?
-  while (++i < subDevCount)
-    {
-      // Tell ALSA to fill in our snd_pcm_info_t with info on this subdevice
-      snd_pcm_info_set_subdevice(pcmInfo, i);
-      if ((err = snd_ctl_pcm_info(cardHandle, pcmInfo)) < 0)
-        {
-//          qDebug() << QString("Can't get info for wave output subdevice hw:%1,%2,%3: %4").arg(cardNum).arg(devNum).arg(i).arg(snd_strerror(err));
-          continue;
-        }
-//      qDebug() << "PCM name" << snd_pcm_info_get_name(pcmInfo);
-      // Print out how many subdevices (once only)
-      if (!i)
-        {
-          subDevCount = snd_pcm_info_get_subdevices_count(pcmInfo);
-//          qDebug() << QString("Found %1 wave output subdevices on card %2").arg(subDevCount).arg(cardNum);
-        }
-
-      // NOTE: If there's only one subdevice, then the subdevice number is immaterial,
-      // and can be omitted when you specify the hardware name
-      if(subDevCount>1)
-        {
-//          qDebug()<< QString("hw:%1,%2,%3").arg(cardNum).arg(devNum).arg(i);
-          if(direction==SND_PCM_STREAM_CAPTURE)
-            {
-              inputPCMNameList << QString("hw:%1,%2,%3  %4").arg(cardNum).arg(devNum).arg(i).arg(snd_pcm_info_get_name(pcmInfo));
-            }
-
-          else
-            {
-              outputPCMNameList << QString("hw:%1,%2,%3  %4").arg(cardNum).arg(devNum).arg(i).arg(snd_pcm_info_get_name(pcmInfo));
-            }
-
-         }
-      else
-        {
-//          qDebug()<< QString("hw:%1,%2").arg(cardNum).arg(devNum);
-          if(direction==SND_PCM_STREAM_CAPTURE)
-            {
-              inputPCMNameList << QString("hw:%1,%2  %3").arg(cardNum).arg(devNum).arg(snd_pcm_info_get_name(pcmInfo));
-            }
-
-          else
-            {
-              outputPCMNameList << QString("hw:%1,%2  %3").arg(cardNum).arg(devNum).arg(snd_pcm_info_get_name(pcmInfo));
-           }
-        }
-
-    }
-
-}
-
-bool soundIO::errorHandler(int err,QString info)
-{
-  if(err<0)
-    {
-      lastError=info+ ": "+ QString ( snd_strerror ( err ) );
-      qDebug() << lastError;
-      addToLog(lastError,LOGALL);
-      return false;
-    }
-  return true;
-}
-
-void soundIO::errorHandler(QString info)
-{
-  lastError=info;
-  qDebug() << lastError;
-  addToLog(lastError,LOGALL);
-}
-
-
-
-bool soundIO::startCapture()
-{
-  playbackState=PBINIT;
-  if(!soundOK) return false;
-  switch(soundRoutingInput)
-    {
-      case SNDINCARD:
-      if(minChannelsCapture==1) isStereo=false; else isStereo=true;
-      break;
-      case SNDINFILE:
-      if(!waveIn.openFileForRead("",true))
-        {
-          errorHandler("File not opened");
-          return false;
-        }
-      if(waveIn.getNumberOfChannels()==1) isStereo=false; else isStereo=true;
-      break;
-      case SNDINCARDTOFILE:
-        {
-        if(minChannelsCapture==1) isStereo=false; else isStereo=true;
-          if(!waveOut.openFileForWrite("",true,isStereo))
-            {
-              errorHandler("File not opened");
-              return false;
-            }
-        }
-      break;
-    }
-  rxBuffer.reset();
-  captureState=CPSTARTING;
-  addToLog("start capturing",LOGSOUND);
-  return true;
-}
-
-bool soundIO::startPlayback()
-{
-  frameCounter=0;
-  captureState=CPINIT;
-  if(!soundOK) return false;
-  soundIOPtr->txBuffer.reset();
-
-  if(soundRoutingOutput==SNDOUTTOFILE)
-    {
-      if(!waveOut.openFileForWrite("",true,true)) // indicate stereo
-        {
-          errorHandler("File not opened");
-          return false;
-        }
-    }
-  playbackState=PBSTARTING;
-  snd_pcm_prepare (playbackHandle);
-  addToLog(QString("start playback, txbuffercount: %1").arg(txBuffer.count()),LOGSOUND);
-
-  return true;
-}
-
-bool soundIO::startCalibration(bool capture)
-{
-  captureState=CPINIT;
-  playbackState=PBINIT;
-  if(!soundOK) return false;
-  while(detectedCaptureState!=CPINIT)
-    {
-      qApp->processEvents();
-    };
-  while(detectedPlaybackState!=PBINIT)
-    {
-      qApp->processEvents();
-    };
-  calibrationFrames=0;
-  if(capture)
-    {
-     snd_pcm_prepare (captureHandle );
-     snd_pcm_start (captureHandle);
-     captureState=CPCALIBRATE;
-    }
-  else
-    {
-      txBuffer.fill(0);
-     //
-      snd_pcm_start (playbackHandle);
-      //snd_pcm_prepare (playbackHandle );
-      playbackState=PBCALIBRATE1;
-    }
-  return true;
-}
-
-void soundIO::idle()
-{
-  waveOut.close();
-  waveIn.closeFile();
-  captureState=CPINIT;
-  playbackState=PBINIT;
-}
-
-/**
- * @brief stopping soundio thread
- */
-
-void soundIO::stopAndWait()
-{
-  if(!soundOK) return;
-  waveOut.write(NULL,0,false);
-  abort=true;
-  while(abort)
-    {
-      qApp->processEvents();
-    }
-}
-
-
-int soundIO::calibrationCount(int &frames)
-{
-  int tempT,tempC;
-  mutex.lock();
-  tempC=calibrationFrames;
-  tempT=calibrationTime;
-  mutex.unlock();
-  frames=tempC-CALIBRATIONLEADIN;
-  return tempT;
-}
-
-
-
-
-
diff --git a/qsstv/sound/soundio.cpp_new b/qsstv/sound/soundio.cpp_new
deleted file mode 100644
index 78be941..0000000
--- a/qsstv/sound/soundio.cpp_new
+++ /dev/null
@@ -1,851 +0,0 @@
-/**************************************************************************
-*   Copyright (C) 2000-2012 by Johan Maes                                 *
-*   on4qz at telenet.be                                                      *
-*   http://users.telenet.be/on4qz                                         *
-*                                                                         *
-*   This program is free software; you can redistribute it and/or modify  *
-*   it under the terms of the GNU General Public License as published by  *
-*   the Free Software Foundation; either version 2 of the License, or     *
-*   (at your option) any later version.                                   *
-*                                                                         *
-*   This program is distributed in the hope that it will be useful,       *
-*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
-*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
-*   GNU General Public License for more details.                          *
-*                                                                         *
-*   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.,                                       *
-*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
-***************************************************************************/
-#include "soundio.h"
-#include "qsstvglobal.h"
-#include"soundcontrol.h"
-#include <QDebug>
-#include <QApplication>
-#include <stdio.h>
-#include <unistd.h>
-#include "utils/supportfunctions.h"
-//#include "scope/scopeview.h"
-#include <sys/time.h>
-#include <sys/timex.h>
-
-
-soundIO *soundIOPtr;
-
-
-static const unsigned int rates[] =
-{
-  5512,
-  8000,
-  11025,
-  16000,
-  22050,
-  32000,
-  44100,
-  48000,
-  64000,
-  88200,
-  96000,
-  176400,
-  192000,
-};
-
-
-soundIO::soundIO(int s)
-{
-  setSamplerate(s);
-  soundOK=FALSE;
-
-}
-
-
-void soundIO::setSamplerate(int s)
-{
-  samplerate=s;
-}
-
-void  soundIO::run()
-{
-  unsigned int delay;
-  delay=((playbackBufferSize*1000)/samplerate);
-  abort=FALSE;
-  playbackState=PBINIT;
-  captureState=CPINIT;
-  if(!soundOK) return;
-  while(!abort)
-    {
-      switch(playbackState)
-        {
-        case PBINIT:
-          msleep(10);
-          detectedPlaybackState= PBINIT;
-        break;
-        case PBSTARTING:
-          if (play()==0) msleep(10);
-          else
-            {
-              playbackState=PBRUNNING;
-              addToLog("playback started",LOGPERFORM);
-            }
-          detectedPlaybackState= PBSTARTING;
-        break;
-        case PBRUNNING:
-          if (play()==0)
-            {
-               addToLog(QString("playback stopped: delay=%1").arg(delay),LOGPERFORM);
-               msleep(delay);
-               waveOut.close();
-               addToLog("playback stopped",LOGPERFORM);
-               emit playbackStopped();
-               playbackState=PBINIT;
-            }
-          detectedPlaybackState= PBRUNNING;
-        break;
-        case PBCALIBRATE1:
-          {
-            detectedPlaybackState= PBCALIBRATE1;
-            if (playbackCalibration()!=0)
-              {
-                playbackState=PBCALIBRATE2;
-              }
-          }
-        break;
-        case PBCALIBRATE2:
-          {
-            if (playbackCalibration()==0) break;
-            detectedPlaybackState= PBCALIBRATE2;
-          }
-          break;
-       }
-      switch(captureState)
-        {
-        case CPINIT:
-          msleep(10);
-          detectedCaptureState=CPINIT;
-        break;
-        case CPSTARTING:
-          rxBuffer.reset(); //clear the rxBuffer
-          snd_pcm_readi( captureHandle, tempRXBuffer,PERIODSIZE);
-          detectedCaptureState=CPSTARTING;
-          captureState=CPRUNNING;
-        break;
-        case CPRUNNING:
-          if (capture()==0) msleep(75);
-          detectedCaptureState=CPRUNNING;
-        break;
-        case CPCALIBRATE:
-          {
-            if (captureCalibration()==0) msleep(0);
-            detectedCaptureState= CPCALIBRATE;
-          }
-       }
-    }
-  abort=FALSE;
-  playbackState=PBINIT;
-  captureState=CPINIT;
-}
-
-
-/**
- * @brief play sound from txBuffer
- *
- * The sound is controlled by soundRoutingOutput (via configuration).
- * - SNDOUTCARD  sound to card only
- * - SNDOUTTOFILE sound to card and saved in wav file
- * - SNDOUTFILETOCARD sound from wav file to card
- *
- * @return number of frames sent.
- *
- * The readIndex must always be a multiple of 2*PERIODSIZE because we don't check the txBuffer for wrap-around.
- *
- */
-
-double soundIO::getPlaybackStartupTime()
-{
-  return (double)playbackBufferSize/BASESAMPLERATE;
-}
-
-int soundIO::play()
-{
- unsigned int numFrames,restFrames;
- int framesWritten,error;
-  addToLog(QString("readIndex: %1,writeIndex: %2 count: %3").arg(txBuffer.getReadIndex()).arg(txBuffer.getWriteIndex()).arg(txBuffer.count()),LOGSOUND);
-  if(playbackState==PBSTARTING)
-    {
-      // prefill buffers to the max
-      if((numFrames=txBuffer.count())<playbackBufferSize) return 0;
-      addToLog(QString("start numFrame: %1").arg(numFrames),LOGSOUND);
-      numFrames=playbackBufferSize;
-    }
-  else
-    {
-      if((numFrames=txBuffer.count())>=(2*PERIODSIZE))
-        {
-          numFrames=2*PERIODSIZE;
-        }
-    }
-
-  if(soundRoutingOutput==SNDOUTTOFILE)
-    {
-      if(storedFrames<=(ulong)recordingSize*1048576L)
-        {
-          waveOut.write(txBuffer.readPointer(),numFrames);
-          storedFrames+=numFrames;
-          txBuffer.skip(numFrames);
-          return numFrames;
-        }
-      else
-        {
-          return 0;
-        }
-
-    }
-  restFrames=numFrames;
-  while(restFrames)
-    {
-      framesWritten =  snd_pcm_writei ( playbackHandle, txBuffer.readPointer(), restFrames);
-//      arrayDump(QString("sio %1").arg(frameCounter++),txBuffer.readPointer(),32,TRUE);
-      if(framesWritten<0)
-        {
-          if ( framesWritten ==  -EAGAIN )
-            {
-              return -1;
-            }
-          else if ( framesWritten == -EPIPE )
-            {
-              /* underrun */
-              errorHandler(framesWritten,QString("Underrun recovery for %1").arg(numFrames));
-              error = snd_pcm_prepare (playbackHandle);
-              if ( error < 0 )
-                {
-                  errorHandler(framesWritten,"Can't recover from underrun, prepare failed");
-                  snd_pcm_drop (playbackHandle);
-                }
-            }
-          else
-            {
-              errorHandler(framesWritten,"Unhandled error in playback");
-              snd_pcm_drop (playbackHandle );
-            }
-        }
-      else
-        {
-          addToLog(QString("framesWritten:%1").arg(framesWritten),LOGSOUND);
-          txBuffer.skip(framesWritten);
-          if(restFrames!=numFrames)
-            {
-              addToLog(QString("restFrames: %1; framesWritten %2").arg(restFrames).arg(framesWritten),LOGSOUND);
-            }
-          msleep(10);
-          restFrames-=framesWritten;
-        }
-    }
-  return numFrames;
-}
-
-int soundIO::playbackCalibration()
-{
-  int numFrames,framesWritten;
-  if(playbackState==PBCALIBRATE1)
-    {
-      numFrames=playbackBufferSize;
-      framesWritten =  snd_pcm_writei ( playbackHandle, txBuffer.readPointer(), numFrames);
-      if(numFrames!=framesWritten)
-        {
-//          qDebug() << " error in calibration framesWriiten" <<framesWritten << numFrames ;
-        }
-      calibrationFrames=0;
-      return numFrames;
-    }
-  else
-    {
-      numFrames=1*PERIODSIZE;
-    }
-  framesWritten =  snd_pcm_writei ( playbackHandle, txBuffer.readPointer(), numFrames);
-  if(numFrames!=framesWritten)
-    {
-//       qDebug() << " error in calibration framesWriiten" <<framesWritten << numFrames ;
-       framesWritten =  snd_pcm_writei ( playbackHandle, txBuffer.readPointer(), numFrames-framesWritten);
-    }
-  else
-    {
-
-    }
-  mutex.lock();
-  calibrationFrames+=1;
-  calibrationTime=stopwatch.elapsed();
-  if(calibrationFrames==CALIBRATIONLEADIN)
-    {
-      stopwatch.start();
-      addToLog("start calrx",LOGCAM);
-    }
-  mutex.unlock();
-  return numFrames;
-}
-
-/**
- * @brief capture sound to rxBuffer
- *
- * The sound recording is controlled by soundRoutingInput (via configuration).
- *
- * - SNDINCARD sound from card
- * - SNDINFILE sound from a wav file
- * - SNDINCARDTOFILE sound from card and recording to wav file
- *
- * @return number of frames recorded.
- */
-
-int soundIO::capture()
-{
-  int count;
-  QString debugStr;
-  if(rxBuffer.spaceLeft()<1024) return 0;
-  if(soundRoutingInput==SNDINFILE)
-    {
-      count=waveIn.read((quint32*)tempRXBuffer,PERIODSIZE);
-     //delay to give realtime feeling
-      msleep((2*count)/samplerate);
-      if(count<=0)
-        {
-          waveIn.close();
-          captureState=CPINIT;
-        }
-    }
-  else
-    {
-      count=snd_pcm_avail(captureHandle); // check for available frames
-      if(count>=PERIODSIZE)
-        {
-          count = snd_pcm_readi( captureHandle, tempRXBuffer,PERIODSIZE);
-        }
-      if ( count < 0 )
-        {
-          if ( count != -EAGAIN )
-            {
-              if ( count == -EPIPE )
-                {
-                  // Overrun
-                  snd_pcm_prepare (captureHandle );
-                  snd_pcm_start (captureHandle);
-                  printf ( "Overrun\n" );
-                }
-              else
-                {
-                  snd_pcm_drop (captureHandle );
-                  printf ( "Overrun , reason %d\nStopping device", count );
-                }
-            }
-          addToLog("soundIO: sound eagain",LOGSOUND);
-          return 0;
-        }
-      else
-        {
-          if(soundRoutingInput==SNDINCARDTOFILE)
-            {
-              if(storedFrames<=(ulong)recordingSize*1048576L)
-                {
-                  waveOut.write((quint32*)tempRXBuffer,count);
-                  //             addToLog(QString("storing data: %1").arg(storedFrames),LOGSOUND);
-                  storedFrames+=count;
-                }
-              else
-                {
-                  captureState=CPINIT;
-                }
-            }
-        }
-    }
-//  addToLog(QString("rxBuffercount: %1").arg(count),LOGSOUND);
-  if(count!=PERIODSIZE)
-    {
-//      addToLog("count not periodsize",LOGSOUND);
-      return 0;
-    }
-  if(isStereo)
-    {
-      for(int i=0;i<count;i++)
-        {
-          tempRXBuffer[i]=tempRXBuffer[2*i];  // setup as mono channel
-        }
-     }
-  rxBuffer.putNoCheck(tempRXBuffer,count);
-  addToLog(QString("in buffer count: %1 % readIndex=%2 writeindex=%3").arg(rxBuffer.count()).arg(rxBuffer.getReadIndex()).arg(rxBuffer.getWriteIndex()),LOGSOUND);
-  return count;
-}
-
-int soundIO::captureCalibration()
-{
-  int count;
-  count = snd_pcm_readi( captureHandle, tempRXBuffer,PERIODSIZE);
-  if (count==PERIODSIZE)
-    {
-      mutex.lock();
-      calibrationFrames++;
-      calibrationTime=stopwatch.elapsed();
-      if(calibrationFrames==CALIBRATIONLEADIN)
-        {
-          stopwatch.start();
-          addToLog("start calrx",LOGCAM);
-        }
-      mutex.unlock();
-      if(calibrationFrames%50==0) addToLog(QString("calrx %1 T=%2").arg(calibrationFrames).arg(calibrationTime),LOGCAM);
-    }
-  else if(count>=0)
-    {
-      qDebug() << "invalid count" << count << "frames" << calibrationFrames << "time" << calibrationTime;
-      qDebug() <<  "requested" << PERIODSIZE-count;
-      count = snd_pcm_readi( captureHandle, tempRXBuffer,PERIODSIZE-count);
-      qDebug() << "new count" << count ;
-      mutex.lock();
-      calibrationFrames++;
-      calibrationTime=stopwatch.elapsed();
-      mutex.unlock();
-
-    }
-  else
-    {
-      calibrationFrames=0; // restart calibration
-      qDebug() << "restarting calibration";
-      if ( count != -EAGAIN )
-        {
-          if ( count == -EPIPE )
-            {
-              // Overrun
-              snd_pcm_prepare (captureHandle );
-              snd_pcm_start (captureHandle);
-              printf ( "Overrun\n" );
-            }
-          else
-            {
-              snd_pcm_drop (captureHandle );
-              printf ( "Overrun , reason %d\nStopping device", count );
-            }
-        }
-      addToLog("soundIO: sound eagain",LOGSOUND);
-      return 0;
-    }
-
-  return count;
-}
-
-/**
- * @brief Initialisation of the soundcard hardware in full-duplex
- *
- * This function must be called before using the soundcard and after the configuration has been loaded
- *@return bool TRUE if call was succesfull
- */
-
-bool soundIO::init()
-{
-  int err;
-  stopSoundIO();
-  QString tempDevice;
-  lastError.clear();
-  soundOK=FALSE;
-  tempDevice=outputAudioDevice.left(outputAudioDevice.indexOf(" "));
-  err = snd_pcm_open(&playbackHandle,tempDevice.toLatin1().data(), SND_PCM_STREAM_PLAYBACK,0); //open in blocking mode
-  if(!errorHandler(err,"Unable to open "+outputAudioDevice)) return FALSE;
-  tempDevice=inputAudioDevice.left(inputAudioDevice.indexOf(" "));
-  err = snd_pcm_open(&captureHandle,tempDevice.toLatin1().data(), SND_PCM_STREAM_CAPTURE, 0);
-  if(!errorHandler(err,"Unable to open "+inputAudioDevice)) return FALSE;
-  snd_pcm_hw_params_malloc ( &hwparams );
-  snd_pcm_sw_params_malloc ( &swparams );
-  if(setupSoundParams(TRUE))
-    {
-      if(setupSoundParams(FALSE)) soundOK=TRUE;
-    }
-
-  snd_pcm_hw_params_free ( hwparams );
-  snd_pcm_sw_params_free ( swparams );
-   return soundOK;
-}
-
-void soundIO::stopSoundIO()
-{
-  int err;
-  if(soundOK)
-    {
-      err=snd_pcm_close(playbackHandle);
-      err=snd_pcm_close(captureHandle);
-      soundOK=FALSE;
-    }
-}
-
-bool soundIO::setupSoundParams(bool isCapture)
-{
-  int err;
-  int dir=0;
-  snd_pcm_t *handle;
-
-  playbackPeriodSize=PERIODSIZE;
-  playbackBufferSize=BUFFERSIZE;
-  capturePeriodSize=PERIODSIZE;
-  captureBufferSize=BUFFERSIZE;
-
-  if(isCapture) handle=captureHandle;
-  else handle=playbackHandle;
-
-  /* Choose all parameters */
-  err = snd_pcm_hw_params_any ( handle, hwparams );
-  if(!errorHandler(err,"Broken configuration : no configurations available")) return FALSE;
-
-  /* Set the interleaved read/write format */
-  err = snd_pcm_hw_params_set_access ( handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED );
-  if(!errorHandler(err,"Access type not available : ")) return FALSE;
-
-  /* Set the sample format */
-  err = snd_pcm_hw_params_set_format ( handle, hwparams, SND_PCM_FORMAT_S16_LE );
-  if(!errorHandler(err,"Sample format Float not available : ")) return FALSE;
-  /* Set the count of channels */
-  if(isCapture)
-    {
-      err=snd_pcm_hw_params_get_channels_min(hwparams,&minChannelsCapture);
-      err=snd_pcm_hw_params_get_channels_max(hwparams,&maxChannelsCapture);
-      qDebug() << "numChannels Capture" << minChannelsCapture << maxChannelsCapture;
-      err = snd_pcm_hw_params_set_channels ( handle, hwparams, minChannelsCapture);
-      if(!errorHandler(err,"Channels count not correct; " )) return FALSE;
-     }
-  else
-    {
-
-      err=snd_pcm_hw_params_get_channels_min(hwparams,&minChannelsPlayback);
-      err=snd_pcm_hw_params_get_channels_max(hwparams,&maxChannelsPlayback);
-      qDebug() << "numChannels Playback" << minChannelsPlayback << maxChannelsPlayback;
-      err = snd_pcm_hw_params_set_channels ( handle, hwparams, minChannelsPlayback);
-      if(!errorHandler(err,"Channels count not correct; " ))
-        {
-          return FALSE;
-        }
-    }
-
-  err = snd_pcm_hw_params_set_rate ( handle, hwparams, samplerate, 0 );
-  if(!errorHandler(err,QString("Samplerate %1 not available").arg(samplerate))) return FALSE;
-
-  if(isCapture)
-    {
-      err = snd_pcm_hw_params_set_period_size_near ( handle, hwparams, &capturePeriodSize, &dir );
-      if(!errorHandler(err,QString("Unable to set period size %1 for capture").arg(capturePeriodSize))) return FALSE;
-      err = snd_pcm_hw_params_set_buffer_size_near ( handle, hwparams, &captureBufferSize );
-      if(!errorHandler(err,QString("Unable to set buffersize %1 for capture").arg(captureBufferSize))) return FALSE;
-    }
-  else
-    {
-      err = snd_pcm_hw_params_set_period_size_near ( handle, hwparams, &playbackPeriodSize, &dir );
-      if(!errorHandler(err,QString("Unable to set period size %1 for playback").arg(playbackPeriodSize))) return FALSE;
-      err = snd_pcm_hw_params_set_buffer_size_near ( handle, hwparams, &playbackBufferSize );
-      if(!errorHandler(err,QString("Unable to set buffersize %1 for playback").arg(playbackBufferSize))) return FALSE;
-    }
-  err = snd_pcm_hw_params ( handle, hwparams );
-  if(isCapture)
-    {
-      if(!errorHandler(err,QString("Unable to set hw params for capture:"))) return FALSE;
-    }
-  else
-    {
-      if(!errorHandler(err,QString("Unable to set hw params for playback:"))) return FALSE;
-    }
-
-  /* Get the current swparams */
-  err = snd_pcm_sw_params_current ( handle, swparams );
-  if(!errorHandler(err,"Unable to determine current swparams")) return FALSE;
-  err = snd_pcm_sw_params_set_start_threshold ( handle, swparams, 2048 );
-  if(!errorHandler(err,"Unable to set start threshold mode")) return FALSE;
-   /* Write the parameters to the record/playback device */
-  err = snd_pcm_sw_params ( handle, swparams );
-  if(!errorHandler(err,"Unable to set sw params for output")) return FALSE;
-  return TRUE;
- }
-
-bool soundIO::listCards()
-{
-  int  err;
-  int  cardNum, totalCards;
-  char   str[64];
-  snd_ctl_card_info_t *cardInfo;
-  int      devNum, totalDevices;
-  snd_pcm_info_t *pcmInfo;
-  snd_ctl_t *cardHandle;
-
-  // No cards found yet
-  totalCards = 0;
-
-  // Start with first card
-  cardNum = -1;
-
-  for (;;)
-    {
-
-      // Get next sound card's card number. When "cardNum" == -1, then ALSA fetches the first card
-      if ((err = snd_card_next(&cardNum)) < 0)
-        {
-          qDebug() << "Can't get the next card number:" << snd_strerror(err);
-          return FALSE;
-        }
-
-      if (cardNum < 0) break; // No more cards? ALSA sets "cardNum" to -1 if so
-      sprintf(str, "hw:%i", cardNum);
-      if ((err = snd_ctl_open(&cardHandle, str, 0)) < 0)
-        {
-          qDebug() << "Can't open card "<< cardNum << snd_strerror(err);
-          continue;
-        }
-      // We need to get a snd_ctl_card_info_t. Just alloc it on the stack
-      snd_ctl_card_info_alloca(&cardInfo);
-
-      // Tell ALSA to fill in our snd_ctl_card_info_t with info about this card
-      if ((err = snd_ctl_card_info(cardHandle, cardInfo)) < 0)
-        qDebug() << "Can't get info for card" << cardNum << snd_strerror(err);
-      else
-        qDebug() << "Card " << cardNum << "name: " << snd_ctl_card_info_get_name(cardInfo);
-      totalDevices = 0;
-      devNum = -1; // Start with the first wave device on this card
-      for (;;)
-        {
-          if ((err = snd_ctl_pcm_next_device(cardHandle, &devNum)) < 0)  // Get the number of the next wave device on this card
-            {
-              qDebug()<< "Can't get next wave device number: " << snd_strerror(err);
-              break;
-            }
-
-          // No more wave devices on this card? ALSA sets "devNum" to -1 if so.
-          // NOTE: It's possible that this sound card may have no wave devices on it
-          // at all, for example if it's only a MIDI card
-          if (devNum < 0) break;
-          // To get some info about the subdevices of this wave device (on the card), we need a
-          // snd_pcm_info_t, so let's allocate one on the stack
-          snd_pcm_info_alloca(&pcmInfo);
-          memset(pcmInfo, 0, snd_pcm_info_sizeof());
-
-          // Tell ALSA which device (number) we want info about
-          snd_pcm_info_set_device(pcmInfo, devNum);
-          // Get info on the wave outs of this device
-          getDevices(cardHandle,cardNum,devNum,pcmInfo, SND_PCM_STREAM_PLAYBACK);
-          getDevices(cardHandle,cardNum,devNum,pcmInfo, SND_PCM_STREAM_CAPTURE);
-        }
-      ++totalCards;
-      // Close the card's control interface after we're done with it
-      snd_ctl_close(cardHandle);
-      qDebug() << "Found:" << totalDevices << " digital audio devices on card " <<  cardNum;
-    }
-
-  qDebug() << "ALSA found cards" << totalCards;
-
-  // ALSA allocates some mem to load its config file when we call
-  // snd_card_next. Now that we're done getting the info, let's tell ALSA
-  // to unload the info and free up that mem
-  snd_config_update_free_global();
-  return TRUE;
-}
-
-
-void soundIO::getDevices(snd_ctl_t *cardHandle,int cardNum,int devNum,snd_pcm_info_t *pcmInfo, snd_pcm_stream_t direction)
-{
-  int  err;
-  int i= -1;
-  int subDevCount = 1;
-  snd_pcm_info_set_stream(pcmInfo, direction);
-
-  // More subdevices?
-  while (++i < subDevCount)
-    {
-      // Tell ALSA to fill in our snd_pcm_info_t with info on this subdevice
-      snd_pcm_info_set_subdevice(pcmInfo, i);
-      if ((err = snd_ctl_pcm_info(cardHandle, pcmInfo)) < 0)
-        {
-          qDebug() << QString("Can't get info for wave output subdevice hw:%1,%2,%3: %4").arg(cardNum).arg(devNum).arg(i).arg(snd_strerror(err));
-          continue;
-        }
-      qDebug() << "PCM name" << snd_pcm_info_get_name(pcmInfo);
-      // Print out how many subdevices (once only)
-      if (!i)
-        {
-          subDevCount = snd_pcm_info_get_subdevices_count(pcmInfo);
-          qDebug() << QString("Found %1 wave output subdevices on card %2").arg(subDevCount).arg(cardNum);
-        }
-
-      // NOTE: If there's only one subdevice, then the subdevice number is immaterial,
-      // and can be omitted when you specify the hardware name
-      if(subDevCount>1)
-        {
-          qDebug()<< QString("hw:%1,%2,%3").arg(cardNum).arg(devNum).arg(i);
-          if(direction==SND_PCM_STREAM_CAPTURE)
-            {
-              inputPCMNameList << QString("hw:%1,%2,%3  %4").arg(cardNum).arg(devNum).arg(i).arg(snd_pcm_info_get_name(pcmInfo));
-            }
-
-          else
-            {
-              outputPCMNameList << QString("hw:%1,%2,%3  %4").arg(cardNum).arg(devNum).arg(i).arg(snd_pcm_info_get_name(pcmInfo));
-            }
-
-         }
-      else
-        {
-          qDebug()<< QString("hw:%1,%2").arg(cardNum).arg(devNum);
-          if(direction==SND_PCM_STREAM_CAPTURE)
-            {
-              inputPCMNameList << QString("hw:%1,%2  %3").arg(cardNum).arg(devNum).arg(snd_pcm_info_get_name(pcmInfo));
-            }
-
-          else
-            {
-              outputPCMNameList << QString("hw:%1,%2  %3").arg(cardNum).arg(devNum).arg(snd_pcm_info_get_name(pcmInfo));
-           }
-        }
-
-    }
-
-}
-
-
-
-bool soundIO::errorHandler(int err,QString info)
-{
-  if(err<0)
-    {
-      lastError=info+ ": "+ QString ( snd_strerror ( err ) );
-      qDebug() << lastError;
-      addToLog(lastError,LOGALL);
-      return FALSE;
-    }
-  return TRUE;
-}
-
-void soundIO::errorHandler(QString info)
-{
-  lastError=info;
-  qDebug() << lastError;
-  addToLog(lastError,LOGALL);
-}
-
-
-
-bool soundIO::startCapture()
-{
-  init();
-  playbackState=PBINIT;
-  if(!soundOK) return FALSE;
-  switch(soundRoutingInput)
-    {
-      case SNDINCARD:
-      if(minChannelsCapture==1) isStereo=FALSE; else isStereo=TRUE;
-      break;
-      case SNDINFILE:
-      if(!waveIn.openFileForRead("",TRUE))
-        {
-          errorHandler("File not opened");
-          return FALSE;
-        }
-      if(waveIn.getNumberOfChannels()==1) isStereo=FALSE; else isStereo=TRUE;
-      break;
-      case SNDINCARDTOFILE:
-        {
-          if(!waveOut.openFileForWrite("",TRUE))
-            {
-              errorHandler("File not opened");
-              return FALSE;
-            }
-        }
-      break;
-    }
-  rxBuffer.reset();
-  captureState=CPSTARTING;
-  addToLog("start capturing",LOGSOUND);
-  return TRUE;
-}
-
-bool soundIO::startPlayback()
-{
-  int count;
-  frameCounter=0;
-  captureState=CPINIT;
-  if(!soundOK) return FALSE;
-  soundIOPtr->txBuffer.reset();
-  if(soundRoutingOutput==SNDOUTFILETOCARD)
-    {
-      if(!waveIn.openFileForRead("",TRUE))
-        {
-          errorHandler("File not opened");
-          return FALSE;
-        }
-      snd_pcm_prepare (playbackHandle);
-      playbackState=PBSTARTING;
-      do
-        {
-          while(txBuffer.spaceLeft()<1024)
-            {
-              qApp->processEvents();
-            }
-          count=waveIn.read(txBuffer.writePointer(),1024);
-          txBuffer.advance(count);
-        }
-      while(count>0);
-      waveIn.close();
-    }
-  else
-    {
-      if(soundRoutingOutput==SNDOUTTOFILE)
-        {
-          if(!waveOut.openFileForWrite("",TRUE))
-            {
-              errorHandler("File not opened");
-              return FALSE;
-            }
-        }
-      playbackState=PBSTARTING;
-      snd_pcm_prepare (playbackHandle);
-      addToLog(QString("start playback, txbuffercount: %1").arg(txBuffer.count()),LOGSOUND);
-    }
-  return TRUE;
-}
-
-bool soundIO::startCalibration(bool capture)
-{
-  captureState=CPINIT;
-  playbackState=PBINIT;
-  if(!soundOK) return FALSE;
-  while(detectedCaptureState!=CPINIT) {};
-  while(detectedPlaybackState!=PBINIT) {};
-  calibrationFrames=0;
-  if(capture)
-    {
-     snd_pcm_prepare (captureHandle );
-     snd_pcm_start (captureHandle);
-     captureState=CPCALIBRATE;
-    }
-  else
-    {
-      txBuffer.fill(0);
-     //
-      snd_pcm_start (playbackHandle);
-      //snd_pcm_prepare (playbackHandle );
-      playbackState=PBCALIBRATE1;
-    }
-  return TRUE;
-}
-
-void soundIO::idle()
-{
-  captureState=CPINIT;
-  playbackState=PBINIT;
-}
-
-/**
- * @brief stopping soundio thread
- */
-
-void soundIO::stopAndWait()
-{
-  if(!soundOK) return;
-  abort=TRUE;
-  while(abort)
-    {
-      qApp->processEvents();
-    }
-}
-
-
-
-
-
diff --git a/qsstv/sound/soundio.h b/qsstv/sound/soundio.h
deleted file mode 100644
index 2aec2b1..0000000
--- a/qsstv/sound/soundio.h
+++ /dev/null
@@ -1,142 +0,0 @@
-#ifndef SOUNDIO_H
-#define SOUNDIO_H
-
-#include <alsa/asoundlib.h>
-#include "qsstvglobal.h"
-#include <QStringList>
-#include <QThread>
-#include "utils/buffermanag.h"
-#include "wavio.h"
-#include "qsstvdefs.h"
-#include <QTime>
-
-/*! \file soundio.h */
-
-/**
- * @brief soundio class
- *
- *General Info<br>
- * A frame is equivalent of one sample being played, irrespective of the number of channels or the number of bits.<br>
- * e.g.
-    1 frame of a Stereo 48khz 16bit PCM stream is 4 bytes.
-    1 frame of a 5.1 48khz 16bit PCM stream is 12 bytes.
-
-A period is the number of frames in between each hardware interrupt. The poll() will return once a period.
-
-The buffer is a ring buffer. The buffer size always has to be greater than one period size. Commonly this is 2*period size, but some hardware can do 8 periods per buffer. It is also possible for the buffer size to not be an integer multiple of the period size.
-
-Now, if the hardware has been set to 48000Hz , 2 periods, of 1024 frames each, making a buffer size of 2048 frames. The hardware will interrupt 2 times per buffer. ALSA will endeavor to keep the buffer as full as possible. Once the first period of samples has been played, the third period of samples is transfered into the space the first one occupied while the second period of samples is being played. (normal ring buffer behaviour).
-
- */
-
-#define CALIBRATIONLEADIN 100
-
-class soundIO:public QThread
-{
-  Q_OBJECT
-public:
-  enum edataSrc{SNDINCARD,SNDINFILE,SNDINCARDTOFILE};
-  enum edataDst{SNDOUTCARD,SNDOUTTOFILE};
-  enum eplaybackState{PBINIT,PBSTARTING,PBRUNNING,PBCALIBRATE1,PBCALIBRATE2};
-  enum ecaptureState{CPINIT,CPSTARTING,CPRUNNING,CPCALIBRATE,CPEND};
-#define PERIODBITS 12
-#define PERIODSIZE (1<<PERIODBITS)
-#define BUFFERSIZE (8*PERIODSIZE)
-  soundIO(int s=48000);
-  void setSamplerate(int s);
-  bool init();
-  bool isSoundOK() {return soundOK;}
-  bool listCards();
-  void run();
-  bool startCapture();
-  bool startPlayback();
-  bool startCalibration(bool capture);
-  double getPlaybackStartupTime();
-  int play();
-  int capture();
-  int captureCalibration();
-  int playbackCalibration();
-  void idle();
-  void stopAndWait();
-  bool isCapturing() {return captureState!=CPINIT;}
-  bool stoppedPlaying();
-  void abortPlayback() {playbackState=PBINIT;}
-  QString *getLastError() {return &lastError;}
-  QStringList *getPCMNamList(bool input)
-    {
-    if (input) return &inputPCMNameList;
-    else return &outputPCMNameList;
-    }
-  QString inputAudioDevice; //!< audio device (e.g. /dev/dsp)
-  QString outputAudioDevice; //!< audio device (e.g. /dev/dsp)
-  edataSrc soundRoutingInput;
-  edataDst soundRoutingOutput;
-  uint recordingSize;
-  buffer<short int,24> rxBuffer;
-  buffer<SOUNDFRAME,PERIODBITS+5> txBuffer;
-  short int tempRXBuffer[2*PERIODSIZE]; // twice because we are using stereo input
-  wavIO waveIn;
-  wavIO waveOut;
-  uint frameCounter;
-  void setStereo(bool st) {isStereo=st;}
-  int calibrationCount(int &frames);
-//  {
-//    int tempT,tempC;
-//    mutex.lock();
-//    tempC=calibrationFrames;
-//    tempT=calibrationTime;
-//    mutex.unlock();
-//    frames=tempC-CALIBRATIONLEADIN;
-//    return tempT;
-//  }
-
-signals:
-  void playbackStopped();
-
-
-private:
-  bool initialized;
-  snd_pcm_t      *playbackHandle;
-  snd_pcm_t      *captureHandle;
-  QStringList inputPCMNameList; /**< list of PCM Names for input*/
-  //QStringList inputPCMInfoList; /**< list of PCM Descriptions for input*/
-  QStringList outputPCMNameList; /**< list of PCM Names for output*/
-  //QStringList outputPCMInfoList; /**< list of PCM Descriptions for output*/
-  QString lastError;
-  bool errorHandler(int err,QString info);
-  void errorHandler(QString info);
-  bool setupSoundParams(bool isCapture);
-  int samplerate;
-  snd_pcm_uframes_t playbackPeriodSize;
-  snd_pcm_uframes_t playbackBufferSize;
-  snd_pcm_uframes_t capturePeriodSize;
-  snd_pcm_uframes_t captureBufferSize;
-  snd_pcm_hw_params_t *hwparams;
-  snd_pcm_sw_params_t *swparams;
-  bool abort;
-  unsigned long storedFrames;
-  eplaybackState playbackState;
-  eplaybackState detectedPlaybackState;
-  ecaptureState  captureState;
-  ecaptureState  detectedCaptureState;
-  bool soundOK;
-
-  unsigned int minChannelsCapture;
-  unsigned int maxChannelsCapture;
-  unsigned int minChannelsPlayback;
-  unsigned int maxChannelsPlayback;
-  bool isStereo;
-  void getDevices(snd_ctl_t *cardHandle, int cardNum, int devNum, snd_pcm_info_t *pcmInfo, snd_pcm_stream_t direction);
-  QTime stopwatch;
-  QMutex mutex;
-  unsigned int calibrationFrames;
-  int calibrationTime;
-
-};
-
-/*! \var soundIO *soundIOPtr
-\brief predefined pointer to soundIO, must be initialized by the main program
-*/
-extern soundIO *soundIOPtr;
-
-#endif // SOUNDIO_H
diff --git a/qsstv/sound/soundpulse.cpp b/qsstv/sound/soundpulse.cpp
new file mode 100644
index 0000000..2fe081b
--- /dev/null
+++ b/qsstv/sound/soundpulse.cpp
@@ -0,0 +1,177 @@
+/**************************************************************************
+*   Copyright (C) 2000-2012 by Johan Maes                                 *
+*   on4qz at telenet.be                                                      *
+*   http://users.telenet.be/on4qz                                         *
+*                                                                         *
+*   This program is free software; you can redistribute it and/or modify  *
+*   it under the terms of the GNU General Public License as published by  *
+*   the Free Software Foundation; either version 2 of the License, or     *
+*   (at your option) any later version.                                   *
+*                                                                         *
+*   This program is distributed in the hope that it will be useful,       *
+*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+*   GNU General Public License for more details.                          *
+*                                                                         *
+*   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.,                                       *
+*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+***************************************************************************/
+#include "soundpulse.h"
+
+#include <sys/types.h>
+#include <unistd.h>
+
+
+
+soundPulse::soundPulse()
+{
+  sd[0].stream = NULL;
+  sd[1].stream = NULL;
+
+}
+
+soundPulse::~soundPulse()
+{
+  if(sd[0].stream)  pa_simple_free(sd[0].stream);
+  if(sd[1].stream)  pa_simple_free(sd[1].stream);
+  sd[0].stream = NULL;
+  sd[1].stream = NULL;
+}
+
+
+bool soundPulse::init(int samplerate)
+{
+  soundDriverOK=false;
+  QString sname;
+  sampleRate=samplerate;
+  //open two streams (capture and play)
+  int err;
+  sd[0].stream = NULL;
+  sd[0].dir = PA_STREAM_RECORD;
+  sd[0].stream_params.format = PA_SAMPLE_S16LE;
+  sd[0].stream_params.channels = MONOCHANNEL;
+  sd[0].stream_params.rate=sampleRate;
+  sd[0].buffer_attrs.maxlength = (uint32_t)-1; // let the server decide
+  sd[0].buffer_attrs.minreq =    (uint32_t)-1;
+  sd[0].buffer_attrs.prebuf =    (uint32_t)-1;
+  sd[0].buffer_attrs.tlength =   (uint32_t)-1;
+  sd[0].buffer_attrs.fragsize =  CAPTFRAGSIZE * sizeof(short int);
+
+  sd[1].stream = NULL;
+  sd[1].dir = PA_STREAM_PLAYBACK;
+  sd[1].stream = NULL;
+  sd[1].stream_params.format = PA_SAMPLE_S16LE;
+  sd[1].stream_params.channels = STEREOCHANNEL;
+  sd[1].stream_params.rate=sampleRate;
+  sd[1].buffer_attrs.fragsize =  (uint32_t)-1; // let the server decide
+  sd[1].buffer_attrs.maxlength = (uint32_t)-1;
+  sd[1].buffer_attrs.minreq =    (uint32_t)-1;
+  sd[1].buffer_attrs.prebuf =    (uint32_t)-1;
+  sd[1].buffer_attrs.tlength =   PLAYLENGTH * sizeof(quint32);
+
+  // opening device
+  sname=QString("capture %1").arg(getpid());
+  sd[0].stream = pa_simple_new(NULL, shortName.toLatin1().data(), sd[0].dir, NULL,sname.toLatin1().data(), &sd[0].stream_params, NULL,&sd[0].buffer_attrs, &err);
+  //  sd[0].stream = pa_simple_new(NULL, shortName.toLatin1().data(), sd[0].dir, NULL,sname.toLatin1().data(), &sd[0].stream_params, NULL,&sd[0].buffer_attrs, &err);
+  if(sd[0].stream==NULL)
+  {
+    errorHandler("PulseAudio read init error",QString(pa_strerror(err)));
+    return false;
+  }
+
+  sname=QString("playback %1").arg(getpid());
+  sd[1].stream = pa_simple_new(NULL, shortName.toLatin1().data(), sd[1].dir, NULL,sname.toLatin1().data(), &sd[1].stream_params, NULL,&sd[1].buffer_attrs, &err);
+  if(sd[1].stream==NULL)
+  {
+    errorHandler("PulseAudio read init error",QString(pa_strerror(err)));
+    return false;
+  }
+  isStereo=false;
+  soundDriverOK=true;
+  return true;
+}
+
+
+
+int soundPulse::read(int &countAvailable)
+{
+  int err=PA_OK;
+  pa_usec_t latency;
+  latency = pa_simple_get_latency(sd[0].stream, &err);
+  if(err!=PA_OK)
+  {
+    errorHandler("PulseAudio latency error:", QString(pa_strerror(err)));
+    return -1;
+  }
+  countAvailable= pa_usec_to_bytes(latency, &sd[0].stream_params);
+  if (pa_simple_read(sd[0].stream, tempRXBuffer,sizeof(qint16)*DOWNSAMPLESIZE, &err) <0)
+  {
+    errorHandler("PulseAudio read error",QString(pa_strerror(err)));
+    return -1;
+  }
+  return  DOWNSAMPLESIZE;
+}
+
+int soundPulse::write(uint numFrames)
+{
+  int err;
+  if(numFrames!=0)
+    {
+      if (pa_simple_write(sd[1].stream, tempTXBuffer,sizeof(quint32)*numFrames, &err) <0)
+      {
+        errorHandler("PulseAudio write error",QString(pa_strerror(err)));
+        return -1;
+      }
+    }
+  return numFrames;
+}
+
+
+
+void soundPulse::flushCapture()
+{
+  int err=PA_OK;
+  pa_usec_t t = pa_simple_get_latency(sd[0].stream, &err);
+  if (t && err == PA_OK)
+  {
+    size_t bytes = pa_usec_to_bytes(t, &sd[0].stream_params);
+    while (bytes > sizeof(qint16)*PERIODSIZE)
+    {
+      pa_simple_read(sd[0].stream, tempRXBuffer,sizeof(qint16)*PERIODSIZE, &err);
+      if (err != PA_OK)
+        break;
+      bytes -= sizeof(qint16)*PERIODSIZE;
+    }
+    if (bytes)
+      pa_simple_read(sd[0].stream, tempRXBuffer, bytes, &err);
+  }
+
+  //  int err;
+  //  if(pa_simple_flush (sd[0].stream, &err)<0)
+  //  {
+  //    errorHandler("flush: ", QString(pa_strerror(err)));
+  //  }
+}
+
+void soundPulse::flushPlayback()
+{
+  int err;
+  if(pa_simple_flush (sd[1].stream, &err)<0)
+  {
+    errorHandler("flush: ", QString(pa_strerror(err)));
+  }
+}
+
+void soundPulse::closeDevices()
+{
+  if (sd[0].stream) pa_simple_free(sd[0].stream);
+  sd[0].stream=0;
+  if (sd[1].stream) pa_simple_free(sd[1].stream);
+  sd[1].stream=0;
+  msleep(1000);
+}
+
+
+
diff --git a/qsstv/sound/soundpulse.h b/qsstv/sound/soundpulse.h
new file mode 100644
index 0000000..50e2f81
--- /dev/null
+++ b/qsstv/sound/soundpulse.h
@@ -0,0 +1,43 @@
+#ifndef SOUNDPULSE_H
+#define SOUNDPULSE_H
+
+
+#include "soundbase.h"
+
+#define CAPTFRAGSIZE 512
+//#define PLAYLENGTH   512
+#define PLAYLENGTH   (4096*5)
+
+/*! \file soundio.h */
+
+
+#include <pulse/simple.h>
+#include <pulse/error.h>
+
+class soundPulse:public soundBase
+{
+public:
+  soundPulse();
+  ~soundPulse();
+  bool init(int samplerate);
+  int read(int &countAvailable);
+  int write(uint numFrames);
+protected:
+  void flushCapture();
+  void flushPlayback();
+  void closeDevices();
+private:
+  struct stream_data {
+    pa_simple*	stream;
+    pa_sample_spec	stream_params;
+    pa_buffer_attr  buffer_attrs;
+    pa_stream_direction_t dir;
+    double		src_ratio;
+    size_t		blocksize;
+  } sd[2];
+
+
+
+
+};
+#endif // SOUNDPULSE_H
diff --git a/qsstv/sound/waterfalltext.cpp b/qsstv/sound/waterfalltext.cpp
index 7e841b1..918622e 100644
--- a/qsstv/sound/waterfalltext.cpp
+++ b/qsstv/sound/waterfalltext.cpp
@@ -1,20 +1,22 @@
 #include "waterfalltext.h"
-#include "qsstvglobal.h"
+#include "appglobal.h"
 #include "configparams.h"
+#include "imageviewer.h"
+
+#include "filters.h"
+#include "supportfunctions.h"
+#include "drm.h"
+
 #include "math.h"
-#include "widgets/imageviewer.h"
 #include <QPainter>
 #include <QDebug>
-#include "dsp/filter.h"
-#include "dsp/filterparam.h"
-#include "utils/supportfunctions.h"
 
 #define FREQ_AMPLITUDE 16E3
 #define FREQ_OFFSET 350.0
 #define FREQ_MAX 2600.
 
-#define FONTSIZE 13
-#define FONTNAME "Arial"
+//#define FONTSIZE 13
+//#define FONTNAME "Arial"
 
 waterfallText::waterfallText()
 {
@@ -26,6 +28,9 @@ waterfallText::waterfallText()
 
 }
 
+/**
+  \todo:: txFilter not used
+ */
 
 waterfallText::~waterfallText()
 {
@@ -43,33 +48,31 @@ void waterfallText::init()
   double binSize;
   if(phr!=NULL) delete phr;
   if(phi!=NULL) delete phi;
-  fftLength=TXSTRIPE*SUBSAMPLINGRATIO/2;
+  fftLength=TXSTRIPE*SUBSAMPLINGFACTOR/2;
   samplingrate=BASESAMPLERATE;
   binSize=(double)(BASESAMPLERATE)/((double)fftLength);
-  txFilter= new filter(TXSTRIPE*SUBSAMPLINGRATIO,wfFilter,TXWFNUMTAPS,0,BASESAMPLERATE,true,1);
+  txFilter= new wfFilter(TXSTRIPE);
   out = (fftw_complex *) fftw_malloc(sizeof(fftw_complex)*fftLength);
   dataBuffer = (fftw_complex *) fftw_malloc(sizeof(fftw_complex)*fftLength);
   outFiltered = new DSPFLOAT [fftLength];
   audioBuf = new DSPFLOAT [fftLength];
-   // create the fftw plan
+  // create the fftw plan
   plan = fftw_plan_dft_1d(fftLength, dataBuffer, out, FFTW_BACKWARD, FFTW_ESTIMATE);
   imageWidth=(FREQ_MAX-FREQ_OFFSET)/binSize;
 
-//  imageWidth=200;
+  //  imageWidth=200;
   startFreqIndex=(int)round(FREQ_OFFSET/binSize);
 
-
-
   //Chirp
   phr=new double[imageWidth];
   phi=new double[imageWidth];
   amplitude=FREQ_AMPLITUDE/sqrt(imageWidth);
   for(i=0;i<imageWidth;i++)
-    {
-      ph=(-M_PI/imageWidth)*i*i;
-      phr[i]=amplitude*cos(ph);
-      phi[i]=amplitude*sin(ph);
-    }
+  {
+    ph=(-M_PI/imageWidth)*i*i;
+    phr[i]=amplitude*cos(ph);
+    phi[i]=amplitude*sin(ph);
+  }
 
 
 
@@ -77,13 +80,11 @@ void waterfallText::init()
 
 double waterfallText::getDuration(QString txt)
 {
-  QString t=convert(txt);
-
-  if(t!=NULL)
+  if(!txt.isNull())
     {
-      setupImage(t);
+      setupImage(convert(txt));
     }
-  return ((double)(line*2*fftLength))/(double)samplingrate;
+  return ((double)(line*3*fftLength))/(double)samplingrate;
 }
 
 void waterfallText::setText(QString txt)
@@ -99,50 +100,36 @@ DSPFLOAT * waterfallText::nextLine()
   int i,freqIndex;
 
   if(dLine%3==0)
+  {
+    line--;
+    if(line<0)
+    {
+      return NULL;
+    }
+
+    addToLog(QString("sendingline %1").arg(line),LOGSYNTHES);
+    cPtr=(QRgb *)image.scanLine(line);
+    for(i=0;i<fftLength;i++)
+    {
+      dataBuffer[i][0]=0.0;
+      dataBuffer[i][1]=0.0;
+    }
+
+    for(i=0;i<imageWidth;i++)
+    {
+      freqIndex=i+startFreqIndex;
+      if((cPtr[i]&0xffffff)!=0)
+      {
+        dataBuffer[freqIndex][0]= phr[i];
+        dataBuffer[freqIndex][1]= phi[i];
+      }
+    }
+    fftw_execute(plan);
+    for(i=0;i<fftLength;i++)
     {
-      line--;
-      if(line<0)
-        {
-          return NULL;
-        }
-
-      addToLog(QString("sendingline %1").arg(line),LOGSYNTHES);
-      cPtr=(QRgb *)image.scanLine(line);
-      for(i=0;i<fftLength;i++)
-        {
-        dataBuffer[i][0]=0.0;
-        dataBuffer[i][1]=0.0;
-        }
-
-      for(i=0;i<imageWidth;i++)
-        {
-          freqIndex=i+startFreqIndex;
-          if((cPtr[i]&0xffffff)!=0)
-            {
-              dataBuffer[freqIndex][0]= phr[i];
-              dataBuffer[freqIndex][1]= phi[i];
-            }
-        }
-      fftw_execute(plan);
-      for(i=0;i<fftLength;i++)
-        {
-          outFiltered[i]=(DSPFLOAT) out[i][0];
-        }
-//        arrayDump(QString("wf_fil"),outFiltered,32,true);
-//      txFilter->process(outFiltered,audioBuf,fftLength);
+      outFiltered[i]=(DSPFLOAT) out[i][0];
     }
-//  for (i=0; i <10; i++)
-//    {
-//      outFiltered[i] = (audioBuf[i]*exp(-(10-i)*0.100));
-//    }
-//  for (i=10; i <fftLength-10; i++)
-//    {
-//      outFiltered[i]=audioBuf[i];
-//    }
-//  for (i=fftLength-10; i <fftLength; i++)
-//    {
-//      outFiltered[i]= (audioBuf[i]*exp((fftLength-10 -i)*0.1));
-//    }
+  }
   dLine++;
   return outFiltered;
 }
@@ -161,7 +148,7 @@ void waterfallText::setupImage(QString txt)
   image.fill(Qt::black);
   p.begin(&image);
   p.setPen(pen);
-  p.setFont(QFont(FONTNAME,FONTSIZE,QFont::Light));
+  p.setFont(QFont(wfFont,wfFontSize,QFont::Light));
   rct=p.boundingRect(QRect(0,0,imageWidth,30),Qt::AlignTop|Qt::AlignCenter,txt);
   p.end();
   height=rct.height();
@@ -170,7 +157,7 @@ void waterfallText::setupImage(QString txt)
   image.fill(Qt::black);
   p.begin(&image);
   p.setPen(pen);
-  p.setFont(QFont(FONTNAME,FONTSIZE,QFont::Light));
+  p.setFont(QFont(wfFont,wfFontSize,QFont::Light));
   p.drawText(QRectF(0,0,width,height),Qt::AlignCenter,txt);
   p.end();
   line=image.height();
@@ -180,11 +167,10 @@ void waterfallText::setupImage(QString txt)
 QString  waterfallText::convert(QString txt)
 {
   mexp.clear();
- mexp.addConversion('m',myCallsign);
- mexp.addConversion('s',QString::number(lastAvgSNR,'g',2));
- QString t=mexp.convert(txt);
- return t;
-}
-
-
+  mexp.addConversion('m',myCallsign);
+  mexp.addConversion('s',QString::number(lastAvgSNR,'g',2));
+  mexp.addConversion('c',lastReceivedCall);
 
+  QString t=mexp.convert(txt);
+  return t;
+}
diff --git a/qsstv/sound/waterfalltext.h b/qsstv/sound/waterfalltext.h
index 57bf55a..a2d75e9 100644
--- a/qsstv/sound/waterfalltext.h
+++ b/qsstv/sound/waterfalltext.h
@@ -1,14 +1,13 @@
 #ifndef WATERFALLTEXT_H
 #define WATERFALLTEXT_H
-#include "qsstvdefs.h"
-//#include <complex.h>
+#include "appdefs.h"
 #include "fftw3.h"
 #include <QString>
 #include <QImage>
-#include "utils/macroexpansion.h"
+#include "macroexpansion.h"
 
 class imageViewer;
-class filter;
+class wfFilter;
 
 
 class waterfallText
@@ -21,7 +20,7 @@ public:
   QImage *getImagePtr() {return ℑ}
  DSPFLOAT *nextLine();
  int getLength() {return fftLength;}
- double getDuration(QString txt=NULL);
+ double getDuration(QString txt=QString());
 private:
   int fftLength;
   int samplingrate;
@@ -37,7 +36,7 @@ private:
   int width;
   int height;
   int line;
-  filter *txFilter;
+  wfFilter *txFilter;
   QImage image;
   int dLine;
   int startFreqIndex;
diff --git a/qsstv/sound/wavio.cpp b/qsstv/sound/wavio.cpp
index 1993a82..ab34701 100644
--- a/qsstv/sound/wavio.cpp
+++ b/qsstv/sound/wavio.cpp
@@ -20,11 +20,11 @@
  ***************************************************************************/
 
 #include "wavio.h"
-#include "qsstvglobal.h"
-#include <qfiledialog.h>
+#include "appglobal.h"
 #include "configparams.h"
-#include "utils/supportfunctions.h"
+#include "utils/dirdialog.h"
 #include "unistd.h"
+#include <qfiledialog.h>
 
 /**
   constructor: creates a waveIO instance
@@ -63,27 +63,27 @@ bool  wavIO::openFileForRead(QString fname,bool ask)
   QString tmp;
 
   if (ask)
-    {
-      dirDialog d((QWidget *)mainWindowPtr,"Wave file");
-      QString s=d.openFileName(audioPath,"*");
-      if (s==QString::null) return false;
-      if (s.isEmpty()) return false;
-      inopf.setFileName(s);
-    }
+  {
+    dirDialog d((QWidget *)mainWindowPtr,"Wave file");
+    QString s=d.openFileName(audioPath,"*");
+    if (s==QString::null) return false;
+    if (s.isEmpty()) return false;
+    inopf.setFileName(s);
+  }
   else
-    {
-      inopf.setFileName(fname);
-    }
+  {
+    inopf.setFileName(fname);
+  }
   if(!inopf.open(QIODevice::ReadOnly))
-    {
-      return false;
-    }
+  {
+    return false;
+  }
   reading=true;
   if(inopf.read(&waveHeader.chunkID[0],sizeof(sWave))!=sizeof(sWave))
-    {
-      closeFile();
-      return false;
-    }
+  {
+    closeFile();
+    return false;
+  }
 
 
   // check the header
@@ -91,27 +91,26 @@ bool  wavIO::openFileForRead(QString fname,bool ask)
        ||(!checkString(waveHeader.format,"WAVE"))
        ||(!checkString(waveHeader.subChunk1ID,"fmt "))
        ||(!checkString(waveHeader.subChunk2ID,"data")))
-    {
-      addToLog("wavio read header error",LOGALL);
-      closeFile();
-      return false;
-    }
+  {
+    addToLog("wavio read header error",LOGALL);
+    closeFile();
+    return false;
+  }
 
   if( (waveHeader.subChunk1Size!=16)
       ||(waveHeader.audioFormat!=1)
-      ||(waveHeader.numChannels>MAXNUMCHANNELS)
+      ||(waveHeader.numChannels>STEREOCHANNEL)
       ||(waveHeader.sampleRate!=samplingrate)
       //      ||(waveHeader.byteRate!=sizeof(SOUNDFRAME)*samplingrate)
       ||(waveHeader.blockAlign!=waveHeader.numChannels*2)
       ||(waveHeader.bitsPerSample!=16))
-    {
-      addToLog("wavio read header error, not supported",LOGALL);
-      closeFile();
-      return false;
-    }
+  {
+    addToLog("wavio read header error, not supported",LOGALL);
+    closeFile();
+    return false;
+  }
   numberOfChannels=waveHeader.numChannels;
-  numberOfSamples=waveHeader.subChunk2Size/(2*numberOfChannels);
-
+  numberOfSamples=waveHeader.subChunk2Size/(2*numberOfChannels);  // number of mono or stereo samples
   samplesRead=0;
   return true;
 }
@@ -121,52 +120,40 @@ bool  wavIO::openFileForRead(QString fname,bool ask)
 
   \param dPtr pointer to buffer for SOUNDFRAME type samples.
   \param numSamples  number of samples to read
-  \return returns the nummber of samples read. -1 is returned if the end of the file is reached. The file is then automatically closed.
+  \return returns the number of samples read. -1 is returned if there is an error, 0 is returned on end of the file else the numeber of samples read.
+
+The file will be closed on reaching the end of file;
+
+Output is always in mono.
 */
 
-int  wavIO::read(SOUNDFRAME *dPtr ,uint numSamples)
+int  wavIO::read(short int *dPtr ,uint numSamples)
 {
   int i,llen,result;
-  quint16 *tempBuf;
+  qint16 *tempBuf;
 
   if(!inopf.isOpen())
-    {
-      addToLog("wavio not open during read",LOGALL);
-      return -2;
-    }
-  if(numberOfSamples<=samplesRead)
-    {
-      closeFile();
-      return -1;
-    }
-  llen=numSamples*sizeof(quint16)*numberOfChannels;
-  if(sizeof(SOUNDFRAME)/numberOfChannels==sizeof(quint16))
-    {
-      //we do not need conversion
-       result=inopf.read((char*)dPtr,llen);
-    }
+  {
+    addToLog("wavio not open during read",LOGALL);
+    return -1;
+  }
+
+  llen=numSamples*sizeof(quint16)*numberOfChannels; // lenght in bytes
+  if(waveHeader.numChannels==1)
+  {
+    result=inopf.read((char*)dPtr,llen); //we do not need conversion
+  }
   else
+  {
+    tempBuf=new qint16[llen/2];
+    result=inopf.read((char*)tempBuf,llen);
+    for(i=0;i<(result/4);i++)
     {
-      tempBuf=new quint16[llen/2];
-      if(numberOfChannels==1) // if input is mono -> output in stereo
-        {
-          quint16 *tempBuf=new quint16[llen/2];
-          result=inopf.read((char*)tempBuf,llen);
-          for(i=0;i<(result/2);i++)
-            {
-              dPtr[i]=tempBuf[i]+(tempBuf[i]<<16);
-            }
-          delete tempBuf;
-        }
-      else // if input is stereo  -> output in mono (SOUNDFRAME is quint16)
-        {
-          result=inopf.read((char*)tempBuf,llen);
-          for(i=0;i<(result/4);i++)
-            {
-              dPtr[i]=(tempBuf[2*i]+tempBuf[2*i+1])/2;
-            }
-        }
+      dPtr[i]=tempBuf[2*i];
     }
+    delete [] tempBuf;
+
+  }
   if(result==0) inopf.close();
   samplesRead+=result/(sizeof(quint16)*numberOfChannels);
   return result/(sizeof(quint16)*numberOfChannels);
@@ -185,19 +172,19 @@ bool  wavIO::openFileForWrite(QString fname,bool ask,bool isStereo)
 {
   QFileInfo fin;
   if (ask)
-    {
-      dirDialog d((QWidget *)mainWindowPtr,"wave IO");
-      QString fn=d.saveFileName(audioPath,"*.wav","wav");
-      inopf.setFileName(fn);
-    }
+  {
+    dirDialog d((QWidget *)mainWindowPtr,"wave IO");
+    QString fn=d.saveFileName(audioPath,"*.wav","wav");
+    inopf.setFileName(fn);
+  }
   else
-    {
-      inopf.setFileName(fname);
-    }
+  {
+    inopf.setFileName(fname);
+  }
   if(!inopf.open(QIODevice::WriteOnly|QIODevice::Truncate))
-    {
-      return false;
-    }
+  {
+    return false;
+  }
   numberOfSamples=0;
   if(isStereo) numberOfChannels=2;
   else numberOfChannels=1;
@@ -232,38 +219,38 @@ bool  wavIO::write(quint16 *dPtr, uint numSamples, bool isStereo)
 
 
   if((!writing)&&(numSamples!=0))
-    {
-      addToLog("wavio not open during write",LOGALL);
-      return true;
-    }
+  {
+    addToLog("wavio not open during write",LOGALL);
+    return true;
+  }
   if((!writing)&&(numSamples==0)) return true;
   if(numSamples==0)
-    {
-      addToLog(QString("wavio write close samples=%1").arg(numberOfSamples),LOGWAVIO);
-      inopf.flush();
-      writeHeader();
-      closeFile();
-      return true;
-    }
+  {
+    addToLog(QString("wavio write close samples=%1").arg(numberOfSamples),LOGWAVIO);
+    inopf.flush();
+    writeHeader();
+    closeFile();
+    return true;
+  }
 
   if((sizeof(SOUNDFRAME)==2) && (isStereo))  // we need stereo output and input is mono
+  {
+    tempBufPtr=new quint16 [numSamples*2];
+    tmpPtr=tempBufPtr;
+    for(i=0;i<numSamples;i++)
     {
-      tempBufPtr=new quint16 [numSamples*2];
-      tmpPtr=tempBufPtr;
-      for(i=0;i<numSamples;i++)
-        {
-          tempBufPtr[i*2]=dPtr[i];
-          tempBufPtr[i*2+1]=0;
-        }
+      tempBufPtr[i*2]=dPtr[i];
+      tempBufPtr[i*2+1]=0;
     }
+  }
 
   if(inopf.write((char *)tmpPtr,len)!=len)
-    {
-      addToLog("wavio write error",LOGALL);
-      closeFile();
-      if(tempBufPtr) delete tempBufPtr;
-      return false;
-    }
+  {
+    addToLog("wavio write error",LOGALL);
+    closeFile();
+    if(tempBufPtr) delete tempBufPtr;
+    return false;
+  }
   numberOfSamples+=numSamples;
   addToLog(QString("wavio write:%1 total samples=%2").arg(numSamples).arg(numberOfSamples),LOGWAVIO);
   if(tempBufPtr) delete tempBufPtr;
@@ -310,9 +297,9 @@ void wavIO::initHeader()
 bool  wavIO::checkString(char *str,const char *cstr)
 {
   for (int i=0;i<4;i++)
-    {
-      if (str[i]!=cstr[i]) return false;
-    }
+  {
+    if (str[i]!=cstr[i]) return false;
+  }
   return true;
 }
 
@@ -322,12 +309,12 @@ bool  wavIO::writeHeader()
   waveHeader.subChunk2Size=numberOfSamples*sizeof(quint16)*numberOfChannels;
   lseek(inopf.handle(),0,SEEK_SET); //position at beginning
   if((err=inopf.write(&waveHeader.chunkID[0],sizeof(sWave)))!=sizeof(sWave))
-    {
+  {
 
-      addToLog(QString("wavio write header error %1").arg(err),LOGWAVIO);
-      closeFile();
-      return false;
-    }
+    addToLog(QString("wavio write header error %1").arg(err),LOGWAVIO);
+    closeFile();
+    return false;
+  }
   inopf.flush();
   lseek(inopf.handle(),0,SEEK_END); //position at beginning
   addToLog(QString("wavio write header %1 %2 %3 %4").arg(waveHeader.chunkID[0]).arg(waveHeader.chunkID[1]).arg(waveHeader.chunkID[2]).arg(waveHeader.chunkID[3]),LOGWAVIO);
diff --git a/qsstv/sound/wavio.h b/qsstv/sound/wavio.h
index a369716..219dfcf 100644
--- a/qsstv/sound/wavio.h
+++ b/qsstv/sound/wavio.h
@@ -1,8 +1,8 @@
 #ifndef WAVEIO_H
 #define WAVEIO_H
 
-#include <qfile.h>
-#include "qsstvdefs.h"
+#include "appglobal.h"
+#include <QFile>
 
 /*! a WAVE format structure
 
@@ -81,7 +81,7 @@ public:
 	~wavIO();
 	bool openFileForRead(QString fname,bool ask);
   bool openFileForWrite(QString fname, bool ask, bool isStereo);
-  int  read (quint32 *dPtr, uint len);
+  int  read (short int *dPtr, uint len);
   bool write(quint16 *dPtr, uint len, bool isStereo);
 	void setSamplingrate(int sr) {samplingrate=sr;}
   int getNumberOfChannels(){return numberOfChannels;}
diff --git a/qsstv/sstv/cw.cpp b/qsstv/sstv/cw.cpp
index 15be797..8265924 100644
--- a/qsstv/sstv/cw.cpp
+++ b/qsstv/sstv/cw.cpp
@@ -16,7 +16,7 @@
  ***************************************************************************/
 #include "cw.h"
 #include <ctype.h>
-#include "qsstvglobal.h"
+#include "appglobal.h"
 #include "configparams.h"
 
 
@@ -38,8 +38,8 @@ static  eCWResult result;
 //  const char *s;
 
 static struct {
-	char key;
-	const char	*cw;
+  char key;
+  const char	*cw;
 } charTable[] = 
 {
   {'A',	".-"	}, {'B',"-..."  },{'C',	"-.-." },
@@ -68,7 +68,7 @@ void initCW(QString cwTxt)
 { 
   cwState=CWNEW;
   dotSpacing=1.2/(float)cwWPM;
-	cwString=cwTxt;
+  cwString=cwTxt;
 }
 
 const char *charLookupCW(const char a)
@@ -76,14 +76,14 @@ const char *charLookupCW(const char a)
   char b;
   int i=0;;
   b=toupper(a);
-	dotIndex=0;
+  dotIndex=0;
   while (charTable[i].key!=0)
     {
       if(charTable[i].key==b)
-				{
-					
-	  			return (charTable[i].cw);
-				}
+        {
+
+          return (charTable[i].cw);
+        }
       i++;
     }
   return NULL;
@@ -107,6 +107,17 @@ bool nextSymbolCW(float &duration)
   return true;
 }
 
+float getCWDuration()
+{
+  float tim=0;
+  float tone,duration;
+  tone=0;
+  while(sendTextCW(tone,duration))
+    {
+      tim+=duration;
+    }
+  return tim;
+}
 
 bool sendTextCW(float &tone,float &duration)
 {
@@ -114,96 +125,96 @@ bool sendTextCW(float &tone,float &duration)
   do
     {
       switch (cwState)
-			{
-				case CWNEW:
-	  			{
-	    			charIndex=0;
-	    			if (cwString[0]==0)
-	      			{
-								result=CWfalse;
-	      			}
-	    			cwState=CWNEXTCHAR;
-	  			}
-	  		break;
-				case CWNEXTCHAR:
-	  			{
-	    			if(cwString[charIndex]==' ')
-	      			{
-								charIndex++;
-								cwState=CWWORDSPACING;
-	      			}
-	    			else
-	      			{
+        {
+        case CWNEW:
+          {
+            charIndex=0;
+            if (cwString[0]==0)
+              {
+                result=CWfalse;
+              }
+            cwState=CWNEXTCHAR;
+          }
+        break;
+        case CWNEXTCHAR:
+          {
+            if(cwString[charIndex]==' ')
+              {
+                charIndex++;
+                cwState=CWWORDSPACING;
+              }
+            else
+              {
                 dotPtr=charLookupCW(cwString[charIndex++].toLatin1());
-								if (dotPtr==NULL)
-		  						{
-		  							cwState=CWEND;
-		  						}
-								else
-		  						{
-		    						dotIndex=0;
-		    						cwState=CWNEXTDOT;
-		  						}
-	      			}
-	  			}
-	  		break;
-				case CWNEXTDOT:
-	  			{
-	    			if(nextSymbolCW(duration))
-	      			{
-								tone=(float)cwTone;
-								cwState=CWDOTSPACING;
-								result=CWtrue;
-	      			}
-	    			else
-	      			{
-								cwState=CWCHARSPACING;
-	      			}
-	  			}
-	  		break;
-				case CWDOTSPACING:
-	  			{
-	    			tone=0;
-	    			duration=dotSpacing;
-	    			cwState=CWNEXTDOT;
-	    			result=CWtrue;
-	  			}
-	  		break;
-				case CWCHARSPACING:
-	  			{
-	    			tone=0;
-	    			duration=2*dotSpacing;  // we already had a dotspace
-	    			cwState=CWNEXTCHAR;
-	   				result=CWtrue;
-	  			}
-	  		break;
-				case CWWORDSPACING:
-	  			{
-	    			tone=0;
-	    			duration=4*dotSpacing; // we already had a charspace
-	    			cwState=CWNEXTCHAR;
-	    			result=CWtrue;
-	  			}
-	  		break;
-	
-				case CWEND:
-	  			{
-	    			tone=0;
-	    			duration=7*dotSpacing;
-	    			cwState=CWFINISHED;
-	    			result=CWtrue;
-	  			}
-	  		break;
-				case CWFINISHED:
-	  			{
-	    			result=CWfalse;
-	  			}
-	  		break;
-	  
-			}
+                if (dotPtr==NULL)
+                  {
+                    cwState=CWEND;
+                  }
+                else
+                  {
+                    dotIndex=0;
+                    cwState=CWNEXTDOT;
+                  }
+              }
+          }
+        break;
+        case CWNEXTDOT:
+          {
+            if(nextSymbolCW(duration))
+              {
+                tone=(float)cwTone;
+                cwState=CWDOTSPACING;
+                result=CWtrue;
+              }
+            else
+              {
+                cwState=CWCHARSPACING;
+              }
+          }
+        break;
+        case CWDOTSPACING:
+          {
+            tone=0;
+            duration=dotSpacing;
+            cwState=CWNEXTDOT;
+            result=CWtrue;
+          }
+        break;
+        case CWCHARSPACING:
+          {
+            tone=0;
+            duration=2*dotSpacing;  // we already had a dotspace
+            cwState=CWNEXTCHAR;
+            result=CWtrue;
+          }
+        break;
+        case CWWORDSPACING:
+          {
+            tone=0;
+            duration=4*dotSpacing; // we already had a charspace
+            cwState=CWNEXTCHAR;
+            result=CWtrue;
+          }
+        break;
+
+        case CWEND:
+          {
+            tone=0;
+            duration=7*dotSpacing;
+            cwState=CWFINISHED;
+            result=CWtrue;
+          }
+        break;
+        case CWFINISHED:
+          {
+            result=CWfalse;
+          }
+        break;
+
+        }
     }
-	while(result==CWIDLE);
-	return (result==CWtrue);
+  while(result==CWIDLE);
+  return (result==CWtrue);
 }
 
 
diff --git a/qsstv/sstv/cw.h b/qsstv/sstv/cw.h
index e19fb5d..79e8b62 100644
--- a/qsstv/sstv/cw.h
+++ b/qsstv/sstv/cw.h
@@ -21,7 +21,7 @@
 
 void initCW(QString cwTxt);
 bool sendTextCW(float &tone,float &duration);
-
+float getCWDuration();
 
 
 
diff --git a/qsstv/sstv/modes/modeavt.cpp b/qsstv/sstv/modes/modeavt.cpp
index 2816415..8a4022c 100644
--- a/qsstv/sstv/modes/modeavt.cpp
+++ b/qsstv/sstv/modes/modeavt.cpp
@@ -24,7 +24,7 @@
 #define WORDTIME (5.3108/32.)
 #define BITTIME (WORDTIME/17)
 
-modeAVT::modeAVT(esstvMode m,unsigned int len, bool tx):modeBase(m,len,tx)
+modeAVT::modeAVT(esstvMode m,unsigned int len, bool tx,bool narrowMode):modeBase(m,len,tx,narrowMode)
 {
   avtTrailerDetect=true;
   trailerState=D1900;
@@ -40,11 +40,11 @@ modeAVT:: ~modeAVT()
 
 void modeAVT::setupParams(double clock)
 {
-  visibleLineLength=(lineLength(mode,clock))/3.;
+  visibleLineLength=(getLineLength(mode,clock))/3.;
 }
 
 
-modeBase::eModeBase modeAVT::process(int *demod,unsigned int syncPos,bool goToSync)
+modeBase::eModeBase modeAVT::process(quint16 *demod,unsigned int syncPos,bool goToSync)
 {
   unsigned int i=0;
   unsigned char a,b;
@@ -100,7 +100,7 @@ modeBase::eModeBase modeAVT::process(int *demod,unsigned int syncPos,bool goToSy
                   if (count==0)
                     {
                       duration-=5;
-                      if((duration<(unsigned int)(0.011*rxClock)) && (duration>(unsigned int)(0.009*rxClock)))
+                      if((duration<(unsigned int)(0.011*rxClock/SUBSAMPLINGFACTOR)) && (duration>(unsigned int)(0.009*rxClock/SUBSAMPLINGFACTOR)))
                         {
                           bitCounter=0;
                           count=10;
@@ -117,7 +117,7 @@ modeBase::eModeBase modeAVT::process(int *demod,unsigned int syncPos,bool goToSy
                   debugState=stHALF;
                   count++;
                   code=0;
-                  if(count>=(unsigned int)(round((BITTIME/2)*rxClock))) trailerState=BITS;
+                  if(count>=(unsigned int)(round((BITTIME/2)*rxClock/SUBSAMPLINGFACTOR))) trailerState=BITS;
                 break;
                 case BITS:
                   debugState=stBITS+bitCounter;
@@ -134,7 +134,7 @@ modeBase::eModeBase modeAVT::process(int *demod,unsigned int syncPos,bool goToSy
                 case DELAYFULL:
                   debugState=stFULL;
                   count++;
-                  if(count>=(unsigned int)(round(BITTIME*rxClock))) trailerState=BITS;
+                  if(count>=(unsigned int)(round(BITTIME*rxClock/SUBSAMPLINGFACTOR))) trailerState=BITS;
                 break;
                 case CALCDELAY:
                   //check if
@@ -149,7 +149,7 @@ modeBase::eModeBase modeAVT::process(int *demod,unsigned int syncPos,bool goToSy
                       break;
                     }
                    a&=0x1F;
-                   delay=(unsigned int)(((31-a)*WORDTIME+BITTIME/2)*rxClock);
+                   delay=(unsigned int)(((31-a)*WORDTIME+BITTIME/2)*rxClock/SUBSAMPLINGFACTOR);
                    trailerState=WAITSTART;
                 break;
                 case WAITSTART:
@@ -257,7 +257,7 @@ modeBase::embState modeAVT::txSetupLine()
 				txDur=(unsigned int)rint(fp);
 				return MBTXGAP;
 			case 6:
-				txFreq=1200;
+        txFreq=syncFreq;
 				txDur=(unsigned int)rint(syncDuration);
 				return MBTXGAP;
 			default:
diff --git a/qsstv/sstv/modes/modeavt.h b/qsstv/sstv/modes/modeavt.h
index 534108a..dea7b55 100644
--- a/qsstv/sstv/modes/modeavt.h
+++ b/qsstv/sstv/modes/modeavt.h
@@ -30,9 +30,9 @@ class modeAVT : public modeBase
 {
   enum eTrailerState {D1900,D1900END,DELAYHALF,DELAYFULL,BITS,CALCDELAY,WAITSTART};
 public:
-  modeAVT(esstvMode m,unsigned int len,bool tx);
+  modeAVT(esstvMode m,unsigned int len,bool tx,bool narrowMode);
   ~modeAVT();
-  eModeBase process(int *demod, unsigned int syncPos=0, bool goToSync=false);
+  eModeBase process(quint16 *demod, unsigned int syncPos=0, bool goToSync=false);
 protected:
   embState rxSetupLine();
 	void calcPixelPositionTable(unsigned int colorLine,bool tx);
diff --git a/qsstv/sstv/modes/modebase.cpp b/qsstv/sstv/modes/modebase.cpp
index 7e31dd7..07ed441 100644
--- a/qsstv/sstv/modes/modebase.cpp
+++ b/qsstv/sstv/modes/modebase.cpp
@@ -19,27 +19,54 @@
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 #include "modebase.h"
-#include "qsstvglobal.h"
+#include "appglobal.h"
 #include "configparams.h"
-#include "dispatcher.h"
+#include "dispatch/dispatcher.h"
 #include "dsp/synthes.h"
 #include "rxwidget.h"
 #include "txwidget.h"
 #include <QApplication>
 
+const QString stateStr[modeBase::MBTXGAPROBOT+1]=
+{
+  "ERROR",
+  "SETUPLINE",
+  "PIXELS",
+  "SYNC",
+  "ENDOFLINE",
+  "EOIMAGE",
+  "RXWAIT",
+  "TXGAP",
+  "TXGAPROBOT"
+};
+
 
-modeBase::modeBase(esstvMode m,unsigned int len,bool tx)
+
+modeBase::modeBase(esstvMode m, unsigned int len, bool tx, bool narrowMode)
 {
-	mode=m;
-	transmit=tx;
-	length=len;
-	greenArrayPtr=NULL;
-	blueArrayPtr=NULL;
-	redArrayPtr=NULL;
-	yArrayPtr=NULL;
-	pixelArrayPtr=NULL;
-	pixelPositionTable=NULL;
-	debugStatePtr=NULL;
+  mode=m;
+  narrow=narrowMode;
+  if(narrow)
+    {
+     lowerFreq=2044;
+     syncFreq=1900;
+    }
+  else
+    {
+      lowerFreq=1500;
+      syncFreq=1200;
+    }
+
+
+  transmit=tx;
+  length=len;
+  greenArrayPtr=NULL;
+  blueArrayPtr=NULL;
+  redArrayPtr=NULL;
+  yArrayPtr=NULL;
+  pixelArrayPtr=NULL;
+  pixelPositionTable=NULL;
+  debugStatePtr=NULL;
   addToLog(QString("mb constructor mode=%1").arg((int) m),LOGMODES);
   if(transmit)
     {
@@ -55,216 +82,255 @@ modeBase::modeBase(esstvMode m,unsigned int len,bool tx)
 
 modeBase::~modeBase()
 {
-	deleteBuffers();
+  deleteBuffers();
 }
 
 
 /**
     \brief delete existing buffers
 
-		Deletes all buffers, and sets the pointers to NULL;
+    Deletes all buffers, and sets the pointers to NULL;
  */
 void modeBase::deleteBuffers()
 {
-	if(pixelPositionTable) delete [] pixelPositionTable;
-	if(greenArrayPtr) delete [] greenArrayPtr;
-	if(blueArrayPtr) delete [] blueArrayPtr;
-	if(redArrayPtr) delete [] redArrayPtr;
-	if(yArrayPtr) delete [] yArrayPtr;
-	if(debugStatePtr) delete [] debugStatePtr;
-	greenArrayPtr=blueArrayPtr=redArrayPtr=yArrayPtr=NULL;
+  if(pixelPositionTable) delete [] pixelPositionTable;
+  if(greenArrayPtr) delete [] greenArrayPtr;
+  if(blueArrayPtr) delete [] blueArrayPtr;
+  if(redArrayPtr) delete [] redArrayPtr;
+  if(yArrayPtr) delete [] yArrayPtr;
+  if(debugStatePtr) delete [] debugStatePtr;
+  greenArrayPtr=blueArrayPtr=redArrayPtr=yArrayPtr=NULL;
+  debugStatePtr=NULL;
+  pixelPositionTable=NULL;
 }
 
 /**
-	\brief initialize the selected mode
+  \brief initialize the selected mode
 
-	This function initializes all buffers and mode parameters. The localClock will be set to rxClk if rxClk is not zero in receive mode, else the rxClock of the configuration will be used. The localClock is always equal to the txClock from the configuration while in transmit mode;
-	\param[in] rxClk adjusted receive clock
+  This function initializes all buffers and mode parameters. The localClock will be set to rxClk if rxClk is not zero in receive mode, else the rxClock of the configuration will be used. The localClock is always equal to the txClock from the configuration while in transmit mode;
+  \param[in] rxClk adjusted receive clock
 */
 
 void modeBase::init(DSPFLOAT clk)
 {
-	if(!transmit)
-		{
-      if(clk==0.) localClock=clk;
-      else localClock=clk;
-		}
-	lineCounter=0;
-	displayLineCounter=0;
-	subLine=0;
-	sampleCounter=0;
+  localClock=clk;
+  lineCounter=0;
+  displayLineCounter=0;
+  subLine=0;
+  sampleCounter=0;
   setupSSTVLineTimeTable(mode,localClock,transmit);
-	state=MBSETUPLINE;
-	debugState=stHUNT;
-	deleteBuffers();
+  state=MBSETUPLINE;
+  debugState=stHUNT;
+  deleteBuffers();
   pixelPositionTable=new unsigned int[activeSSTVParam->numberOfPixels];
   greenArrayPtr=new unsigned char[activeSSTVParam->numberOfPixels];
   blueArrayPtr=new unsigned char[activeSSTVParam->numberOfPixels];
   redArrayPtr=new unsigned char[activeSSTVParam->numberOfPixels];
   yArrayPtr=new unsigned char[activeSSTVParam->numberOfPixels];
-	debugStatePtr=new unsigned char [length];
+  debugStatePtr=new unsigned int [length];
   for(unsigned int i=0;i<length;i++)
-  {
-    debugStatePtr[i]=0;
-  }
-	if(transmit)
-		{
+    {
+      debugStatePtr[i]=stHUNT;
+    }
+  if(transmit)
+    {
       fp=activeSSTVParam->fpt*localClock;
       bp=activeSSTVParam->bpt*localClock;
       blank=activeSSTVParam->blankt*localClock;
-		}
-	else
-		{
+    }
+  else
+    {
       fp=activeSSTVParam->fp*localClock;
       bp=activeSSTVParam->bp*localClock;
       blank=activeSSTVParam->blank*localClock;
-		}
+    }
   syncDuration=activeSSTVParam->sync*localClock;
-	setupParams(localClock);
+  setupParams(localClock);
   activeSSTVParam->pixelDuration=visibleLineLength/(double)activeSSTVParam->numberOfPixels;
-//  if(transmit)
-//    {
-//      txWidgetPtr->getImageViewerPtr()->createImage(QSize(activeSSTVParam->numberOfPixels,activeSSTVParam->numberOfDisplayLines),QColor(128,128,128));
-//    }
-//  else
-//    {
-//     rxWidgetPtr->getImageViewerPtr()->createImage(QSize(activeSSTVParam->numberOfPixels,activeSSTVParam->numberOfDisplayLines),QColor(128,128,128));
-//    }
+  avgSample=0;
+  avgSampleCounter=0;
+  isRunning=false;
+  //  if(transmit)
+  //    {
+  //      txWidgetPtr->getImageViewerPtr()->createImage(QSize(activeSSTVParam->numberOfPixels,activeSSTVParam->numberOfDisplayLines),QColor(128,128,128));
+  //    }
+  //  else
+  //    {
+  //     rxWidgetPtr->getImageViewerPtr()->createImage(QSize(activeSSTVParam->numberOfPixels,activeSSTVParam->numberOfDisplayLines),QColor(128,128,128));
+  //    }
 }
 
 
 void modeBase::redrawFast(bool r)
 {
-	fastRedraw=r;
-	if (!fastRedraw)
-		{
-			lineDisplayEvent *ce= new lineDisplayEvent(displayLineCounter);
+  fastRedraw=r;
+  if (!fastRedraw)
+    {
+      lineDisplayEvent *ce= new lineDisplayEvent(displayLineCounter);
       QApplication::postEvent( dispatcherPtr, ce );  // Qt will delete it when done
-		}
+    }
 }
 
-modeBase::eModeBase modeBase::process(int *demod,unsigned int syncPos,bool goToSync)
+modeBase::eModeBase modeBase::process(quint16 *demod,unsigned int syncPos,bool goToSync)
 {
-	unsigned int i=0;
-
-	if(goToSync)
-		{
-			if(syncPos >=length)
-				{
+  unsigned int i=0;
+  if(goToSync)
+    {
+      if(syncPos >=length)
+        {
           addToLog(QString("modebase:process: syncPos: %1 > length %2").arg(syncPos).arg(length),LOGMODES);
-					return MBENDOFIMAGE;
-				}
-			else
-				{
-            for(i=0;i<syncPos;i++)  ;//debugStatePtr[i]=debugState;
-				}
+          return MBENDOFIMAGE;
+        }
+      else
+        {
+          for(i=0;i<syncPos;i++)  ;//debugStatePtr[i]=debugState;
+        }
       rxSampleCounter+=syncPos;
-		}
-	for(;i<length;i++)
-		{
-			if(state==MBSETUPLINE)
-				{
-          state=rxSetupLine();
-					if(state==MBENDOFLINE)
-						{
-							showLine();
-							if (!fastRedraw)
-									{
-                    lineDisplayEvent *ce= new lineDisplayEvent(displayLineCounter);
-                    QApplication::postEvent( dispatcherPtr, ce );  // Qt will delete it when done
-									}
-							lineCounter++;
+    }
+  for(;i<length;i++)
+    {
+      if(state==MBSETUPLINE)
+        {
+          switchState(rxSetupLine());
+          if(state==MBENDOFLINE)
+            {
+              showLine();
+              if (!fastRedraw)
+                {
+                  lineDisplayEvent *ce= new lineDisplayEvent(displayLineCounter);
+                  QApplication::postEvent( dispatcherPtr, ce );  // Qt will delete it when done
+                }
+              lineCounter++;
               if (displayLineCounter>=activeSSTVParam->numberOfDisplayLines)
-								{
-						 			state=MBEOIMAGE;
-								}
-							else
-								{
-									subLine=0;
-                  state=rxSetupLine();
-								}
-						}
-					pixelCounter=0;
-					subLine++;
-				}
-			sample=demod[i];
-			debugStatePtr[i]=debugState;
-//			pos=(++pos&DSPINPUTINDEXMASK);
-			
-			switch(state)
-				{
-					case MBPIXELS:
-						if(getPixels())
-							{
-							 	state=MBSETUPLINE;
-							}
-					break;
-					case MBEOIMAGE:
-						return  MBENDOFIMAGE;
-					break;
-					case MBRXWAIT:
-						if(sampleCounter>=marker)
-							{
-              //  addToLog(QString("modebase:mbrxwait =%1").arg(sampleCounter+rxSampleCounter),LOGMODES);
-								state=MBSETUPLINE;
-							}
-					break;
-					case MBSYNC:
-						{
-							if(sampleCounter>=syncPosition)
-								{
+                {
+                  switchState(MBEOIMAGE);
+                }
+              else
+                {
+                  subLine=0;
+                  switchState(rxSetupLine());
+                }
+            }
+          pixelCounter=0;
+          subLine++;
+        }
+      sample=demod[i];
+      debugStatePtr[i]=debugState;
+
+      switch(state)
+        {
+        case MBPIXELS:
+          if(getPixels())
+            {
+              switchState(MBSETUPLINE);
+            }
+          break;
+        case MBEOIMAGE:
+          return  MBENDOFIMAGE;
+          break;
+        case MBRXWAIT:
+          if(sampleCounter>=marker)
+            {
+              switchState(MBSETUPLINE);
+            }
+          break;
+        case MBSYNC:
+          if(sampleCounter>=syncPosition)
+            {
               //    addToLog(QString("modebase:mbsync =%1").arg(sampleCounter+rxSampleCounter),LOGMODES);
-									state=MBSETUPLINE;
-								}
-						}
-					break;					
-					default:
-            addToLog(QString("unknown state in modeBase: %1 receive").arg((int)state),LOGMODES);
-					break;
-				}
-			sampleCounter++;
-		}
-	return MBRUNNING;
+              switchState(MBSETUPLINE);
+            }
+          break;
+        case MB1500:
+          {
+            // check ODD/EVEN Line for Robot 24/72
+            if(sampleCounter>=marker)
+              {
+                avgFreqGap/=avgFreqGapCounter;
+                if(avgFreqGap > 1900)
+                  {
+                    //                    subLine=10;
+                  }
+                switchState(MBSETUPLINE);
+              }
+            else
+              {
+                avgFreqGap+=demod[i];
+                avgFreqGapCounter++;
+              }
+          }
+          break;
+        case MB2300:
+          {
+            // check ODD/EVEN Line for Robot 24/72
+            if(sampleCounter>=marker)
+              {
+                avgFreqGap/=avgFreqGapCounter;
+                if(avgFreqGap < 1900)
+                  {
+                    //                    subLine=3;
+                  }
+                switchState(MBSETUPLINE);
+              }
+            else
+              {
+                avgFreqGap+=demod[i];
+                avgFreqGapCounter++;
+              }
+          }
+          break;
+        default:
+          addToLog(QString("unknown state in modeBase: %1 receive").arg((int)state),LOGMODES);
+          break;
+        }
+      sampleCounter++;
+    }
+  return MBRUNNING;
 }
 
 /**
-	\brief transfer pixels to pixelArrayPtr
+  \brief transfer pixels to pixelArrayPtr
 
-	This function checks the sampleCounter and stores the pixel in the pixelArray 
-	\return true if end of line (all pixels stored)
+  This function checks the sampleCounter and stores the pixel in the pixelArray
+  \return true if end of line (all pixels stored)
 */
 
 bool modeBase::getPixels()
 {
-	int color;
+  int color;
   double dev=activeSSTVParam->deviation*2;
   double fc=activeSSTVParam->subcarrier;
+  avgSample+=sample;
+  avgSampleCounter++;
   if(sampleCounter>=pixelPositionTable[pixelCounter]+(activeSSTVParam->pixelDuration/2))
     {
-//      addToLog(QString("modebase:getPixels[0] =%1").arg(sampleCounter+rxSampleCounter),LOGMODES);
-      color=128+(int)round(((double)sample-fc)*255./dev);
+      //      addToLog(QString("modebase:getPixels[0] =%1").arg(sampleCounter+rxSampleCounter),LOGMODES);
+      //      color=128+lround(((double)avgSample/(double)avgSampleCounter-fc)*255./dev);
+      color=128+lround(((double)sample-fc)*255./dev);
       if(color<0) color=0; if (color>255) color=255;
       pixelArrayPtr[pixelCounter]=(unsigned char)color;
       pixelCounter++;
+      avgSample=0;
+      avgSampleCounter=0;
       if(pixelCounter>=activeSSTVParam->numberOfPixels) return true;
-		}
-	return false; // indicate, it's not the end of the line
+    }
+  return false; // indicate, it's not the end of the line
 }	
 
 /**
-	\brief tranfer data to rxImage (mode depended)
+  \brief transfer data to rxImage (mode depended)
 
-	This function is the default behaviour. it calls combineColors(). This function must be reimplemented in the derived classes for all other colour modes.
+  This function is the default behaviour. it calls combineColors(). This function must be reimplemented in the derived classes for all other colour modes.
 */
 
 void modeBase::showLine()
 {
-	combineColors();
+  combineColors();
 }
 /**
-	\brief tranfer data to rxImage in RGB mode
+  \brief tranfer data to rxImage in RGB mode
 
-	Combine  R, G and B arrays (like in Martin mode) into the rxImage and advances the displayCounter 	
+  Combine  R, G and B arrays (like in Martin mode) into the rxImage and advances the displayCounter
 */
 
 void modeBase::combineColors()
@@ -274,7 +340,9 @@ void modeBase::combineColors()
   for(i=0;i<activeSSTVParam->numberOfPixels;i++)
     {
       pixelArray[i]=qRgb(redArrayPtr[i],greenArrayPtr[i],blueArrayPtr[i]);
-//        pixelArray[i]=qRgb(255,0,0);
+      //      pixelArray[i]=qRgb(greenArrayPtr[i],greenArrayPtr[i],greenArrayPtr[i]);
+
+      //        pixelArray[i]=qRgb(255,0,0);
     }
   displayLineCounter++;
 }
@@ -282,48 +350,48 @@ void modeBase::combineColors()
 
 
 /**
-	\brief tranfer data to rxImage in grayscale
+  \brief tranfer data to rxImage in grayscale
 
-	Black and White image transfer. greenArray contains the luminance info.
+  Black and White image transfer. greenArray contains the luminance info.
 */
 
 
 void modeBase::grayConversion()
 {
-	unsigned int i;
+  unsigned int i;
   QRgb *pixelArray=rxWidgetPtr->getImageViewerPtr()->getScanLineAddress(displayLineCounter);
   for(i=0;i<activeSSTVParam->numberOfPixels;i++)
-		{
-			pixelArray[i]=qRgb(greenArrayPtr[i],greenArrayPtr[i],greenArrayPtr[i]);
-		}
-	displayLineCounter++;
+    {
+      pixelArray[i]=qRgb(greenArrayPtr[i],greenArrayPtr[i],greenArrayPtr[i]);
+    }
+  displayLineCounter++;
 }
 
 /**
-	\brief tranfer data to rxImage in YUV mode
+  \brief tranfer data to rxImage in YUV mode
 
-	Combine  Y, U  and V arrays (like in PD modes) into the rxImage and advances the displayCounter 	
+  Combine  Y, U  and V arrays (like in PD modes) into the rxImage and advances the displayCounter
 */
 
 void modeBase::yuvConversion(unsigned char *array)
 {
-	unsigned int i;
-	int r,g,b;
+  unsigned int i;
+  int r,g,b;
   QRgb *pixelArray=rxWidgetPtr->getImageViewerPtr()->getScanLineAddress(displayLineCounter);
   for (i=0;i<activeSSTVParam->numberOfPixels;i++)
-		{
-			r=(100*array[i]+140*redArrayPtr[i]-17850)/100;
-			b=(100*array[i]+178*blueArrayPtr[i]-22695)/100;
-			g=(100*array[i]- 71*redArrayPtr[i]-33*blueArrayPtr[i]+13260)/100;
-			r=(r>255 ? 255 : r);
-			r=(r<0 ? 0 : r);
-		  b=(b>255 ? 255 : b);
-		  b=(b<0 ? 0 : b);
-		  g=(g>255 ? 255 : g);
-		  g=(g<0 ? 0 : g);
-		  pixelArray[i]=qRgb(r,g,b);
-		}
-	displayLineCounter++;
+    {
+      r=(100*array[i]+140*redArrayPtr[i]-17850)/100;
+      b=(100*array[i]+178*blueArrayPtr[i]-22695)/100;
+      g=(100*array[i]- 71*redArrayPtr[i]-33*blueArrayPtr[i]+13260)/100;
+      r=(r>255 ? 255 : r);
+      r=(r<0 ? 0 : r);
+      b=(b>255 ? 255 : b);
+      b=(b<0 ? 0 : b);
+      g=(g>255 ? 255 : g);
+      g=(g<0 ? 0 : g);
+      pixelArray[i]=qRgb(r,g,b);
+    }
+  displayLineCounter++;
 }
 
 modeBase::eModeBase modeBase::transmitImage(imageViewer *iv)
@@ -338,51 +406,54 @@ modeBase::eModeBase modeBase::transmitImage(imageViewer *iv)
   abortRun=false;
   while(!abortRun)
     {
+      isRunning=true;
       if(state==MBSETUPLINE)
         {
-          state=txSetupLine();
+          switchState(txSetupLine());
           subLine++;
           pixelCounter=0;
         }
       switch (state)
         {
-          case MBPIXELS:
-            {
-              addToLog(QString("MBPIXELS: samplcntr=%1").arg(sampleCounter),LOGMODES);
-              sendPixelBuffer();
-              state=MBSETUPLINE; // check for end of subline
-            }
+        case MBPIXELS:
+          {
+            addToLog(QString("MBPIXELS: samplcntr=%1").arg(sampleCounter),LOGMODES);
+            sendPixelBuffer();
+            switchState(MBSETUPLINE); // check for end of subline
+          }
           break;
-          case MBTXGAP:
-            {
-       //       addToLog(QString("MBTXGAP: samplcntr=%1").arg(sampleCounter),LOGMODES);
-              synthesPtr->sendSamples(txDur,txFreq); //expressed in samples;
-              sampleCounter+=txDur;
+        case MBTXGAP:
+          {
+            //       addToLog(QString("MBTXGAP: samplcntr=%1").arg(sampleCounter),LOGMODES);
+            synthesPtr->sendSamples(txDur,txFreq); //expressed in samples;
+            sampleCounter+=txDur;
 
-              state=MBSETUPLINE;
+            switchState(MBSETUPLINE);
           }
-        break;
+          break;
         case MBENDOFLINE:
           {
-       //     addToLog(QString("MBENDOFLINE samplcntr=%1 line: %2").arg(sampleCounter).arg(lineCounter),LOGMODES);
+            //     addToLog(QString("MBENDOFLINE samplcntr=%1 line: %2").arg(sampleCounter).arg(lineCounter),LOGMODES);
             if(++lineCounter>=activeSSTVParam->numberOfDataLines) state=MBEOIMAGE;
             else
               {
-               getLine();
-               state=MBSETUPLINE;
-               subLine=0;
+                getLine();
+                switchState(MBSETUPLINE);
+                subLine=0;
               }
 
-           }
-        break;
+          }
+          break;
         default:
-       //   addToLog(QString("default: samplcntr=%1").arg(sampleCounter),LOGMODES);
+          //   addToLog(QString("default: samplcntr=%1").arg(sampleCounter),LOGMODES);
           sampleCounter=0;
           return MBENDOFIMAGE;
-      }
+        }
     }
+  isRunning=false;
+  abortRun=false;
   addToLog("abortrun detected",LOGMODES);
-  return MBENDOFIMAGE;
+  return MBABORTED;
 }
 
 /**
@@ -393,8 +464,8 @@ modeBase::eModeBase modeBase::transmitImage(imageViewer *iv)
 
 void  modeBase::abort()
 {
-  addToLog("modebase: abort received",LOGMODES);
   abortRun=true;
+  addToLog("modebase: abort received",LOGMODES);
 }
 
 /**
@@ -407,21 +478,22 @@ void  modeBase::abort()
 void modeBase::sendPixelBuffer()
 {
   double f;
- // addToLog (QString(" sendPixelBuffer: pixelBuffer: %1").arg(QString::number((ulong)pixelArrayPtr,16)),LOGMODES);
+  // addToLog (QString(" sendPixelBuffer: pixelBuffer: %1").arg(QString::number((ulong)pixelArrayPtr,16)),LOGMODES);
   do
     {
-      f=1500.+((double)pixelArrayPtr[pixelCounter]*(2300.-1500.)/255.);
+      f=lowerFreq+((double)pixelArrayPtr[pixelCounter]*(2300-lowerFreq)/255.);
+
       while(sampleCounter<pixelPositionTable[pixelCounter])
         {
-          if(f>2300.) f=2300.;
-          if (f<1500.) f=1500.;
+          if(f>2300) f=2300;
+          if (f<lowerFreq) f=lowerFreq;
           synthesPtr->sendSample(f);
           sampleCounter++;
         }
       pixelCounter++;
     }
   while(pixelCounter<activeSSTVParam->numberOfPixels);
-//  addToLog(QString("modebase: lpw=%1").arg(sampleCounter),LOGMODES);
+  //  addToLog(QString("modebase: lpw=%1").arg(sampleCounter),LOGMODES);
 }
 
 /**
@@ -434,11 +506,11 @@ void modeBase::sendPixelBuffer()
 void modeBase::getLineY(bool evenodd)
 {
   // we will process 2 lines at a time
-//	QColor c;
+  //	QColor c;
   int tO,tE;
   int r,yo,ye,b;
   if ((displayLineCounter&1) && (evenodd)) return; // only even lines accepted
-//  txImPtr->createImage(QSize(activeSSTVParam->numberOfPixels,activeSSTVParam->numberOfDisplayLines),QColor(128,128,128));
+  //  txImPtr->createImage(QSize(activeSSTVParam->numberOfPixels,activeSSTVParam->numberOfDisplayLines),QColor(128,128,128),imageStretch);
   unsigned int *pixelArrayE=txImPtr->getScanLineAddress(displayLineCounter);
   if (evenodd)
     {
@@ -462,7 +534,7 @@ void modeBase::getLineY(bool evenodd)
     }
   else
     {
-//			addToLog(QString("getline=%1").arg(lineCounter),LOGMODES);
+      //			addToLog(QString("getline=%1").arg(lineCounter),LOGMODES);
       for (unsigned int i=0;i<activeSSTVParam->numberOfPixels;i++)
         {
           tE=pixelArrayE[i];
@@ -490,7 +562,7 @@ void modeBase::getLineBW()
 {
 
   unsigned int t;
-//  txImPtr->createImage(QSize(activeSSTVParam->numberOfPixels,activeSSTVParam->numberOfDisplayLines),QColor(128,128,128));
+  //  txImPtr->createImage(QSize(activeSSTVParam->numberOfPixels,activeSSTVParam->numberOfDisplayLines),QColor(128,128,128),imageStretch);
   unsigned int *pixelArray=txImPtr->getScanLineAddress(displayLineCounter);
   for (unsigned int i=0;i<activeSSTVParam->numberOfPixels;i++)
     {
@@ -512,11 +584,11 @@ void modeBase::getLine()
 {
   unsigned int t;
 
-//  txImPtr->createImage(QSize(activeSSTVParam->numberOfPixels,activeSSTVParam->numberOfDisplayLines),QColor(128,128,128));
-//  addToLog (QString(" Bufferpointers: green: %1 red %2, blue %3")
-//      .arg(QString::number((ulong)greenArrayPtr,16))
-//      .arg(QString::number((ulong)redArrayPtr,16))
-//      .arg(QString::number((ulong)blueArrayPtr,16)),LOGMODES);
+  //  txImPtr->createImage(QSize(activeSSTVParam->numberOfPixels,activeSSTVParam->numberOfDisplayLines),QColor(128,128,128));
+  //  addToLog (QString(" Bufferpointers: green: %1 red %2, blue %3")
+  //      .arg(QString::number((ulong)greenArrayPtr,16))
+  //      .arg(QString::number((ulong)redArrayPtr,16))
+  //      .arg(QString::number((ulong)blueArrayPtr,16)),LOGMODES);
   unsigned int *pixelArray=txImPtr->getScanLineAddress(displayLineCounter);
   for (unsigned int i=0;i<activeSSTVParam->numberOfPixels;i++)
     {
@@ -524,9 +596,15 @@ void modeBase::getLine()
       greenArrayPtr[i]=qGreen(t);
       redArrayPtr[i]=qRed(t);
       blueArrayPtr[i]=qBlue(t);
-//            greenArrayPtr[i]=255;
-//            redArrayPtr[i]=0;
-//            blueArrayPtr[i]=0;
+      //            greenArrayPtr[i]=255;
+      //            redArrayPtr[i]=0;
+      //            blueArrayPtr[i]=0;
     }
   displayLineCounter++;
 }
+
+void modeBase::switchState(embState  newState)
+{
+  addToLog(QString("%1 to %2").arg(stateStr[state]).arg(stateStr[newState]),LOGMODES);
+  state=newState;
+}
diff --git a/qsstv/sstv/modes/modebase.h b/qsstv/sstv/modes/modebase.h
index fdbbb00..48725a8 100644
--- a/qsstv/sstv/modes/modebase.h
+++ b/qsstv/sstv/modes/modebase.h
@@ -24,27 +24,31 @@
 #include "widgets/imageviewer.h"
 #include <math.h>
 
-#define stHUNT			 0
-#define stColorLine0 1 
-#define stColorLine1 2
-#define stColorLine2 3
-#define stColorLine3 4
-#define stColorLine4 5
-#define stG1				 6
-#define stG2				 7
-#define stRepTone		 8
-#define stWaitVIS		 9
-#define stSTART			10
-#define stWaitSync	11
-#define stFP				12
-#define stBP				13
-#define stSync			14
-#define st1900B			15
-#define st1900E     16
-#define stWAIT      17
-#define stHALF      18
-#define stFULL      19
-#define stBITS			20
+#define MODESTATESCALER 10
+
+#define stHUNT			 (0*MODESTATESCALER)
+#define stColorLine0 (10*MODESTATESCALER)
+#define stColorLine1 (20*MODESTATESCALER)
+#define stColorLine2 (30*MODESTATESCALER)
+#define stColorLine3 (40*MODESTATESCALER)
+#define stColorLine4 (50*MODESTATESCALER)
+#define stG1				 (60*MODESTATESCALER)
+#define stG1a				 (65*MODESTATESCALER)
+#define stG2				 (70*MODESTATESCALER)
+#define stG2a				 (75*MODESTATESCALER)
+#define stSync			 (80*MODESTATESCALER)
+#define stWaitVIS		 (90*MODESTATESCALER)
+#define stSTART			(100*MODESTATESCALER)
+#define stWaitSync	(110*MODESTATESCALER)
+#define stFP				(120*MODESTATESCALER)
+#define stBP				(130*MODESTATESCALER)
+#define stRepTone	  (140*MODESTATESCALER)
+#define st1900B			(150*MODESTATESCALER)
+#define st1900E     (160*MODESTATESCALER)
+#define stWAIT      (170*MODESTATESCALER)
+#define stHALF      (180*MODESTATESCALER)
+#define stFULL      (190*MODESTATESCALER)
+#define stBITS			(200*MODESTATESCALER)
 
 
 
@@ -53,9 +57,9 @@ class imageViewer;
 class modeBase
 {
 public:
-	enum embState {MBERROR,MBSETUPLINE,MBPIXELS,MBSYNC,MBENDOFLINE,MBEOIMAGE,MBRXWAIT,MBTXGAP,MBTXGAPROBOT};
-	enum eModeBase {MBRUNNING,MBENDOFIMAGE};
-	modeBase(esstvMode m,unsigned int len,bool tx);
+  enum embState {MBERROR,MBSETUPLINE,MBPIXELS,MBSYNC,MBENDOFLINE,MBEOIMAGE,MBRXWAIT,MB1500,MB2300,MBTXGAP,MBTXGAPROBOT};
+  enum eModeBase {MBRUNNING,MBENDOFIMAGE,MBABORTED};
+  modeBase(esstvMode m,unsigned int len,bool tx,bool narrowMode);
 	virtual ~modeBase();
   /*!
     \brief initialize mode specific items
@@ -66,15 +70,21 @@ public:
 	virtual void setupParams(double clock)=0;
 
 	virtual bool getPixels();
-	virtual unsigned long adjustSyncPosition(unsigned long syncPos)
+  virtual unsigned long adjustSyncPosition(unsigned long syncPos0,bool isRetrace)
 		{
-			return syncPos;
+     if(isRetrace) return syncPos0;
+     else return (syncPos0+10);
 		}
 
+//  virtual unsigned long retraceAdjust(unsigned long syncPos)
+//    {
+//      return syncPos-lineTimeTableRX[1];
+//    }
+
 	void redrawFast(bool r);
-  virtual eModeBase process(int *demod,unsigned int syncPos=0,bool goToSync=false);
+  virtual eModeBase process(quint16 *demod,unsigned int syncPos=0,bool goToSync=false);
   void init(DSPFLOAT clk);
-	unsigned char *debugStatePtr;
+  unsigned int *debugStatePtr;
   void abort();
   esstvMode getMode() { return mode;}
   eModeBase transmitImage(imageViewer *iv);
@@ -83,6 +93,8 @@ public:
   int receivedLines() {return displayLineCounter;}
   int imageLines() {return activeSSTVParam->numberOfDisplayLines;}
   int imagePixels() {return activeSSTVParam->numberOfPixels;}
+  bool aborted() {return !abortRun;}
+  bool isNarrow() {return narrow;}
 protected:
 	DSPFLOAT visibleLineLength;
 	esstvMode mode;
@@ -94,12 +106,13 @@ protected:
 	DSPFLOAT syncDuration;
 	DSPFLOAT localClock;
 
-  int sample;
+  quint16 sample;
   DSPFLOAT start;
   sSSTVParam *activeSSTVParam;
 
 
 	unsigned int marker;
+  DSPFLOAT markerFloat;
 	unsigned int syncPosition;
 	unsigned int syncEndPosition;
 	unsigned int lineCounter;
@@ -116,7 +129,9 @@ protected:
 	unsigned char *yArrayPtr;
 	unsigned char *pixelArrayPtr;
 	unsigned int *pixelPositionTable;
-	unsigned char debugState;
+  unsigned int debugState;
+  uint avgFreqGap;
+  uint avgFreqGapCounter;
 
 	DSPFLOAT txFreq;
 	unsigned int txDur;
@@ -145,13 +160,19 @@ protected:
   void getLineY(bool evenodd);
   void getLineBW();
   int rxSampleCounter;
+  DSPFLOAT syncFreq;
+  DSPFLOAT lowerFreq;
 
 
 private:
+  void switchState(embState  newState);
   void sendPixelBuffer();
   bool abortRun;
+  bool isRunning;
   imageViewer *txImPtr;
-
+  int avgSample;
+  int avgSampleCounter;
+  bool narrow;
 
 
 };
diff --git a/qsstv/sstv/modes/modebw.cpp b/qsstv/sstv/modes/modebw.cpp
index 9fc7ede..48b782f 100644
--- a/qsstv/sstv/modes/modebw.cpp
+++ b/qsstv/sstv/modes/modebw.cpp
@@ -31,7 +31,7 @@
 #include "modebw.h"
 #include "math.h"
 
-modeBW::modeBW(esstvMode m,unsigned int len, bool tx) : modeBase(m,len,tx)
+modeBW::modeBW(esstvMode m,unsigned int len, bool tx,bool narrowMode) : modeBase(m,len,tx,narrowMode)
 {
 }
 
@@ -43,7 +43,7 @@ modeBW::~modeBW()
 
 void modeBW::setupParams(double clock)
 {
-  visibleLineLength=(lineLength(mode,clock)-fp-bp-syncDuration);
+  visibleLineLength=(getLineLength(mode,clock)-fp-bp-syncDuration);
 }
 
 modeBase::embState modeBW::rxSetupLine()
@@ -51,11 +51,24 @@ modeBase::embState modeBW::rxSetupLine()
   start=lineTimeTableRX[lineCounter];
   switch(subLine)
 		{
-			case 0:
-				calcPixelPositionTable(GREENLINE,false);
-				pixelArrayPtr=greenArrayPtr;
-				return MBPIXELS;
-			case 1:
+    case 0:
+      debugState=stBP;
+      start=lineTimeTableRX[lineCounter];
+      markerFloat=start+bp;
+      marker=(unsigned int)round(markerFloat);
+      return MBRXWAIT;
+      case 1:
+      calcPixelPositionTable(GREENLINE,false);
+      markerFloat+=visibleLineLength;
+      debugState=stColorLine0;
+      pixelArrayPtr=greenArrayPtr;
+      return MBPIXELS;
+    case 2:
+      debugState=stFP;
+      markerFloat+=fp;
+      marker=(unsigned int)round(markerFloat);
+      return MBRXWAIT;
+    case 3:
 				debugState=stSync;
         syncPosition=(unsigned int)round(lineTimeTableRX[lineCounter+1]);
 				return MBSYNC;
@@ -72,21 +85,21 @@ void modeBW::showLine()
 }
 
 
-
-void modeBW::calcPixelPositionTable(unsigned int colorLine,bool tx)
+void  modeBW::calcPixelPositionTable(unsigned int colorLine,bool tx)
 {
-	unsigned int i;
-	int ofx=0;
-	if(tx) ofx=1;
-  double start;
-  if(tx) start=lineTimeTableTX[lineCounter];
-  else start=lineTimeTableRX[lineCounter];
-	debugState=colorLine;
-	start+=bp;
+  unsigned int i;DSPFLOAT lineStart=start;
+  int ofx=0;
+  if(tx) ofx=1;
+  switch (colorLine)
+    {
+    case GREENLINE:
+        lineStart+=bp;
+    break;
+    }
   for(i=0;i<activeSSTVParam->numberOfPixels;i++)
-		{
-      pixelPositionTable[i]=(unsigned int)round(start+(((float)(i+ofx)*visibleLineLength)/activeSSTVParam->numberOfPixels));
-		}
+    {
+      pixelPositionTable[i]=(unsigned int)round(lineStart+(((float)(i+ofx)*visibleLineLength)/activeSSTVParam->numberOfPixels));
+    }
 }
 
 modeBase::embState modeBW::txSetupLine()
@@ -99,15 +112,15 @@ modeBase::embState modeBW::txSetupLine()
 				pixelArrayPtr=greenArrayPtr;
 				return MBPIXELS;
 			case 1:
-				txFreq=1500;
+        txFreq=lowerFreq;
 				txDur=(unsigned int)rint(fp);
 				return MBTXGAP;
 			case 2:
-				txFreq=1200;
+        txFreq=syncFreq;
 				txDur=(unsigned int)rint(syncDuration);
 				return MBTXGAP;
 			case 3:
-				txFreq=1500;
+        txFreq=lowerFreq;
 				txDur=(unsigned int)rint(bp);
 				return MBTXGAP;
 			default:
diff --git a/qsstv/sstv/modes/modebw.h b/qsstv/sstv/modes/modebw.h
index 1d61525..c03e098 100644
--- a/qsstv/sstv/modes/modebw.h
+++ b/qsstv/sstv/modes/modebw.h
@@ -40,7 +40,7 @@
 class modeBW : public modeBase
 {
 public:
-    modeBW(esstvMode m,unsigned int len, bool tx);
+    modeBW(esstvMode m, unsigned int len, bool tx, bool narrowMode);
 
     ~modeBW();
 protected:
diff --git a/qsstv/sstv/modes/modegbr.cpp b/qsstv/sstv/modes/modegbr.cpp
index a32e324..ac23db1 100644
--- a/qsstv/sstv/modes/modegbr.cpp
+++ b/qsstv/sstv/modes/modegbr.cpp
@@ -21,9 +21,9 @@
 #include "modegbr.h"
 
 
-modeGBR::modeGBR(esstvMode m,unsigned int len, bool tx):modeBase(m,len,tx)
+modeGBR::modeGBR(esstvMode m,unsigned int len, bool tx,bool narrowMode):modeBase(m,len,tx,narrowMode)
 {
-	
+
 }
 
 
@@ -34,72 +34,91 @@ modeGBR::~modeGBR()
 
 void modeGBR::setupParams(double clock)
 {
-	visibleLineLength=(lineLength(mode,clock)-fp-bp-2*blank-syncDuration)/3.;
+  visibleLineLength=(getLineLength(mode,clock)-fp-bp-2*blank-syncDuration)/3.;
 }
 
 modeBase::embState modeGBR::rxSetupLine()
 {	
   start=lineTimeTableRX[lineCounter];
   //if(subLine==0) addToLog(QString("modeGBR: subLine %1, line=%2, absSampleCounter %3").arg(subLine).arg(lineCounter).arg(start+rxSampleCounter),DBMODES);
-	
+
   switch(subLine)
-		{
-			case 0:
-				calcPixelPositionTable(GREENLINE,false);
-				pixelArrayPtr=greenArrayPtr;
-				return MBPIXELS;
-			case 1:
-				debugState=stG1;
-				marker=(unsigned int)round(start+bp+blank+visibleLineLength);
-				return MBRXWAIT;
-			case 2:
-				calcPixelPositionTable(BLUELINE,false);
-				pixelArrayPtr=blueArrayPtr;
-				return MBPIXELS;
-			case 3:
-				debugState=stG2;
-				marker=(unsigned int)round(start+bp+2*blank+2*visibleLineLength);
-				return MBRXWAIT;
-			case 4:
-				calcPixelPositionTable(REDLINE,false);
-				pixelArrayPtr=redArrayPtr;
-				return MBPIXELS;
-			case 5:
-				debugState=stSync;
-        syncPosition=(unsigned int) round(lineTimeTableRX[lineCounter+1]);
-				return MBSYNC;
-			break;
-			default:
-				return MBENDOFLINE;
-		}
+    {
+    case 0:
+      debugState=stBP;
+      start=lineTimeTableRX[lineCounter];
+      markerFloat=start+bp;
+      marker=(unsigned int)round(markerFloat);
+      return MBRXWAIT;
+    case 1:
+      calcPixelPositionTable(GREENLINE,false);
+      markerFloat+=visibleLineLength;
+      debugState=stColorLine0;
+      pixelArrayPtr=greenArrayPtr;
+      return MBPIXELS;
+    case 2:
+      debugState=stG1;
+      markerFloat+=blank;
+      marker=(unsigned int)round(markerFloat);
+      return MBRXWAIT;
+    case 3:
+      calcPixelPositionTable(BLUELINE,false);
+      markerFloat+=visibleLineLength;
+      debugState=stColorLine1;
+      pixelArrayPtr=blueArrayPtr;
+      return MBPIXELS;
+    case 4:
+      debugState=stG2;
+      markerFloat+=blank;
+      marker=(unsigned int)round(markerFloat);
+      return MBRXWAIT;
+    case 5:
+      calcPixelPositionTable(REDLINE,false);
+      markerFloat+=visibleLineLength;
+      debugState=stColorLine2;
+      pixelArrayPtr=redArrayPtr;
+      return MBPIXELS;
+    case 6:
+      debugState=stFP;
+      markerFloat+=fp;
+      marker=(unsigned int)round(markerFloat);
+      return MBRXWAIT;
+    case 7:
+      debugState=stSync;
+      markerFloat+=syncDuration;
+      marker=(unsigned int)round(markerFloat);
+      syncPosition=marker;
+      return MBSYNC;
+      break;
+    default:
+      return MBENDOFLINE;
+    }
 }
 
 void modeGBR::calcPixelPositionTable(unsigned int colorLine,bool tx)
 {
-	unsigned int i;
-	int ofx=0;
-	if(tx) ofx=1;
-	debugState=stColorLine0+colorLine;
-	
-	switch (colorLine)
-		{
-			case GREENLINE:
-				start+=bp;
- //       addToLog(QString("calcPixelPosition: startGreen %1").arg(start+rxSampleCounter),DBMODES);
-			break;
-			case BLUELINE:
-        start+=(bp+visibleLineLength+blank);
- //       addToLog(QString("calcPixelPosition: startBlue %1").arg(start+rxSampleCounter),DBMODES);
-			break;
-			case REDLINE:
-        start+=(bp+2.*visibleLineLength+2.*blank);
- //        addToLog(QString("calcPixelPosition: startRed %1").arg(start+rxSampleCounter),DBMODES);
-			break;
-		}
+  unsigned int i;DSPFLOAT lineStart=start;
+  int ofx=0;
+  if(tx) ofx=1;
+  switch (colorLine)
+    {
+    case GREENLINE:
+      lineStart+=bp;
+      //       addToLog(QString("calcPixelPosition: startGreen %1").arg(start+rxSampleCounter),DBMODES);
+      break;
+    case BLUELINE:
+      lineStart+=(bp+visibleLineLength+blank);
+      //       addToLog(QString("calcPixelPosition: startBlue %1").arg(start+rxSampleCounter),DBMODES);
+      break;
+    case REDLINE:
+      lineStart+=(bp+2.*visibleLineLength+2.*blank);
+      //        addToLog(QString("calcPixelPosition: startRed %1").arg(start+rxSampleCounter),DBMODES);
+      break;
+    }
   for(i=0;i<activeSSTVParam->numberOfPixels;i++)
-		{
-      pixelPositionTable[i]=(unsigned int)round(start+(((float)(i+ofx)*visibleLineLength)/activeSSTVParam->numberOfPixels));
-		}
+    {
+      pixelPositionTable[i]=(unsigned int)round(lineStart+(((float)(i+ofx)*visibleLineLength)/activeSSTVParam->numberOfPixels));
+    }
 }
 
 
@@ -107,41 +126,41 @@ modeBase::embState modeGBR::txSetupLine()
 {
   start=lineTimeTableTX[lineCounter];
   switch(subLine)
-		{
-			case 0:
-				calcPixelPositionTable(GREENLINE,true);
-				pixelArrayPtr=greenArrayPtr;
-				return MBPIXELS;
-			case 1:
-				txFreq=1500.;
-				txDur=(unsigned int)rint(blank);
-				return MBTXGAP;
-			case 2:
-				calcPixelPositionTable(BLUELINE,true);
-				pixelArrayPtr=blueArrayPtr;
-				return MBPIXELS;
-			case 3:
-				txFreq=1500.;
-				txDur=(unsigned int)rint(blank);
-				return MBTXGAP;
-			case 4:
-				calcPixelPositionTable(REDLINE,true);
-				pixelArrayPtr=redArrayPtr;
-				return MBPIXELS;
-			case 5:
-				txFreq=1500;
-				txDur=(unsigned int)rint(fp);
-				return MBTXGAP;
-			case 6:
-				txFreq=1200;
-				txDur=(unsigned int)rint(syncDuration);
-				return MBTXGAP;
-      case 7:
-        txFreq=1500;
-        txDur=(unsigned int)rint(bp);
+    {
+    case 0:
+      calcPixelPositionTable(GREENLINE,true);
+      pixelArrayPtr=greenArrayPtr;
+      return MBPIXELS;
+    case 1:
+      txFreq=lowerFreq;
+      txDur=(unsigned int)rint(blank);
+      return MBTXGAP;
+    case 2:
+      calcPixelPositionTable(BLUELINE,true);
+      pixelArrayPtr=blueArrayPtr;
+      return MBPIXELS;
+    case 3:
+      txFreq=lowerFreq;
+      txDur=(unsigned int)rint(blank);
+      return MBTXGAP;
+    case 4:
+      calcPixelPositionTable(REDLINE,true);
+      pixelArrayPtr=redArrayPtr;
+      return MBPIXELS;
+    case 5:
+      txFreq=lowerFreq;
+      txDur=(unsigned int)rint(fp);
+      return MBTXGAP;
+    case 6:
+      txFreq=syncFreq;
+      txDur=(unsigned int)rint(syncDuration);
+      return MBTXGAP;
+    case 7:
+      txFreq=lowerFreq;
+      txDur=(unsigned int)rint(bp);
       return MBTXGAP;
-      default:
-				return MBENDOFLINE;
-		}
+    default:
+      return MBENDOFLINE;
+    }
 }
 
diff --git a/qsstv/sstv/modes/modegbr.h b/qsstv/sstv/modes/modegbr.h
index 954fa0d..f599961 100644
--- a/qsstv/sstv/modes/modegbr.h
+++ b/qsstv/sstv/modes/modegbr.h
@@ -29,7 +29,7 @@
 class modeGBR : public modeBase
 {
 public:
-	modeGBR(esstvMode m,unsigned int len,bool tx);
+  modeGBR(esstvMode m, unsigned int len, bool tx, bool narrowMode);
 	~modeGBR();
 protected:
   embState rxSetupLine();
diff --git a/qsstv/sstv/modes/modegbr2.cpp b/qsstv/sstv/modes/modegbr2.cpp
index 9490f61..3f87bed 100644
--- a/qsstv/sstv/modes/modegbr2.cpp
+++ b/qsstv/sstv/modes/modegbr2.cpp
@@ -30,8 +30,9 @@
  ***************************************************************************/
 #include "modegbr2.h"
 
+// Scottie 1,2 and SDX
 
-modeGBR2::modeGBR2(esstvMode m,unsigned int len, bool tx):modeBase(m,len,tx)
+modeGBR2::modeGBR2(esstvMode m,unsigned int len, bool tx,bool narrowMode):modeBase(m,len,tx,narrowMode)
 {
 }
 
@@ -42,142 +43,159 @@ modeGBR2::~modeGBR2()
 
 void modeGBR2::setupParams(double clock)
 {
-	visibleLineLength=(lineLength(mode,clock)-fp-bp-2*blank-syncDuration)/3.;
+  visibleLineLength=(getLineLength(mode,clock)-fp-bp-2*blank-syncDuration)/3.;
 }
 
 modeBase::embState modeGBR2::rxSetupLine()
 {
-	// the start of the Scottie mode is always at the start of the green line 
-  start=lineTimeTableRX[lineCounter];
- // if(subLine==0) addToLog(QString("modeGBR2: subLine %1, line=%2").arg(subLine).arg(lineCounter),DBMODES);
+  // the start of the Scottie mode is always at the start of the green line
+
+  // if(subLine==0) addToLog(QString("modeGBR2: subLine %1, line=%2").arg(subLine).arg(lineCounter),DBMODES);
   switch(subLine)
-		{
-
-			case 0:
-				calcPixelPositionTable(GREENLINE,false);
-				debugState=stColorLine0;
-				pixelArrayPtr=greenArrayPtr;
-				return MBPIXELS;
-			case 1:
-				debugState=stG1;
-				marker=(unsigned int)round(start+blank+visibleLineLength);
-				return MBRXWAIT;
-			case 2:
-				calcPixelPositionTable(BLUELINE,false);
-				debugState=stColorLine1;
-				pixelArrayPtr=blueArrayPtr;
-				return MBPIXELS;
-			case 3:
-				debugState=stFP;
-				marker=(unsigned int)round(start+blank+fp+2*visibleLineLength);
-				return MBRXWAIT;
-			case 4:
-				debugState=stSync;
-				syncPosition=syncEndPosition;
-				return MBSYNC;
-			case 5:
-				debugState=stBP;
-				marker=(unsigned int)round(syncEndPosition+bp);
-				return MBRXWAIT;
-			case 6:
-				calcPixelPositionTable(REDLINE,false);
-				debugState=stColorLine2;
-				pixelArrayPtr=redArrayPtr;
-				return MBPIXELS;
-			case 7:
-				debugState=stG1;
-        marker=(unsigned int)round(lineTimeTableRX[lineCounter]);
-				return MBRXWAIT;
-			break;
-			default:
-				return MBENDOFLINE;
-		}
+    {
+    case 0:
+      debugState=stG1;
+      start=lineTimeTableRX[lineCounter];
+      markerFloat=start+blank;
+      marker=(unsigned int)round(markerFloat);
+      return MBRXWAIT;
+    case 1:
+      calcPixelPositionTable(GREENLINE,false);
+      markerFloat+=visibleLineLength;
+      debugState=stColorLine0;
+      pixelArrayPtr=greenArrayPtr;
+      return MBPIXELS;
+    case 2:
+      debugState=stG2;
+      markerFloat+=blank;
+      marker=(unsigned int)round(markerFloat);
+      return MBRXWAIT;
+    case 3:
+      calcPixelPositionTable(BLUELINE,false);
+      markerFloat+=visibleLineLength;
+      debugState=stColorLine1;
+      pixelArrayPtr=blueArrayPtr;
+      return MBPIXELS;
+    case 4:
+      debugState=stFP;
+      markerFloat+=fp;
+      marker=(unsigned int)round(markerFloat);
+      return MBRXWAIT;
+    case 5:
+      debugState=stSync;
+      markerFloat+=syncDuration;
+      marker=(unsigned int)round(markerFloat);
+      syncPosition=marker;
+      return MBSYNC;
+    case 6:
+      debugState=stBP;
+      markerFloat+=bp;
+      marker=(unsigned int)round(markerFloat);
+      return MBRXWAIT;
+    case 7:
+      calcPixelPositionTable(REDLINE,false);
+      markerFloat+=visibleLineLength;
+      debugState=stColorLine2;
+      pixelArrayPtr=redArrayPtr;
+      return MBPIXELS;
+      break;
+    default:
+      return MBENDOFLINE;
+    }
 }
 
 void modeGBR2::calcPixelPositionTable(unsigned int colorLine,bool tx)
 {
-	unsigned int i;
-	int ofx=0;
-	if(tx) ofx=1;
-	debugState=colorLine;
-	switch (colorLine)
-		{
-			case GREENLINE:
-				start+=bp;
-       // addToLog(QString("gbr2: greenstart=%1").arg(start),DBMODES);
-
-			break;
-			case BLUELINE:
-				start+=(bp+blank+visibleLineLength);
-				syncEndPosition=(unsigned int)(start+visibleLineLength+fp+syncDuration);
-
-       // addToLog(QString("gbr2: bluestart=%1").arg(start),DBMODES);
-
-			break;
-			case REDLINE:
-				start+=bp+fp+syncDuration+bp+blank+2.*visibleLineLength;
-       // addToLog(QString("gbr2: redstart=%1").arg(start),DBMODES);
-
-			break;
-		}
+  unsigned int i;
+  DSPFLOAT lineStart=start;
+  int ofx=0;
+  if(tx) ofx=1;
+//  debugState=colorLine;
+  switch (colorLine)
+    {
+    case GREENLINE:
+      lineStart+=blank;
+      // addToLog(QString("gbr2: greenstart=%1").arg(start),DBMODES);
+
+      break;
+    case BLUELINE:
+      lineStart+=(blank+visibleLineLength+blank);
+      syncEndPosition=(unsigned int)(lineStart+fp+syncDuration);
+
+      // addToLog(QString("gbr2: bluestart=%1").arg(start),DBMODES);
+
+      break;
+    case REDLINE:
+      lineStart+=2*blank+fp+syncDuration+bp+2.*visibleLineLength;
+      // addToLog(QString("gbr2: redstart=%1").arg(start),DBMODES);
+
+      break;
+    }
   for(i=0;i<activeSSTVParam->numberOfPixels;i++)
-		{
-      pixelPositionTable[i]=(unsigned int)round(start+(((float)(i+ofx)*visibleLineLength)/activeSSTVParam->numberOfPixels));
-		}
+    {
+      pixelPositionTable[i]=(unsigned int)round(lineStart+(((float)(i+ofx)*visibleLineLength)/activeSSTVParam->numberOfPixels));
+    }
 }
 
 
-unsigned long modeGBR2::adjustSyncPosition(unsigned long syncPos)
+unsigned long modeGBR2::adjustSyncPosition(unsigned long syncPos0,bool isRetrace)
 {
-  if(syncPos<(unsigned long)(fp+2*visibleLineLength+2*blank+syncDuration))
-  {
-    return syncPos+(unsigned long)(bp+visibleLineLength);
-  }
+  if(isRetrace) return syncPos0;
+  if(syncPos0<(unsigned long)(fp+2*visibleLineLength+2*blank+syncDuration/2))
+    {
+      return syncPos0+(unsigned long)(bp+visibleLineLength);
+    }
   else
-  {
-    return syncPos-(unsigned long)(fp+2*visibleLineLength+2*blank+syncDuration);
-  }
+    {
+      return syncPos0-(unsigned long)(fp+2*visibleLineLength+2*blank+syncDuration);
+    }
+
 }
 
+//unsigned long modeGBR2::retraceAdjust(unsigned long syncPos)
+//{
+//  return syncPos-(unsigned long)(blank+visibleLineLength+syncDuration);
+//}
+
 modeBase::embState modeGBR2::txSetupLine()
 {
   start=lineTimeTableTX[lineCounter];
- // if(subLine==0) addToLog(QString("modeGBR2: subLine %1, line=%2").arg(subLine).arg(lineCounter),DBMODES);
+  // if(subLine==0) addToLog(QString("modeGBR2: subLine %1, line=%2").arg(subLine).arg(lineCounter),DBMODES);
   switch(subLine)
-		{
-			case 0:
-				calcPixelPositionTable(GREENLINE,true);
-				pixelArrayPtr=greenArrayPtr;
-				return MBPIXELS;
-			case 1:
-				txFreq=1500.;
-				txDur=(unsigned int)rint(blank);
-				return MBTXGAP;
-			case 2:
-				calcPixelPositionTable(BLUELINE,true);
-				pixelArrayPtr=blueArrayPtr;
-				return MBPIXELS;
-			case 3:
-				txFreq=1500;
-				txDur=(unsigned int)rint(fp);
-				return MBTXGAP;
-			case 4:
-				txFreq=1200;
-				txDur=(unsigned int)rint(syncDuration);
-				return MBTXGAP;
-			case 5:
-				txFreq=1500;
-				txDur=(unsigned int)rint(bp);
-				return MBTXGAP;	
-			case 6:
-				calcPixelPositionTable(REDLINE,true);
-				pixelArrayPtr=redArrayPtr;
-				return MBPIXELS;
-			case 7:
-				txFreq=1500.;
-				txDur=(unsigned int)rint(blank);
-				return MBTXGAP;
-			default:
-				return MBENDOFLINE;
-		}
+    {
+    case 0:
+      calcPixelPositionTable(GREENLINE,true);
+      pixelArrayPtr=greenArrayPtr;
+      return MBPIXELS;
+    case 1:
+      txFreq=lowerFreq;
+      txDur=(unsigned int)rint(blank);
+      return MBTXGAP;
+    case 2:
+      calcPixelPositionTable(BLUELINE,true);
+      pixelArrayPtr=blueArrayPtr;
+      return MBPIXELS;
+    case 3:
+      txFreq=lowerFreq;
+      txDur=(unsigned int)rint(fp);
+      return MBTXGAP;
+    case 4:
+      txFreq=syncFreq;
+      txDur=(unsigned int)rint(syncDuration);
+      return MBTXGAP;
+    case 5:
+      txFreq=lowerFreq;
+      txDur=(unsigned int)rint(bp);
+      return MBTXGAP;
+    case 6:
+      calcPixelPositionTable(REDLINE,true);
+      pixelArrayPtr=redArrayPtr;
+      return MBPIXELS;
+    case 7:
+      txFreq=lowerFreq;
+      txDur=(unsigned int)rint(blank);
+      return MBTXGAP;
+    default:
+      return MBENDOFLINE;
+    }
 }
diff --git a/qsstv/sstv/modes/modegbr2.h b/qsstv/sstv/modes/modegbr2.h
index f6d7fcd..aaa75fc 100644
--- a/qsstv/sstv/modes/modegbr2.h
+++ b/qsstv/sstv/modes/modegbr2.h
@@ -39,14 +39,15 @@
 class modeGBR2 : public modeBase
 {
 public:
-	modeGBR2(esstvMode m,unsigned int len,bool tx);
+  modeGBR2(esstvMode m, unsigned int len, bool tx, bool narrowMode);
 	~modeGBR2();
 
 protected:
   embState rxSetupLine();
 	void calcPixelPositionTable(unsigned int colorLine,bool tx);
 	void setupParams(double clock);
-	unsigned long adjustSyncPosition(unsigned long syncPos);
+  unsigned long adjustSyncPosition(unsigned long syncPos0, bool isRetrace);
+//  unsigned long retraceAdjust(unsigned long syncPos);
 
 //	int adaptStartPosition(bool vertRetrace);
   embState txSetupLine();
diff --git a/qsstv/sstv/modes/modepd.cpp b/qsstv/sstv/modes/modepd.cpp
index ecf8133..08baff6 100644
--- a/qsstv/sstv/modes/modepd.cpp
+++ b/qsstv/sstv/modes/modepd.cpp
@@ -30,7 +30,7 @@
  ***************************************************************************/
 #include "modepd.h"
 
-modePD::modePD(esstvMode m,unsigned int len,bool tx): modeBase(m,len,tx)
+modePD::modePD(esstvMode m,unsigned int len,bool tx,bool narrowMode): modeBase(m,len,tx,narrowMode)
 {
 
 }
@@ -43,164 +43,162 @@ modePD::~modePD()
 
 void modePD::setupParams(double clock)
 {
-  visibleLineLength=(lineLength(mode,clock)-fp-bp-3*blank-syncDuration)/4;
+  visibleLineLength=(getLineLength(mode,clock)-fp-bp-syncDuration)/4;
 }
 
+
 modeBase::embState modePD::rxSetupLine()
 {
   start=lineTimeTableRX[lineCounter];
   switch(subLine)
-		{
-			case 0:
-				calcPixelPositionTable(YLINEODD,false);
-        addToLog(QString("yOdd %1").arg(pixelPositionTable[0]),LOGMODES);
-				pixelArrayPtr=yArrayPtr;
-				return MBPIXELS;
-      case 1:
-        debugState=stG1;
-        start=lineTimeTableRX[lineCounter];
-        marker=(unsigned int)round(start+bp+blank+visibleLineLength);
-        addToLog(QString("mrk1 %1").arg(marker),LOGMODES);
-        return MBRXWAIT;
-      case 2:
-				calcPixelPositionTable(REDLINE,false);
-				pixelArrayPtr=redArrayPtr;
-        addToLog(QString("red %1").arg(pixelPositionTable[0]),LOGMODES);
-				return MBPIXELS;
-      case 3:
-        debugState=stG1;
-        start=lineTimeTableRX[lineCounter];
-        marker=(unsigned int)round(start+bp+2*blank+2*visibleLineLength);
-        addToLog(QString("mrk2 %1").arg(marker),LOGMODES);
-        return MBRXWAIT;
-      case 4:
-				calcPixelPositionTable(BLUELINE,false);
-				pixelArrayPtr=blueArrayPtr;
-        addToLog(QString("blue %1").arg(pixelPositionTable[0]),LOGMODES);
-				return MBPIXELS;
-      case 5:
-        debugState=stG1;
-        start=lineTimeTableRX[lineCounter];
-        marker=(unsigned int)round(start+bp+3*blank+3*visibleLineLength);
-        addToLog(QString("mrk3 %1").arg(marker),LOGMODES);
-        return MBRXWAIT;
-      case 6:
-				calcPixelPositionTable(YLINEEVEN,false);
-				pixelArrayPtr=greenArrayPtr;
-        addToLog(QString("yEven %1").arg(pixelPositionTable[0]),LOGMODES);
-				return MBPIXELS;				
-      case 7:
-				debugState=stSync;
-        syncPosition=(unsigned int)round(lineTimeTableRX[lineCounter+1]);
-				return MBSYNC;
-			default:
-				return MBENDOFLINE;
-		}
+    {
+    case 0:
+      debugState=stBP;
+      start=lineTimeTableRX[lineCounter];
+      markerFloat=start+bp;
+      marker=(unsigned int)round(markerFloat);
+      return MBRXWAIT;
+    case 1:
+      debugState=stColorLine0 ;
+      calcPixelPositionTable(YLINEODD,false);
+      markerFloat+=visibleLineLength;
+      pixelArrayPtr=yArrayPtr;
+      return MBPIXELS;
+    case 2:
+      debugState=stColorLine1 ;
+      calcPixelPositionTable(REDLINE,false);
+      markerFloat+=visibleLineLength;
+      pixelArrayPtr=redArrayPtr;
+      return MBPIXELS;
+    case 3:
+      debugState=stColorLine2;
+      calcPixelPositionTable(BLUELINE,false);
+      markerFloat+=visibleLineLength;
+      pixelArrayPtr=blueArrayPtr;
+      return MBPIXELS;
+    case 4:
+      debugState=stColorLine3;
+      calcPixelPositionTable(YLINEEVEN,false);
+      markerFloat+=visibleLineLength;
+      pixelArrayPtr=greenArrayPtr;
+      return MBPIXELS;
+    case 5:
+      debugState=stFP;
+      start=lineTimeTableRX[lineCounter];
+      markerFloat+=fp;
+      marker=(unsigned int)round(markerFloat);
+      return MBRXWAIT;
+    case 6:
+      debugState=stSync;
+      markerFloat+=syncDuration;
+      marker=(unsigned int)round(markerFloat);
+      syncPosition=marker;
+      return MBSYNC;
+    default:
+      return MBENDOFLINE;
+    }
 }
 
 
 
 void modePD::calcPixelPositionTable(unsigned int colorLine,bool tx)
 {
-	unsigned int i;
-	int ofx=0;
-	if(tx) ofx=1;
-  double start;
-  if(tx) start=lineTimeTableTX[lineCounter];
-  else start=lineTimeTableRX[lineCounter];
-	debugState=colorLine;
-	switch (colorLine)
-		{
-			case YLINEODD:
-				start+=bp;
-        for(i=0;i<activeSSTVParam->numberOfPixels;i++)
-					{
-            pixelPositionTable[i]=(unsigned int)round(start+(((float)(i+ofx)*visibleLineLength)/activeSSTVParam->numberOfPixels));
-					}
-			break;
-			case REDLINE:
-				start+=(bp+blank+visibleLineLength);
-        for(i=0;i<activeSSTVParam->numberOfPixels;i++)
-					{
-            pixelPositionTable[i]=(unsigned int)round(start+(((float)(i+ofx)*visibleLineLength)/activeSSTVParam->numberOfPixels));
-					}
-			break;
-			case BLUELINE:
-				start+=bp+2*blank+2*visibleLineLength;
-        for(i=0;i<activeSSTVParam->numberOfPixels;i++)
-					{
-            pixelPositionTable[i]=(unsigned int)round(start+(((float)(i+ofx)*visibleLineLength)/activeSSTVParam->numberOfPixels));
-					}
-			break;
-			case YLINEEVEN:
-				start+=bp+(3*blank+3*visibleLineLength);
-        for(i=0;i<activeSSTVParam->numberOfPixels;i++)
-					{
-            pixelPositionTable[i]=(unsigned int)round(start+(((float)(i+ofx)*visibleLineLength)/activeSSTVParam->numberOfPixels));
-					}
-			break;
-		}
+  unsigned int i;
+  int ofx=0;
+  if(tx) ofx=1;
+  DSPFLOAT lineStart=start;
+  switch (colorLine)
+    {
+    case YLINEODD:
+      lineStart+=bp;
+      for(i=0;i<activeSSTVParam->numberOfPixels;i++)
+        {
+          pixelPositionTable[i]=(unsigned int)round(lineStart+(((float)(i+ofx)*visibleLineLength)/activeSSTVParam->numberOfPixels));
+        }
+      break;
+    case REDLINE:
+      lineStart+=(bp+visibleLineLength);
+      for(i=0;i<activeSSTVParam->numberOfPixels;i++)
+        {
+          pixelPositionTable[i]=(unsigned int)round(lineStart+(((float)(i+ofx)*visibleLineLength)/activeSSTVParam->numberOfPixels));
+        }
+      break;
+    case BLUELINE:
+      lineStart+=(bp+2*visibleLineLength);
+      for(i=0;i<activeSSTVParam->numberOfPixels;i++)
+        {
+          pixelPositionTable[i]=(unsigned int)round(lineStart+(((float)(i+ofx)*visibleLineLength)/activeSSTVParam->numberOfPixels));
+        }
+      break;
+    case YLINEEVEN:
+      lineStart+=(bp+3*visibleLineLength);
+      for(i=0;i<activeSSTVParam->numberOfPixels;i++)
+        {
+          pixelPositionTable[i]=(unsigned int)round(lineStart+(((float)(i+ofx)*visibleLineLength)/activeSSTVParam->numberOfPixels));
+        }
+      break;
+    }
 }
 
 void modePD::showLine()
 {
-	yuvConversion(yArrayPtr);
-	yuvConversion(greenArrayPtr);
+  yuvConversion(yArrayPtr);
+  yuvConversion(greenArrayPtr);
 }
 
 modeBase::embState modePD::txSetupLine()
 {
-    start=lineTimeTableTX[lineCounter];
-    switch(subLine)
-		{
-			case 0:
-				calcPixelPositionTable(YLINEODD,true);
-				pixelArrayPtr=yArrayPtr;
-				return MBPIXELS;
-			case 1:
-				txFreq=1500.;
-				txDur=(unsigned int)rint(blank);
-				return MBTXGAP;
-			case 2:
-				calcPixelPositionTable(REDLINE,true);
-				pixelArrayPtr=redArrayPtr;
-				return MBPIXELS;
-			case 3:
-				txFreq=1500;
-				txDur=(unsigned int)rint(blank);
-				return MBTXGAP;
-			case 4:
-				calcPixelPositionTable(BLUELINE,true);
-				pixelArrayPtr=blueArrayPtr;
-				return MBPIXELS;
-			case 5:
-				txFreq=1500;
-				txDur=(unsigned int)rint(blank);
-				return MBTXGAP;
-			case 6:
-				calcPixelPositionTable(YLINEEVEN,true);
-				pixelArrayPtr=greenArrayPtr;
-				return MBPIXELS;
-			case 7:
-				txFreq=1500;
-				txDur=(unsigned int)rint(fp);
-				return MBTXGAP;
-			case 8:
-				txFreq=1200;
-				txDur=(unsigned int)rint(syncDuration);
-				return MBTXGAP;
-			case 9:
-				txFreq=1500;
-				txDur=(unsigned int)rint(bp);
-				return MBTXGAP;
-			default:
-//				lineCounter++;
-				return MBENDOFLINE;
-		}
+  start=lineTimeTableTX[lineCounter];
+  switch(subLine)
+    {
+    case 0:
+      calcPixelPositionTable(YLINEODD,true);
+      pixelArrayPtr=yArrayPtr;
+      return MBPIXELS;
+    case 1:
+      txFreq=lowerFreq;
+      txDur=(unsigned int)rint(blank);
+      return MBTXGAP;
+    case 2:
+      calcPixelPositionTable(REDLINE,true);
+      pixelArrayPtr=redArrayPtr;
+      return MBPIXELS;
+    case 3:
+      txFreq=lowerFreq;
+      txDur=(unsigned int)rint(blank);
+      return MBTXGAP;
+    case 4:
+      calcPixelPositionTable(BLUELINE,true);
+      pixelArrayPtr=blueArrayPtr;
+      return MBPIXELS;
+    case 5:
+      txFreq=lowerFreq;
+      txDur=(unsigned int)rint(blank);
+      return MBTXGAP;
+    case 6:
+      calcPixelPositionTable(YLINEEVEN,true);
+      pixelArrayPtr=greenArrayPtr;
+      return MBPIXELS;
+    case 7:
+      txFreq=lowerFreq;
+      txDur=(unsigned int)rint(fp);
+      return MBTXGAP;
+    case 8:
+      txFreq=syncFreq;
+      txDur=(unsigned int)rint(syncDuration);
+      return MBTXGAP;
+    case 9:
+      txFreq=lowerFreq;
+      txDur=(unsigned int)rint(bp);
+      return MBTXGAP;
+    default:
+      //				lineCounter++;
+      return MBENDOFLINE;
+    }
 }
 
 
 void  modePD::getLine()
 {
-	getLineY(true);
+  getLineY(true);
 }
diff --git a/qsstv/sstv/modes/modepd.h b/qsstv/sstv/modes/modepd.h
index 4c57b6b..882f3ea 100644
--- a/qsstv/sstv/modes/modepd.h
+++ b/qsstv/sstv/modes/modepd.h
@@ -40,7 +40,7 @@
 class modePD : public modeBase
 {
 public:
-  modePD(esstvMode m,unsigned int len,bool tx);
+  modePD(esstvMode m, unsigned int len, bool tx, bool narrowMode);
 	~modePD();
 protected:
   embState rxSetupLine();
diff --git a/qsstv/sstv/modes/modergb.cpp b/qsstv/sstv/modes/modergb.cpp
index f6e44d3..bc48f1a 100644
--- a/qsstv/sstv/modes/modergb.cpp
+++ b/qsstv/sstv/modes/modergb.cpp
@@ -30,7 +30,7 @@
  ***************************************************************************/
 #include "modergb.h"
 
-modeRGB::modeRGB(esstvMode m,unsigned int len, bool tx):modeBase(m,len,tx)
+modeRGB::modeRGB(esstvMode m,unsigned int len, bool tx,bool narrowMode):modeBase(m,len,tx,narrowMode)
 {
 }
 
@@ -42,10 +42,12 @@ modeRGB::~modeRGB()
 
 void modeRGB::setupParams(double clock)
 {
-	visibleLineLength=(lineLength(mode,clock)-fp-bp-2*blank-syncDuration)/3.;
+  visibleLineLength=(getLineLength(mode,clock)-fp-bp-2*blank-syncDuration)/3.;
 }
 
 
+
+
 modeBase::embState modeRGB::rxSetupLine()
 {	
 
@@ -53,67 +55,107 @@ modeBase::embState modeRGB::rxSetupLine()
   switch(subLine)
 		{
 			case 0:
-				calcPixelPositionTable(REDLINE,false);
-				pixelArrayPtr=redArrayPtr;
-				return MBPIXELS;
-			case 1:
-				debugState=stG1;
-				marker=(unsigned int)round(start+blank+visibleLineLength);
-				return MBRXWAIT;
-			case 2:
-				calcPixelPositionTable(GREENLINE,false);
-				pixelArrayPtr=greenArrayPtr;
-				return MBPIXELS;
-			case 3:
-				debugState=stG1;
-				marker=(unsigned int)round(start+2*blank+2*visibleLineLength);
-				return MBRXWAIT;				
-			case 4:
-				calcPixelPositionTable(BLUELINE,false);
-				pixelArrayPtr=blueArrayPtr;
-				return MBPIXELS;
-			case 5:
-				debugState=stFP;
-				marker=(unsigned int)round(start+2*blank+3*visibleLineLength+fp);
-				return MBRXWAIT;				
-			case 6:
-				debugState=stSync;
-        syncPosition=(unsigned int)round(lineTimeTableRX[lineCounter+1]-bp);
-				return MBSYNC;
-			case 7:
-				debugState=stBP;
-        marker=(unsigned int)round(lineTimeTableRX[lineCounter+1]);
-				return MBRXWAIT;				
-			default:
+      debugState=stBP;
+      start=lineTimeTableRX[lineCounter];
+      markerFloat=start+bp;
+      marker=(unsigned int)round(markerFloat);
+      return MBRXWAIT;
+    case 1:
+      debugState=stColorLine0 ;
+      calcPixelPositionTable(REDLINE,false);
+      markerFloat+=visibleLineLength;
+      pixelArrayPtr=redArrayPtr;
+      return MBPIXELS;
+    case 2:
+      debugState=stG1;
+      markerFloat+=blank;
+      marker=(unsigned int)round(markerFloat);
+      return MBRXWAIT;
+    case 3:
+      debugState=stColorLine1;
+      calcPixelPositionTable(GREENLINE,false);
+      markerFloat+=visibleLineLength;
+      pixelArrayPtr=greenArrayPtr;
+      return MBPIXELS;
+    case 4:
+      debugState=stG2;
+      markerFloat+=blank;
+      marker=(unsigned int)round(markerFloat);
+      return MBRXWAIT;
+    case 5:
+      debugState=stColorLine2;
+      calcPixelPositionTable(BLUELINE,false);
+      markerFloat+=visibleLineLength;
+      pixelArrayPtr=blueArrayPtr;
+      return MBPIXELS;
+    case 6:
+      debugState=stFP;
+      start=lineTimeTableRX[lineCounter];
+      markerFloat+=fp;
+      marker=(unsigned int)round(markerFloat);
+      return MBRXWAIT;
+    case 7:
+      debugState=stSync;
+      markerFloat+=syncDuration;
+      marker=(unsigned int)round(markerFloat);
+      syncPosition=marker;
+      return MBSYNC;
+      default:
 				return MBENDOFLINE;
 		}
 }
 
-void modeRGB::calcPixelPositionTable(unsigned int colorLine,bool tx)
+void  modeRGB::calcPixelPositionTable(unsigned int colorLine,bool tx)
 {
-	unsigned int i;
-	int ofx=0;
-	if(tx) ofx=1;
-	debugState=colorLine;
-	switch (colorLine)
-		{
-			case REDLINE:
-				start+=bp;
-			break;
-			case GREENLINE:
-				start+=bp+blank+visibleLineLength;
-			break;
-			case BLUELINE:
-				start+=bp+2.*blank+2.*visibleLineLength;
-			break;
-		}
+  unsigned int i;DSPFLOAT lineStart=start;
+  int ofx=0;
+  if(tx) ofx=1;
+  switch (colorLine)
+    {
+    case REDLINE:
+      lineStart+=bp;
+      //       addToLog(QString("calcPixelPosition: startGreen %1").arg(start+rxSampleCounter),DBMODES);
+      break;
+    case GREENLINE:
+      lineStart+=(bp+visibleLineLength+blank);
+      //       addToLog(QString("calcPixelPosition: startBlue %1").arg(start+rxSampleCounter),DBMODES);
+      break;
+    case BLUELINE:
+      lineStart+=(bp+2.*visibleLineLength+2.*blank);
+      //        addToLog(QString("calcPixelPosition: startRed %1").arg(start+rxSampleCounter),DBMODES);
+      break;
+    }
   for(i=0;i<activeSSTVParam->numberOfPixels;i++)
-		{
-      pixelPositionTable[i]=(unsigned int)round(start+(((float)(i+ofx)*visibleLineLength)/activeSSTVParam->numberOfPixels));
-
-		}
+    {
+      pixelPositionTable[i]=(unsigned int)round(lineStart+(((float)(i+ofx)*visibleLineLength)/activeSSTVParam->numberOfPixels));
+    }
 }
 
+//void modeRGB::calcPixelPositionTable(unsigned int colorLine,bool tx)
+//{
+//	unsigned int i;
+//	int ofx=0;
+//	if(tx) ofx=1;
+//	debugState=colorLine;
+//	switch (colorLine)
+//		{
+//			case REDLINE:
+//				start+=bp;
+//			break;
+//			case GREENLINE:
+//				start+=bp+blank+visibleLineLength;
+//			break;
+//			case BLUELINE:
+//				start+=bp+2.*blank+2.*visibleLineLength;
+//			break;
+//		}
+//  for(i=0;i<activeSSTVParam->numberOfPixels;i++)
+//		{
+//      pixelPositionTable[i]=(unsigned int)round(start+(((float)(i+ofx)*visibleLineLength)/activeSSTVParam->numberOfPixels));
+
+//		}
+//}
+
 modeBase::embState modeRGB::txSetupLine()
 {
   start=lineTimeTableTX[lineCounter];
@@ -124,7 +166,7 @@ modeBase::embState modeRGB::txSetupLine()
 				pixelArrayPtr=redArrayPtr;
 				return MBPIXELS;
 			case 1:
-				txFreq=1500.;
+        txFreq=lowerFreq;
 				txDur=(unsigned int)rint(blank);
 				return MBTXGAP;
 			case 2:
@@ -132,7 +174,7 @@ modeBase::embState modeRGB::txSetupLine()
 				pixelArrayPtr=greenArrayPtr;
 				return MBPIXELS;
 			case 3:
-				txFreq=1500.;
+        txFreq=lowerFreq;
 				txDur=(unsigned int)rint(blank);
 				return MBTXGAP;
 			case 4:
@@ -140,15 +182,15 @@ modeBase::embState modeRGB::txSetupLine()
 				pixelArrayPtr=blueArrayPtr;
 				return MBPIXELS;
 			case 5:
-				txFreq=1500;
+        txFreq=lowerFreq;
 				txDur=(unsigned int)rint(fp);
 				return MBTXGAP;
 			case 6:
-				txFreq=1200;
+        txFreq=syncFreq;
 				txDur=(unsigned int)rint(syncDuration);
 				return MBTXGAP;
 			case 7:
-				txFreq=1500;
+        txFreq=lowerFreq;
 				txDur=(unsigned int)rint(bp);
 				return MBTXGAP;
 			default:
diff --git a/qsstv/sstv/modes/modergb.h b/qsstv/sstv/modes/modergb.h
index 20a4263..f5291fe 100644
--- a/qsstv/sstv/modes/modergb.h
+++ b/qsstv/sstv/modes/modergb.h
@@ -40,7 +40,7 @@
 class modeRGB : public modeBase
 {
 public:
-	modeRGB(esstvMode m,unsigned int len,bool tx);
+  modeRGB(esstvMode m, unsigned int len, bool tx, bool narrowMode);
 	~modeRGB();
 private:
   embState rxSetupLine();
diff --git a/qsstv/sstv/modes/moderobot1.cpp b/qsstv/sstv/modes/moderobot1.cpp
index 146c769..10b5da5 100644
--- a/qsstv/sstv/modes/moderobot1.cpp
+++ b/qsstv/sstv/modes/moderobot1.cpp
@@ -30,7 +30,7 @@
  ***************************************************************************/
 #include "moderobot1.h"
 
-modeRobot1::modeRobot1(esstvMode m,unsigned int len, bool tx):modeBase(m,len,tx)
+modeRobot1::modeRobot1(esstvMode m,unsigned int len, bool tx,bool narrowMode):modeBase(m,len,tx,narrowMode)
 {
 }
 
@@ -41,188 +41,224 @@ modeRobot1::~modeRobot1()
 
 void modeRobot1::setupParams(double clock)
 {
-  visibleLineLength=(lineLength(mode,clock)-fp-bp-blank-syncDuration)/3.;
+  visibleLineLength=(getLineLength(mode,clock)-fp-bp-blank-syncDuration)/3.;
 }
 
 modeBase::embState modeRobot1::rxSetupLine()
 {
-  start=lineTimeTableRX[lineCounter];
+
   switch(subLine)
-		{
-			case 0:
-				calcPixelPositionTable(YLINEODD,false);
-				pixelArrayPtr=yArrayPtr;
-				return MBPIXELS;
-			case 1:
-				debugState=stG1;
-				marker=(unsigned int)round(start+blank+2*visibleLineLength);
-				return MBRXWAIT;
-			case 2:
-				calcPixelPositionTable(REDLINE,false);
-				pixelArrayPtr=redArrayPtr;
-				return MBPIXELS;
-			case 3:
-				debugState=stFP;
-				marker=(unsigned int)round(start+blank+3*visibleLineLength+fp);
-				return MBRXWAIT;
-			case 4:
-				debugState=stSync;
-        syncPosition=(unsigned int)round(lineTimeTableRX[lineCounter+1]-bp);
-				return MBSYNC;
-			case 5:
-				debugState=stBP;
-        marker=(unsigned int)round(lineTimeTableRX[lineCounter]);
-				lineCounter++;
-				return MBRXWAIT;		
-			case 6:
-				calcPixelPositionTable(YLINEEVEN,false);
-				pixelArrayPtr=greenArrayPtr;
-				return MBPIXELS;
-			case 7:
-				debugState=stG1;
-        marker=(unsigned int)round(lineTimeTableRX[lineCounter]+blank+2*visibleLineLength);
-				return MBRXWAIT;						
-			case 8:
-				calcPixelPositionTable(BLUELINE,false);
-				pixelArrayPtr=blueArrayPtr;
-				return MBPIXELS;
-			case 9:
-				debugState=stFP;
-				marker=(unsigned int)round(start+blank+3*visibleLineLength+fp);
-				return MBRXWAIT;				
-			case 10:
-				debugState=stSync;
-        syncPosition=(unsigned int)round(lineTimeTableRX[lineCounter+1]-bp);
-				return MBSYNC;
-			case 11:
-				debugState=stBP;
-        marker=(unsigned int)round(lineTimeTableRX[lineCounter+1]);
-				return MBRXWAIT;		
-			default:
-				return MBENDOFLINE;
-		}
+    {
+    case 0:
+      debugState=stBP;
+      start=lineTimeTableRX[lineCounter];
+      markerFloat=start+bp;
+      marker=(unsigned int)round(markerFloat);
+      return MBRXWAIT;
+    case 1:
+      debugState=stColorLine0;
+      calcPixelPositionTable(YLINEODD,false);
+      markerFloat+=2*visibleLineLength;
+      marker=(unsigned int)round(markerFloat);
+      pixelArrayPtr=yArrayPtr;
+      return MBPIXELS;
+    case 2:
+      debugState=stG1;
+      avgFreqGap=0;
+      avgFreqGapCounter=0;
+      markerFloat+=((blank/3)*2);
+      marker=(unsigned int)round(markerFloat);
+      return MB1500;
+    case 3:
+      debugState=stG1a;
+      markerFloat+=(blank/3);
+      marker=(unsigned int)round(markerFloat);
+      return MBRXWAIT;
+
+    case 4:
+      debugState=stColorLine1;
+      calcPixelPositionTable(REDLINE,false);
+      pixelArrayPtr=redArrayPtr;
+      markerFloat+=visibleLineLength;
+      marker=(unsigned int)round(markerFloat);
+      return MBPIXELS;
+    case 5:
+      debugState=stFP;
+      markerFloat+=fp;
+      marker=(unsigned int)round(markerFloat);
+      return MBRXWAIT;
+    case 6:
+      debugState=stSync;
+      markerFloat+=syncDuration;
+      marker=(unsigned int)round(markerFloat);
+      syncPosition=marker;
+      return MBSYNC;
+    case 7:
+      debugState=stBP;
+      markerFloat+=bp;
+      marker=(unsigned int)round(markerFloat);
+      lineCounter++;
+      return MBRXWAIT;
+    case 8:
+      debugState=stColorLine2;
+      calcPixelPositionTable(YLINEEVEN,false);
+      pixelArrayPtr=greenArrayPtr;
+      markerFloat+=2*visibleLineLength;
+      marker=(unsigned int)round(markerFloat);
+      return MBPIXELS;
+    case 9:
+      debugState=stG2;
+      avgFreqGap=0;
+      avgFreqGapCounter=0;
+      markerFloat+=((blank/3)*2);
+      marker=(unsigned int)round(markerFloat);
+      return MB2300;
+    case 10:
+      debugState=stG2a;
+      markerFloat+=(blank/3);
+      marker=(unsigned int)round(markerFloat);
+      return MBRXWAIT;
+    case 11:
+      debugState=stColorLine3;
+      calcPixelPositionTable(BLUELINE,false);
+      pixelArrayPtr=blueArrayPtr;
+      markerFloat+=visibleLineLength;
+      marker=(unsigned int)round(markerFloat);
+      return MBPIXELS;
+    case 12:
+      debugState=stFP;
+      markerFloat+=fp;
+      marker=(unsigned int)round(markerFloat);
+      return MBRXWAIT;
+    case 13:
+      debugState=stSync;
+      markerFloat+=syncDuration;
+      marker=(unsigned int)round(markerFloat);
+      syncPosition=marker;
+      return MBSYNC;
+    default:
+      return MBENDOFLINE;
+    }
 }
 
 void modeRobot1::showLine()
 {
-	yuvConversion(yArrayPtr);
-	yuvConversion(greenArrayPtr);
+  yuvConversion(yArrayPtr);
+  yuvConversion(greenArrayPtr);
 }
 
-
+//unsigned long modeRobot1::adjustSyncPosition(unsigned long syncPos0)
+//  {
+//  if(syncPos0<lineTimeTableRX[1]-35) return syncPos0-35;
+//  return syncPos0-lineTimeTableRX[1]+35;
+//  }
 
 
 void modeRobot1::calcPixelPositionTable(unsigned int colorLine,bool tx)
 {
-	unsigned int i;
-	int ofx=0;
-	if(tx) ofx=1;
-  double start;
-  if(tx) start=lineTimeTableTX[lineCounter];
-  else start=lineTimeTableRX[lineCounter];
-	debugState=colorLine;
-	switch (colorLine)
-		{
-			case YLINEODD:
-			case YLINEEVEN:
-				start+=bp;
-        for(i=0;i<activeSSTVParam->numberOfPixels;i++)
-					{
-            pixelPositionTable[i]=(unsigned int)round(start+(((float)(i+ofx)*visibleLineLength*2)/activeSSTVParam->numberOfPixels));
-					}
-			break;
-			case REDLINE:
-				start+=bp+blank+visibleLineLength*2;
-        for(i=0;i<activeSSTVParam->numberOfPixels;i++)
-					{
-						pixelPositionTable[i]=
-            (unsigned int)round(start+(((float)(i+ofx)*visibleLineLength)/activeSSTVParam->numberOfPixels));
-					}
-			break;
-			case BLUELINE:
-				start+=bp+blank+visibleLineLength*2;
-        for(i=0;i<activeSSTVParam->numberOfPixels;i++)
-					{
-						pixelPositionTable[i]=
-            (unsigned int)round(start+(((float)(i+ofx)*visibleLineLength)/activeSSTVParam->numberOfPixels));
-					}
-			break;
-		}
+  unsigned int i;
+  int ofx=0;
+  if(tx) ofx=1;
+//  DSPFLOAT lineStart=start; // todo check lineStart
+  //  double start;
+  //  if(tx) start=lineTimeTableTX[lineCounter];
+  //  else start=lineTimeTableRX[lineCounter];
+  //	debugState=colorLine;
+  switch (colorLine)
+    {
+    case YLINEODD:
+    case YLINEEVEN:
+      for(i=0;i<activeSSTVParam->numberOfPixels;i++)
+        {
+          pixelPositionTable[i]=(unsigned int)round(markerFloat+(((float)(i+ofx)*visibleLineLength*2)/activeSSTVParam->numberOfPixels));
+        }
+      break;
+    case REDLINE:
+    case BLUELINE:
+      for(i=0;i<activeSSTVParam->numberOfPixels;i++)
+        {
+          pixelPositionTable[i]=(unsigned int)round(markerFloat+(((float)(i+ofx)*visibleLineLength)/activeSSTVParam->numberOfPixels));
+        }
+      break;
+    }
 }
 
 /**
-	\todo resync odd/even line via frequency detection
+  \todo resync odd/even line via frequency detection
 */
 
 modeBase::embState modeRobot1::txSetupLine()
 {
   start=lineTimeTableTX[lineCounter];
   switch(subLine)
-		{
-			case 0:
-				calcPixelPositionTable(YLINEODD,true);
-				pixelArrayPtr=yArrayPtr;
-				return MBPIXELS;
-			case 1:
-				txFreq=1500.;
-				txDur=(unsigned int)rint((2*blank)/3);
-				return MBTXGAP;
-			case 2:
-				txFreq=1900.;
-				txDur=(unsigned int)rint(blank/3);
-				return MBTXGAP;
-			case 3:
-				calcPixelPositionTable(REDLINE,true);
-				pixelArrayPtr=redArrayPtr;
-				return MBPIXELS;
-			case 4:
-				txFreq=1500;
-				txDur=(unsigned int)rint(fp);
-				return MBTXGAP;
-			case 5:
-				txFreq=1200;
-				txDur=(unsigned int)rint(syncDuration);
-				return MBTXGAP;
-			case 6:
-				txFreq=1500;
-				txDur=(unsigned int)rint(bp);
-				lineCounter++;
-				return MBTXGAP;
-			case 7:
-				calcPixelPositionTable(YLINEEVEN,true);
-				pixelArrayPtr=greenArrayPtr;
-				return MBPIXELS;
-			case 8:
-				txFreq=2300.;
-				txDur=(unsigned int)rint((2*blank)/3);
-				return MBTXGAP;
-			case 9:
-				txFreq=1900.;
-				txDur=(unsigned int)rint(blank/3);
-				return MBTXGAP;
-			case 10:
-				calcPixelPositionTable(BLUELINE,true);
-				pixelArrayPtr=blueArrayPtr;
-				return MBPIXELS;
-			case 11:
-				txFreq=1500;
-				txDur=(unsigned int)rint(fp);
-				return MBTXGAP;
-			case 12:
-				txFreq=1200;
-				txDur=(unsigned int)rint(syncDuration);
-				return MBTXGAP;
-			case 13:
-				txFreq=1500;
-				txDur=(unsigned int)rint(bp);
-				return MBTXGAP;
-			default:
-				return MBENDOFLINE;
-		}
+    {
+    case 0:
+      markerFloat=start+bp;
+      calcPixelPositionTable(YLINEODD,true);
+      pixelArrayPtr=yArrayPtr;
+      return MBPIXELS;
+    case 1:
+      txFreq=lowerFreq;
+      txDur=(unsigned int)rint((2*blank)/3);
+      return MBTXGAP;
+    case 2:
+      txFreq=1900.;
+      txDur=(unsigned int)rint(blank/3);
+      return MBTXGAP;
+    case 3:
+      calcPixelPositionTable(REDLINE,true);
+      pixelArrayPtr=redArrayPtr;
+      return MBPIXELS;
+    case 4:
+      txFreq=lowerFreq;
+      txDur=(unsigned int)rint(fp);
+      return MBTXGAP;
+    case 5:
+      txFreq=syncFreq;
+      lineCounter++;
+      txDur=(unsigned int)rint(syncDuration);
+      return MBTXGAP;
+    case 6:
+      txFreq=lowerFreq;
+      txDur=(unsigned int)rint(bp);
+      lineCounter++;
+      return MBTXGAP;
+    case 7:
+      markerFloat=start+bp;
+      calcPixelPositionTable(YLINEEVEN,true);
+      pixelArrayPtr=greenArrayPtr;
+      return MBPIXELS;
+    case 8:
+      txFreq=2300.;
+      txDur=(unsigned int)rint((2*blank)/3);
+      return MBTXGAP;
+    case 9:
+      txFreq=1900.;
+      txDur=(unsigned int)rint(blank/3);
+      return MBTXGAP;
+    case 10:
+      calcPixelPositionTable(BLUELINE,true);
+      pixelArrayPtr=blueArrayPtr;
+      return MBPIXELS;
+    case 11:
+      txFreq=lowerFreq;
+      txDur=(unsigned int)rint(fp);
+      return MBTXGAP;
+    case 12:
+      txFreq=syncFreq;
+      txDur=(unsigned int)rint(syncDuration);
+      return MBTXGAP;
+    case 13:
+      txFreq=lowerFreq;
+      txDur=(unsigned int)rint(bp);
+      return MBTXGAP;
+    default:
+      return MBENDOFLINE;
+    }
 }
 
 void modeRobot1::getLine()
 {
-	getLineY(true);
+  getLineY(true);
 }
 
diff --git a/qsstv/sstv/modes/moderobot1.h b/qsstv/sstv/modes/moderobot1.h
index 2433c5d..66ac7e1 100644
--- a/qsstv/sstv/modes/moderobot1.h
+++ b/qsstv/sstv/modes/moderobot1.h
@@ -40,11 +40,13 @@
 class modeRobot1 : public modeBase
 {
 public:
-  modeRobot1 (esstvMode m,unsigned int len,bool tx);
+  modeRobot1 (esstvMode m, unsigned int len, bool tx, bool narrowMode);
   ~modeRobot1();
+
 private:
   embState rxSetupLine();
 	void calcPixelPositionTable(unsigned int colorLine,bool tx);
+//  unsigned long adjustSyncPosition(unsigned long syncPos0);
 	void setupParams(double clock);
 	void showLine();
   embState txSetupLine();
diff --git a/qsstv/sstv/modes/moderobot2.cpp b/qsstv/sstv/modes/moderobot2.cpp
index 1bcdf85..21a6d9d 100644
--- a/qsstv/sstv/modes/moderobot2.cpp
+++ b/qsstv/sstv/modes/moderobot2.cpp
@@ -31,7 +31,7 @@
 #include "moderobot2.h"
 
 
-modeRobot2::modeRobot2(esstvMode m,unsigned int len,bool tx): modeBase(m,len,tx)
+modeRobot2::modeRobot2(esstvMode m,unsigned int len,bool tx,bool narrowMode): modeBase(m,len,tx,narrowMode)
 {
 }
 
@@ -44,48 +44,61 @@ void modeRobot2::setupParams(double clock)
 {
   //double tmp=(activeSSTVParam->imageTime/(double)activeSSTVParam->numberOfDataLines)*clock;
   //visibleLineLength=(tmp-fp-bp-2*blank-syncDuration)/4;
-  visibleLineLength=(lineLength(mode,clock)-fp-bp-2*blank-syncDuration)/4.;
+  visibleLineLength=(getLineLength(mode,clock)-fp-bp-2*blank-syncDuration)/4.;
 }
 
 
+
+
 modeBase::embState modeRobot2::rxSetupLine()
 {
-  start=lineTimeTableRX[lineCounter];
   switch(subLine)
 		{
 			case 0:
 				debugState=stBP;
-//				marker=(unsigned int)round(lineTimeTable[lineCounter])-1;
-				marker=(unsigned int)rint(start+bp);
-				return MBRXWAIT;
+        start=lineTimeTableRX[lineCounter];
+        markerFloat=start+bp;
+        marker=(unsigned int)round(markerFloat);
+        return MBRXWAIT;
 			case 1:
 				calcPixelPositionTable(YLINEODD,false);
-				pixelArrayPtr=yArrayPtr;
-				return MBPIXELS;
-			case 2:
+        markerFloat+=2*visibleLineLength;
+        debugState=stColorLine0;
+        pixelArrayPtr=yArrayPtr;
+        return MBPIXELS;
+      case 2:
 				debugState=stG1;
-				marker=(unsigned int)rint(start+bp+blank+2*visibleLineLength);
+        markerFloat+=blank;
+        marker=(unsigned int)round(markerFloat);
 				return MBRXWAIT;
 			case 3:
 				calcPixelPositionTable(REDLINE,false);
+        markerFloat+=visibleLineLength;
+        debugState=stColorLine1;
 				pixelArrayPtr=redArrayPtr;
 				return MBPIXELS;
 			case 4:
-				debugState=stG1;
-				marker=(unsigned int)rint(start+bp+2*blank+3*visibleLineLength);
+        debugState=stG2;
+        markerFloat+=blank;
+        marker=(unsigned int)round(markerFloat);
 				return MBRXWAIT;
 			case 5:
 				calcPixelPositionTable(BLUELINE,false);
+        markerFloat+=visibleLineLength;
+        debugState=stColorLine2;
 				pixelArrayPtr=blueArrayPtr;
 				return MBPIXELS;
 			case 6:
 				debugState=stFP;
-				marker=(unsigned int)rint(start+bp+2*blank+4*visibleLineLength+fp);
+        markerFloat+=fp;
+        marker=(unsigned int)round(markerFloat);
 				return MBRXWAIT;
 			case 7:
-				debugState=stSync;
-        syncPosition=(unsigned int)rint(lineTimeTableRX[lineCounter+1]);
-				return MBSYNC;
+        debugState=stSync;
+        markerFloat+=syncDuration;
+        marker=(unsigned int)round(markerFloat);
+        syncPosition=marker;
+      return MBSYNC;
 
 			default:
 				return MBENDOFLINE;
@@ -101,40 +114,79 @@ void modeRobot2::showLine()
 
 void modeRobot2::calcPixelPositionTable(unsigned int colorLine,bool tx)
 {
-	unsigned int i;
-	int ofx=0;
-	if(tx) ofx=1;
-  double start;
-  if (tx) start=lineTimeTableTX[lineCounter];
-  else start=lineTimeTableRX[lineCounter];
-	debugState=colorLine;
-	if (tx) start+=9;
-	switch (colorLine)
-		{
-			case YLINEODD:
-				start+=bp;
-        for(i=0;i<activeSSTVParam->numberOfPixels;i++)
-					{
-            pixelPositionTable[i]=(unsigned int)round(start+(((float)(i+ofx)*2*visibleLineLength)/activeSSTVParam->numberOfPixels));
-					}
-			break;
-			case REDLINE:
-				start+=(bp+blank+2*visibleLineLength);
-        for(i=0;i<activeSSTVParam->numberOfPixels;i++)
-					{
-            pixelPositionTable[i]=(unsigned int)round(start+(((float)(i+ofx)*visibleLineLength)/activeSSTVParam->numberOfPixels));
-					}
-			break;
-			case BLUELINE:
-				start+=(bp+2*blank+3*visibleLineLength);
-        for(i=0;i<activeSSTVParam->numberOfPixels;i++)
-					{
-            pixelPositionTable[i]=(unsigned int)(round)(start+(((float)(i+ofx)*visibleLineLength)/activeSSTVParam->numberOfPixels));
-					}
-			break;
-		}
+  unsigned int i;
+  DSPFLOAT lineStart=start;
+  int ofx=0;
+  if(tx) ofx=1;
+//  debugState=colorLine;
+  switch (colorLine)
+    {
+    case YLINEODD:
+      lineStart+=bp;
+    break;
+    case REDLINE:
+      lineStart+=(bp+2*visibleLineLength+blank);
+      break;
+    case BLUELINE:
+      lineStart+=bp+2*blank+3*visibleLineLength;
+      // addToLog(QString("gbr2: redstart=%1").arg(start),DBMODES);
+
+      break;
+    }
+  switch (colorLine)
+    {
+      case YLINEODD:
+      for(i=0;i<activeSSTVParam->numberOfPixels;i++)
+        {
+          pixelPositionTable[i]=(unsigned int)round(lineStart+(((float)(i+ofx)*2*visibleLineLength)/activeSSTVParam->numberOfPixels));
+        }
+      break;
+    default:
+      for(i=0;i<activeSSTVParam->numberOfPixels;i++)
+        {
+          pixelPositionTable[i]=(unsigned int)round(lineStart+(((float)(i+ofx)*visibleLineLength)/activeSSTVParam->numberOfPixels));
+        }
+      break;
+    }
+
 }
 
+//void modeRobot2::calcPixelPositionTable(unsigned int colorLine,bool tx)
+//{
+//	unsigned int i;
+//	int ofx=0;
+//	if(tx) ofx=1;
+//  double start;
+//  if (tx) start=lineTimeTableTX[lineCounter];
+//  else start=lineTimeTableRX[lineCounter];
+//	debugState=colorLine;
+//	if (tx) start+=9;
+//	switch (colorLine)
+//		{
+//			case YLINEODD:
+//				start+=bp;
+//        for(i=0;i<activeSSTVParam->numberOfPixels;i++)
+//					{
+//            pixelPositionTable[i]=(unsigned int)round(start+(((float)(i+ofx)*2*visibleLineLength)/activeSSTVParam->numberOfPixels));
+//					}
+//			break;
+//			case REDLINE:
+//				start+=(bp+blank+2*visibleLineLength);
+//        for(i=0;i<activeSSTVParam->numberOfPixels;i++)
+//					{
+//            pixelPositionTable[i]=(unsigned int)round(start+(((float)(i+ofx)*visibleLineLength)/activeSSTVParam->numberOfPixels));
+//					}
+//			break;
+//			case BLUELINE:
+//				start+=(bp+2*blank+3*visibleLineLength);
+//        for(i=0;i<activeSSTVParam->numberOfPixels;i++)
+//					{
+//            pixelPositionTable[i]=(unsigned int)(round)(start+(((float)(i+ofx)*visibleLineLength)/activeSSTVParam->numberOfPixels));
+//					}
+//			break;
+//		}
+//}
+
 
 
 modeBase::embState modeRobot2::txSetupLine()
@@ -143,7 +195,7 @@ modeBase::embState modeRobot2::txSetupLine()
   switch(subLine)
 		{
 			case 0:
-				txFreq=1500;
+        txFreq=lowerFreq;
 				txDur=(unsigned int)rint(bp+6);
 				return MBTXGAP;
 			case 1:
@@ -151,7 +203,7 @@ modeBase::embState modeRobot2::txSetupLine()
 				pixelArrayPtr=yArrayPtr;
 				return MBPIXELS;
 			case 2:
-				txFreq=1500.;
+        txFreq=lowerFreq;
 				txDur=(unsigned int)rint((2*blank)/3);
 				return MBTXGAP;
 			case 3:
@@ -175,11 +227,11 @@ modeBase::embState modeRobot2::txSetupLine()
 				pixelArrayPtr=blueArrayPtr;
 				return MBPIXELS;
 			case 8:
-				txFreq=1500;
+        txFreq=lowerFreq;
 				txDur=(unsigned int)rint(fp);
 				return MBTXGAP;
 			case 9:
-				txFreq=1200;
+        txFreq=syncFreq;
 				txDur=(unsigned int)rint(syncDuration);
 				return MBTXGAP;
 
diff --git a/qsstv/sstv/modes/moderobot2.h b/qsstv/sstv/modes/moderobot2.h
index cb39e3f..dd2e1fb 100644
--- a/qsstv/sstv/modes/moderobot2.h
+++ b/qsstv/sstv/modes/moderobot2.h
@@ -39,7 +39,7 @@
 class modeRobot2 : public modeBase
 {
 public:
-  modeRobot2(esstvMode m,unsigned int len,bool tx);
+  modeRobot2(esstvMode m, unsigned int len, bool tx, bool narrowMode);
 	~modeRobot2();
 private:
   embState rxSetupLine();
diff --git a/qsstv/sstv/sstvparam.cpp b/qsstv/sstv/sstvparam.cpp
index b89dd97..a561aa7 100644
--- a/qsstv/sstv/sstvparam.cpp
+++ b/qsstv/sstv/sstvparam.cpp
@@ -19,11 +19,12 @@
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
 #include "sstvparam.h"
-#include "qsstvglobal.h"
+#include "appglobal.h"
 #include "utils/supportfunctions.h"
 #include "configparams.h"
 #include <math.h>
 
+
 bool useVIS;
 bool autoSlantAdjust;
 bool autoSave;
@@ -36,7 +37,11 @@ sSSTVParam rxSSTVParam;
 //sFAXParam  rxFAXParam;
 sSSTVParam txSSTVParam;
 //sFAXParam txFAXParam;
-esstvMode sstvModeIndex;
+esstvMode sstvModeIndexRx;
+
+
+esstvMode sstvModeIndexTx;
+
 
 /**
  		\brief setup the lineTable 
@@ -75,16 +80,27 @@ void setupSSTVLineTimeTable(esstvMode modeIndex,DSPFLOAT clock, bool transmit)
 	return the linelength expressed in number of samples
 */
 
-DSPFLOAT lineLength(esstvMode modeIndex,DSPFLOAT clock)
+DSPFLOAT getLineLength(esstvMode modeIndex,DSPFLOAT clock)
 {
 	return (SSTVTable[modeIndex].imageTime/(DSPFLOAT)SSTVTable[modeIndex].numberOfDataLines)*clock;
 }
 
+void dumpSamplesPerLine()
+{
+  int i;
+  for(i=0;i<ENDNARROW;i++)
+    {
+      logFilePtr->addToAux(QString("%1\t%2").arg(getSSTVModeNameShort((esstvMode) i)).arg(getLineLength((esstvMode) i,12000)));
+    }
+
+}
+
+
 /*!
 	return the sync width expressed in number of samples
 */
 
-DSPFLOAT syncWidth(esstvMode modeIndex,DSPFLOAT clock)
+DSPFLOAT getSyncWidth(esstvMode modeIndex,DSPFLOAT clock)
 {
 	return (SSTVTable[modeIndex].sync*clock);
 }
@@ -95,6 +111,7 @@ DSPFLOAT syncWidth(esstvMode modeIndex,DSPFLOAT clock)
   
 	Setup active parameters given the VIS code 
   \param[in] viscode VIS code of the mode to select
+  \param[in] tx if set to true then parameters for transmit
   \return Returns the modeIndex if successful else NOTVALID
 */
 esstvMode initializeParametersVIS(unsigned int viscode,bool tx)
@@ -112,6 +129,7 @@ esstvMode initializeParametersVIS(unsigned int viscode,bool tx)
 
 		Setup active parameters given the modeIndex
  * \param[in] modeIndex selected mode
+ * \param[in] tx if set to true then parameters for transmit
  * \return true if successful 
 */
 bool  initializeSSTVParametersIndex(esstvMode modeIndex,bool tx)
@@ -129,7 +147,7 @@ bool  initializeSSTVParametersIndex(esstvMode modeIndex,bool tx)
 /**
  * \brief print active parameters
 
-	Print the active parameters for debugging purposes (to logfile and/or console) \sa logFile
+	Print the active parameters for debugging purposes (to logFilePtr and/or console) \sa logFile
 */
 
 
@@ -285,39 +303,58 @@ DSPFLOAT longestLine(DSPFLOAT clock)
 */
 sSSTVParam SSTVTable[NUMSSTVMODES+1]=
 {
-//  name      shortName  mode      imagetime Pix Dis Txl  VIS     sync    fp      bp       blank  synctx  fptx   bptx    blanktx
-  {"Martin 1"  ,"M1",     M1,      114.29500,320,256,256,0x00AC,0.00500,0.00080,0.00050,0.00050,0.00500,0.00080,0.00000,0.00050,0.,1900,400 },
-  {"Martin 2"  ,"M2",     M2,       58.06300,320,256,256,0x0028,0.00500,0.00080,0.00050,0.00050,0.00500,0.00080,0.00000,0.00050,0.,1900,400 },
-  {"Scottie 1" ,"S1",     S1,      109.62950,320,256,256,0x003c,0.00900,0.00080,0.00125,0.00125,0.00900,0.00080,0.00080,0.00125,0.,1900,400 },
-  {"Scottie 2" ,"S2",     S2,       71.09250,320,256,256,0x00b8,0.00900,0.00080,0.00125,0.00125,0.00900,0.00000,0.00110,0.00125,0.,1900,400 },
-  {"Scottie DX","SDX",    SDX,     268.89080,320,256,256,0x00cc,0.00900,0.00000,0.00000,0.00100,0.00900,0.00000,0.00000,0.00100,0.,1900,400 },
-  {"SC2 60",    "SC2-60", SC2_60,   61.54150,320,256,256,0x00BB,0.00500,0.00100,0.00100,0.00100,0.00500,0.00000,0.00000,0.00000,0.,1900,400 },
-  {"SC2 120",   "SC2-120",SC2_120, 121.74050,320,256,256,0x003F,0.00500,0.00100,0.00100,0.00100,0.00500,0.00000,0.00000,0.00000,0.,1900,400 },
-  {"SC2 180",   "SC2-180",SC2_180, 182.03650,320,256,256,0x00B7,0.00500,0.00100,0.00100,0.00100,0.00500,0.00000,0.00000,0.00000,0.,1900,400 },
-  {"Robot 24",  "R24",    R24,      24.00150,160,120,120,0x0084,0.00600,0.00180,0.00125,0.00450,0.00600,0.00000,0.00120,0.00380,0.,1900,400 },
-  {"Robot 36"  ,"R36",    R36,      36.00200,320,240,240,0x0088,0.00900,0.00100,0.00340,0.00820,0.00900,0.00000,0.00300,0.00540,0.,1900,400 },
-  {"Robot 72"  ,"R72",    R72,      72.00375,320,240,240,0x000C,0.00900,0.00040,0.00250,0.00600,0.00900,0.00040,0.00250,0.00600,0.,1900,400 },
-  {"P3"        ,"P3" ,    P3,      203.05960,640,496,496,0x0071,0.00520,0.00210,0.00080,0.00250,0.00520,0.00104,0.00104,0.00104,0.,1900,400 },
-  {"P5"        ,"P5" ,    P5,      304.59050,640,496,496,0x0072,0.00780,0.00160,0.00160,0.00160,0.00780,0.00160,0.00160,0.00160,0.,1900,400 },
-  {"P7"        ,"P7" ,    P7,      406.12000,640,496,496,0x00F3,0.01040,0.00210,0.00210,0.00210,0.01040,0.00210,0.00210,0.00210,0.,1900,400 },
-  {"B/W 8"     ,"BW8" ,   BW8,       8.02850,160,120,120,0x0082,0.00600,0.00100,0.00100,0.00000,0.00600,0.00100,0.00100,0.00000,0.,1900,400 },
-  {"B/W 12"    ,"BW12" ,  BW12,     12.00100,160,120,120,0x0086,0.00600,0.00100,0.00100,0.00000,0.00600,0.00100,0.00100,0.00000,0.,1900,400 },
-  {"PD50"      ,"PD50",   PD50,     49.68690,320,256,128,0x00DD,0.02000,0.00000,0.00208,0.00000,0.02000,0.00000,0.00230,0.00000,0.,1900,400 },
-  {"PD90"      ,"PD90",   PD90,     89.99300,320,256,128,0x0063,0.02000,0.00000,0.00208,0.00000,0.02000,0.00000,0.00230,0.00000,0.,1900,400 },
-  {"PD120"     ,"PD120",  PD120,   126.10930,640,496,248,0x005F,0.02000,0.00000,0.00208,0.00000,0.02000,0.00000,0.00230,0.00000,0.,1900,400 },
-  {"PD160"     ,"PD160",  PD160,   160.89120,512,400,200,0x00E2,0.02000,0.00000,0.00200,0.00000,0.02000,0.00000,0.00230,0.00000,0.,1900,400 },
-  {"PD180"     ,"PD180",  PD180,   187.06100,640,496,248,0x0060,0.02000,0.00000,0.00200,0.00000,0.02000,0.00000,0.00230,0.00000,0.,1900,400 },
-  {"PD240"     ,"PD240",  PD240,   248.01300,640,496,248,0x00E1,0.02000,0.00000,0.00200,0.00000,0.02000,0.00000,0.00230,0.00000,0.,1900,400 },
-  {"PD290"     ,"PD290",  PD290,   288.69524,800,616,308,0x00DE,0.02000,0.00000,0.00200,0.00000,0.02000,0.00000,0.00230,0.00000,0.,1900,400 },
-  {"MP73"      ,"MP73",   MP73,     72.96350,320,256,128,0x2523,0.00900,0.00000,0.00100,0.00000,0.00900,0.00000,0.00100,0.00000,0.,1900,400 },
-	{"MP115"     ,"MP115",  MP115,   115.46000,320,256,128,0x2923,0.00900,0.00000,0.00100,0.00000,0.00900,0.00000,0.00100,0.00000,0.,1900,400 },
-	{"MP140"     ,"MP140",  MP140,   139.54000,320,256,128,0x2A23,0.00900,0.00000,0.00100,0.00000,0.00900,0.00000,0.00100,0.00000,0.,1900,400 },
-	{"MP175"     ,"MP175",  MP175,   175.38011,320,256,128,0x2C23,0.00900,0.00000,0.00100,0.00000,0.00900,0.00000,0.00100,0.00000,0.,1900,400 },
-	{"FAX480"    ,"FAX480", FAX480,  133.63300,512,500,500,0x0000,0.00512,0.00000,0.00000,0.00000,0.00512,0.00000,0.00000,0.00000,0.,1900,400 },
-	{"AVT24"     ,"AVT24",  AVT24,    22.50160,128,120,120,0x00c0,0.00500,0.00080,0.00050,0.00050,0.00500,0.00080,0.00000,0.00050,0.,1900,400 },
-	{"AVT90"     ,"AVT90",  AVT90,    90.00450,320,240,240,0x0044,0.00500,0.00080,0.00050,0.00050,0.00500,0.00080,0.00000,0.00050,0.,1900,400 },
-	{"AVT94"     ,"AVT94",  AVT94,    93.75000,320,200,200,0x0048,0.00500,0.00080,0.00050,0.00050,0.00500,0.00080,0.00000,0.00050,0.,1900,400 },
-	{"No Mode"   ,"NOTVALID",NOTVALID ,0.00000,0,0,0,0x0000,0.00000,0.00000,0.000000,0.0000,0.00000,0.00000,0.000000,0.0000,0.,0,0}
+//  name      shortName  mode      imagetime Pix Dis Txl  VIS     sync    fp      bp     blank   synctx   fptx    bptx    blanktx
+  {"Martin 1"  ,"M1",     M1,      114.29700,320,256,256,0xAC  ,0.00500,0.00080,0.00050,0.00050,0.00500,0.00080,0.00000,0.00050,0.,1900,400 },
+  {"Martin 2"  ,"M2",     M2,       58.06400,320,256,256,0x28  ,0.00500,0.00080,0.00050,0.00050,0.00500,0.00080,0.00000,0.00050,0.,1900,400 },
+  {"Scottie 1" ,"S1",     S1,      109.63250,320,256,256,0x3C  ,0.00900,0.00010,0.00125,0.00125,0.00900,0.00080,0.00080,0.00125,0.,1900,400 },
+  {"Scottie 2" ,"S2",     S2,       71.09450,320,256,256,0xB8  ,0.00900,0.00010,0.00150,0.00150,0.00900,0.00000,0.00110,0.00125,0.,1900,400 },
+  {"Scottie DX","SDX",    SDX,     268.89380,320,256,256,0xCC  ,0.00900,0.00000,0.00000,0.00100,0.00900,0.00000,0.00000,0.00100,0.,1900,400 },
+  {"SC2 60",    "SC2-60", SC2_60,   61.54350,320,256,256,0xBB  ,0.00500,0.00100,0.00100,0.00100,0.00500,0.00000,0.00000,0.00000,0.,1900,400 },
+  {"SC2 120",   "SC2-120",SC2_120, 121.74250,320,256,256,0x3F  ,0.00500,0.00100,0.00100,0.00100,0.00500,0.00000,0.00000,0.00000,0.,1900,400 },
+  {"SC2 180",   "SC2-180",SC2_180, 182.03850,320,256,256,0xB7  ,0.00500,0.00100,0.00100,0.00100,0.00500,0.00000,0.00000,0.00000,0.,1900,400 },
+  {"Robot 24",  "R24",    R24,      24.00150,160,120,120,0x84  ,0.00600,0.00010,0.00300,0.00450,0.00600,0.00000,0.00120,0.00380,0.,1900,400 },
+  {"Robot 36"  ,"R36",    R36,      36.00200,320,240,240,0x88  ,0.00900,0.00010,0.00350,0.00700,0.00900,0.00000,0.00300,0.00540,0.,1900,400 },
+  {"Robot 72"  ,"R72",    R72,      72.00500,320,240,240,0x0C  ,0.00900,0.00040,0.00350,0.00600,0.00900,0.00040,0.00250,0.00600,0.,1900,400 },
+  {"P3"        ,"P3" ,    P3,      203.06420,640,496,496,0x71  ,0.00520,0.00210,0.00080,0.00250,0.00520,0.00104,0.00104,0.00104,0.,1900,400 },
+  {"P5"        ,"P5" ,    P5,      304.59600,640,496,496,0x72  ,0.00780,0.00160,0.00160,0.00160,0.00780,0.00160,0.00160,0.00160,0.,1900,400 },
+  {"P7"        ,"P7" ,    P7,      406.12800,640,496,496,0xF3  ,0.01040,0.00210,0.00210,0.00210,0.01040,0.00210,0.00210,0.00210,0.,1900,400 },
+  {"B/W 8"     ,"BW8" ,   BW8,       8.02850,160,120,120,0x82  ,0.00600,0.00050,0.00150,0.00000,0.00600,0.00100,0.00100,0.00000,0.,1900,400 },
+  {"B/W 12"    ,"BW12" ,  BW12,     12.00100,160,120,120,0x86  ,0.00600,0.00050,0.00150,0.00000,0.00600,0.00100,0.00100,0.00000,0.,1900,400 },
+  {"PD50"      ,"PD50",   PD50,     49.68770,320,256,128,0xDD  ,0.02000,0.00000,0.00208,0.00000,0.02000,0.00000,0.00230,0.00000,0.,1900,400 },
+  {"PD90"      ,"PD90",   PD90,     89.99500,320,256,128,0x63  ,0.02000,0.00000,0.00208,0.00000,0.02000,0.00000,0.00230,0.00000,0.,1900,400 },
+  {"PD120"     ,"PD120",  PD120,   126.11150,640,496,248,0x5F  ,0.02000,0.00000,0.00208,0.00000,0.02000,0.00000,0.00230,0.00000,0.,1900,400 },
+  {"PD160"     ,"PD160",  PD160,   160.89420,512,400,200,0xE2  ,0.02000,0.00000,0.00200,0.00000,0.02000,0.00000,0.00230,0.00000,0.,1900,400 },
+  {"PD180"     ,"PD180",  PD180,   187.06450,640,496,248,0x60  ,0.02000,0.00000,0.00200,0.00000,0.02000,0.00000,0.00230,0.00000,0.,1900,400 },
+  {"PD240"     ,"PD240",  PD240,   248.01700,640,496,248,0xE1  ,0.02000,0.00200,0.00200,0.00000,0.02000,0.00000,0.00230,0.00000,0.,1900,400 },
+  {"PD290"     ,"PD290",  PD290,   288.70200,800,616,308,0xDE  ,0.02000,0.00000,0.00200,0.00000,0.02000,0.00000,0.00230,0.00000,0.,1900,400 },
+  {"MP73"      ,"MP73",   MP73,     72.9642,320,256,128,0x2523,0.00900,0.00000,0.00100,0.00000,0.00900,0.00000,0.00100,0.00000,0.,1900,400 },
+  {"MP115"     ,"MP115",  MP115,   115.4640 ,320,256,128,0x2923,0.00900,0.00000,0.00100,0.00000,0.00900,0.00000,0.00100,0.00000,0.,1900,400 },
+  {"MP140"     ,"MP140",  MP140,   139.5280,320,256,128,0x2A23,0.00900,0.00000,0.00100,0.00000,0.00900,0.00000,0.00100,0.00000,0.,1900,400 },
+  {"MP175"     ,"MP175",  MP175,   175.3730,320,256,128,0x2C23,0.00900,0.00000,0.00100,0.00000,0.00900,0.00000,0.00100,0.00000,0.,1900,400 },
+  {"MR73"      ,"MR73",   MR73,     73.2980 ,320,256,256,0x4523,0.00900,0.00000,0.00100,0.00000,0.00900,0.00000,0.00100,0.00000,0.,1900,400 },
+  {"MR90"      ,"MR90",   MR90,     90.1950 ,320,256,256,0x4623,0.00900,0.00000,0.00100,0.00000,0.00900,0.00000,0.00100,0.00000,0.,1900,400 },
+  {"MR115"     ,"MR115",  MR115,   115.2850 ,320,256,256,0x4923,0.00900,0.00000,0.00100,0.00000,0.00900,0.00000,0.00100,0.00000,0.,1900,400 },
+  {"MR140"     ,"MR140",  MR140,   140.3740 ,320,256,256,0x4a23,0.00900,0.00000,0.00100,0.00000,0.00900,0.00000,0.00100,0.00000,0.,1900,400 },
+  {"MR175"     ,"MR175",  MR175,   175.1920 ,320,256,256,0x4a23,0.00900,0.00000,0.00100,0.00000,0.00900,0.00000,0.00100,0.00000,0.,1900,400 },
+  {"ML180"     ,"ML180",  ML180,   180.2085 ,640,496,496,0x8523,0.00900,0.00050,0.00050,0.00050,0.00900,0.00000,0.00100,0.00000,0.,1900,400 },
+  {"ML240"     ,"ML240",  ML240,   239.7328 ,640,496,496,0x8623,0.00900,0.00050,0.00050,0.00050,0.00900,0.00000,0.00100,0.00000,0.,1900,400 },
+  {"ML280"     ,"ML280",  ML280,   280.4060 ,640,496,496,0x8923,0.00900,0.00000,0.00100,0.00000,0.00900,0.00000,0.00100,0.00000,0.,1900,400 },
+  {"ML320"     ,"ML320",  ML320,   320.0910 ,640,496,496,0x8A23,0.00900,0.00000,0.00100,0.00000,0.00900,0.00000,0.00100,0.00000,0.,1900,400 },
+  {"FAX480"    ,"FAX480", FAX480,  133.63300,512,500,500,0x00  ,0.00512,0.00000,0.00000,0.00000,0.00512,0.00000,0.00000,0.00000,0.,1900,400 },
+// narrowModes
+  {"MP73-Narrow" ,"MP73-N",   MP73N,   72.9665,320,256,128, 0x5C256D,0.00900,0.00000,0.00100,0.00000,0.00900,0.00000,0.00100,0.00000,0.,2172,128 },
+  {"MP110-Narrow" ,"MP110-N", MP110N, 109.8320,320,256,128, 0x44456D,0.00900,0.00000,0.00100,0.00000,0.00900,0.00000,0.00100,0.00000,0.,2172,128 },
+  {"MP140-Narrow" ,"MP140-N", MP140N, 139.5300,320,256,128 ,0x40556D,0.00900,0.00000,0.00100,0.00000,0.00900,0.00000,0.00100,0.00000,0.,2172,128 },
+
+  {"MC110-Narrow" ,"MC110-N",   MC110N,   109.703, 320,256,256,   0x05456D,0.00800,0.00000,0.00050,0.00000,0.00900,0.00000,0.00100,0.00000,0.,2172,128 },
+  {"MC140-Narrow" ,"MC140-N",   MC140N,   140.426, 320,256,256,   0x01556D,0.00800,0.00000,0.00050,0.00000,0.00900,0.00000,0.00100,0.00000,0.,2172,128 },
+  {"MC180-Narrow" ,"MC180-N",   MC180N,   180.363, 320,256,256,   0x0D656D,0.00800,0.00000,0.00050,0.00000,0.00900,0.00000,0.00100,0.00000,0.,2172,128 },
+
+  {"AVT24"     ,"AVT24",  AVT24,    22.50160,128,120,120,0xc0  ,0.00500,0.00080,0.00050,0.00050,0.00500,0.00080,0.00000,0.00050,0.,1900,400 },
+  {"AVT90"     ,"AVT90",  AVT90,    90.00450,320,240,240,0x44  ,0.00500,0.00080,0.00050,0.00050,0.00500,0.00080,0.00000,0.00050,0.,1900,400 },
+  {"AVT94"     ,"AVT94",  AVT94,    93.75000,320,200,200,0x48  ,0.00500,0.00080,0.00050,0.00050,0.00500,0.00080,0.00000,0.00050,0.,1900,400 },
+  {"No Mode"   ,"NOTVALID",NOTVALID ,0.00000,0,0,0,0x0000,0.00000,0.00000,0.000000,0.0000,0.00000,0.00000,0.000000,0.0000,0.,0,0}
+
 };
 
 
@@ -421,3 +458,16 @@ sSSTVParam SSTVTable[NUMSSTVMODES+1]=
 
 //}
 
+quint32 getMaxLineSamples()
+{
+  int i;
+  DSPFLOAT maxTime=0;
+  DSPFLOAT time;
+  for(i=M1;i<=FAX480;i++)
+  {
+    time=SSTVTable[i].imageTime/(DSPFLOAT)SSTVTable[i].numberOfDataLines;
+    if(time>maxTime) maxTime=time;
+  }
+  return rint(maxTime*SAMPLERATE);
+}
+
diff --git a/qsstv/sstv/sstvparam.h b/qsstv/sstv/sstvparam.h
index 4dd4e0b..b63e8f9 100644
--- a/qsstv/sstv/sstvparam.h
+++ b/qsstv/sstv/sstvparam.h
@@ -1,8 +1,7 @@
 #ifndef SSTVPARAM_H
 #define SSTVPARAM_H
 #include <QString>
-#include "qsstvglobal.h"
-#include "qsstvdefs.h"
+#include "appglobal.h"
 
 /** \file */
 
@@ -11,7 +10,7 @@ SSTV Parameter functions
 @author Johan Maes - ON4QZ
 */
 
-#define NUMSSTVMODES 31 //!< Number of SSTV Modes for RX and TX
+
 //#define NUMFAXMODES 3 //!< Number of FAX Modes for RX and TX
 
 
@@ -32,46 +31,68 @@ SSTV Parameter functions
 
 
 /**
-	\brief SSTV Modes
-	
+  \brief SSTV Modes
+
   M1 to FAX480 are using sync pulses, AVT modes do not use syncs.
 */
 enum esstvMode
 {
-M1,
-M2,
-S1,
-S2,
-SDX,
-SC2_60,
-SC2_120,
-SC2_180,
-R24,
-R36,
-R72,
-P3,
-P5,
-P7,
-BW8,
-BW12,
-PD50,
-PD90,
-PD120,
-PD160,
-PD180,
-PD240,
-PD290,
-MP73,
-MP115,
-MP140,
-MP175,
-FAX480,
-AVT24,
-AVT90,
-AVT94,
-NOTVALID
+  M1,
+  M2,
+  S1,
+  S2,
+  SDX,
+  SC2_60,
+  SC2_120,
+  SC2_180,
+  R24,
+  R36,
+  R72,
+  P3,
+  P5,
+  P7,
+  BW8,
+  BW12,
+  PD50,
+  PD90,
+  PD120,
+  PD160,
+  PD180,
+  PD240,
+  PD290,
+  MP73,
+  MP115,
+  MP140,
+  MP175,
+  MR73,
+  MR90,
+  MR115,
+  MR140,
+  MR175,
+  ML180,
+  ML240,
+  ML280,
+  ML320,
+  FAX480,
+  MP73N,
+  MP110N,
+  MP140N,
+  MC110N,
+  MC140N,
+  MC180N,
+  AVT24,
+  AVT90,
+  AVT94,
+  NOTVALID
 };
 
+#define NUMSSTVMODES NOTVALID //!< Number of SSTV Modes for RX and TX
+#define STARTNARROW MP73N
+#define ENDNARROW MC180N
+
+#define STARTWIDE M1
+#define ENDWIDE FAX480
+
 //enum efaxMode
 //{
 //	NOAA,
@@ -93,31 +114,31 @@ struct sTimeFreq
 
 /** \brief sstv parameter structure
 
-	Structure containing all the mode depended parameters  Some of the parameters are updated at run time
-	
+  Structure containing all the mode depended parameters  Some of the parameters are updated at run time
+
 */
 
 struct sSSTVParam
 {
   QString name;
   QString shortName;
-	enum esstvMode mode;
+  enum esstvMode mode;
   DSPFLOAT imageTime;
   unsigned int numberOfPixels; // NumberOfPixels per Line
   unsigned int numberOfDisplayLines;
-	unsigned int numberOfDataLines;  // data lines
-  unsigned short int VISCode;
-	float sync;			//used for rx
-	float fp;
-	float bp;
-	float blank;
-	float synct;		// used for tx
-	float fpt;
-	float bpt;
-	float blankt;
-	DSPFLOAT pixelDuration;
-	int subcarrier;
-	int deviation;
+  unsigned int numberOfDataLines;  // data lines
+  quint32 VISCode;
+  float sync;			//used for rx
+  float fp;
+  float bp;
+  float blank;
+  float synct;		// used for tx
+  float fpt;
+  float bpt;
+  float blankt;
+  DSPFLOAT pixelDuration;
+  int subcarrier;
+  int deviation;
 };
 
 //struct sFAXParam
@@ -155,8 +176,8 @@ extern DSPFLOAT *lineTimeTableTX;
 
 
 void setupSSTVLineTimeTable(esstvMode modeIndex,DSPFLOAT clock,bool transmit);
-DSPFLOAT lineLength(esstvMode modeIndex,DSPFLOAT clock);
-DSPFLOAT syncWidth(esstvMode modeIndex,DSPFLOAT clock);
+DSPFLOAT getLineLength(esstvMode modeIndex,DSPFLOAT clock);
+DSPFLOAT getSyncWidth(esstvMode modeIndex,DSPFLOAT clock);
 //void setupFAXLineTimeTable(DSPFLOAT clock);
 esstvMode initializeParametersVIS(unsigned int viscode,bool tx);
 bool  initializeSSTVParametersIndex(esstvMode modeIndex,bool tx);
@@ -164,6 +185,8 @@ bool  initializeSSTVParametersIndex(esstvMode modeIndex,bool tx);
 esstvMode lookupVIS(unsigned int vc);
 QString getSSTVModeNameLong(esstvMode m);
 QString getSSTVModeNameShort(esstvMode m);
+
+void dumpSamplesPerLine();
 //QString getFAXModeNameLong(efaxMode m);
 //QString getFAXModeShort(efaxMode m);
 
@@ -172,17 +195,15 @@ DSPFLOAT longestLine(DSPFLOAT clock);
 bool lineIsValid(esstvMode mode,unsigned int lineLength,DSPFLOAT clock);
 void printActiveSSTVParam(bool tx);
 void copyCustomParam(bool tx);
+quint32 getMaxLineSamples();
 
 
 extern bool useVIS;
 extern bool autoSlantAdjust;
 extern bool autoSave;
 extern int squelch;
-extern int filterIndex;
-extern esstvMode sstvModeIndex;
-
-
-
+extern esstvMode sstvModeIndexRx;
+extern esstvMode sstvModeIndexTx;
 #endif
 
 
diff --git a/qsstv/sstv/sstvrx.cpp b/qsstv/sstv/sstvrx.cpp
new file mode 100644
index 0000000..d4c58c6
--- /dev/null
+++ b/qsstv/sstv/sstvrx.cpp
@@ -0,0 +1,438 @@
+#include "sstvrx.h"
+#include "appglobal.h"
+#include "configparams.h"
+#include "dispatcher.h"
+#include "filterparam.h"
+#include "filters.h"
+#include "modes/modebase.h"
+
+
+#ifndef QT_NO_DEBUG
+#include "utils/arraydumper.h"
+#include "scope/scopeview.h"
+#include "scope/scopeoffset.h"
+#endif
+
+QString defaultImageFormat;
+int minCompletion;
+
+const QString stateStr[sstvRx::END+1]=
+{
+  "Hunting",
+  "Processing",
+  "WaitForSync",
+  "SlantAdjust",
+  "Restart",
+  "Sync Lost",
+  "Wait",
+  "End"
+};
+
+
+sstvRx::sstvRx(QObject *parent) : QObject(parent),syncNarrowProc(true),syncWideProc(false)
+{
+  syncFilterPtr=NULL;
+  videoFilterPtr=NULL;
+#ifndef QT_NO_DEBUG
+  scopeViewerData=new scopeView("Data Scope");
+  scopeViewerSyncNarrow=new scopeView("Sync Scope Narrow");
+  scopeViewerSyncWide=new scopeView("Sync Scope Wide");
+#endif
+}
+
+void sstvRx::init()
+{
+  setFilters(); // setup sstvRx Filters
+  resetParams(true);
+#ifndef QT_NO_DEBUG
+  scopeViewerData->setAlternativeScaleMultiplier(SUBSAMPLINGFACTOR/rxClock);
+  scopeViewerData->setCurveName("RX VOL",SCDATA1);
+  scopeViewerData->setCurveName("TEST",SCDATA2);
+  scopeViewerData->setCurveName("STATE",SCDATA3);
+  scopeViewerData->setCurveName("DEMOD",SCDATA4);
+  scopeViewerData->setAxisTitles("Samples","int","State");
+
+  scopeViewerSyncNarrow->setAlternativeScaleMultiplier(SUBSAMPLINGFACTOR/rxClock);
+  scopeViewerSyncWide->setAlternativeScaleMultiplier(SUBSAMPLINGFACTOR/rxClock);
+#endif
+}
+void sstvRx::resetParams(bool bufferReset)
+{
+  SSTVState=HUNTING;
+  bufferCounter=0;
+  if(bufferReset)
+    {
+      bufferVideoDemod.reset();
+      bufferSync1200Vol.reset();
+      bufferSync1900Vol.reset();
+      bufferInputVol.reset();
+//      bufferSyncDemod.skip(RXSTRIPE);
+      syncNarrowProc.reset();
+      syncWideProc.reset();
+    }
+  else
+    {
+      syncNarrowProc.init();
+      syncWideProc.init();
+    }
+}
+
+sstvRx::~sstvRx()
+{
+  if(videoFilterPtr!=NULL) delete videoFilterPtr;
+  if(syncFilterPtr !=NULL) delete syncFilterPtr;
+}
+
+void sstvRx::setFilters()
+{
+  if(videoFilterPtr==NULL) videoFilterPtr=new videoFilter(RXSTRIPE);
+  else videoFilterPtr->init();
+  if(syncFilterPtr==NULL) syncFilterPtr=new syncFilter(RXSTRIPE);
+  else syncFilterPtr->init();
+}
+
+
+
+void sstvRx::run(DSPFLOAT *dataPtr, unsigned int *inputVolumePtr)
+{
+  bufferCounter++;
+  if(videoFilterPtr==NULL)
+    {
+      errorOut() << "videoFltr NULL";
+      return;
+    }
+  videoFilterPtr->process(dataPtr);
+  bufferVideoDemod.putNoCheck(videoFilterPtr->demodPtr,RXSTRIPE);
+  syncFilterPtr->process(dataPtr);
+  //  bufferSyncDemod.putNoCheck(syncFilterPtr->demodPtr,RXSTRIPE);
+  bufferSync1200Vol.putNoCheck(syncFilterPtr->detect1200Ptr,RXSTRIPE);
+  bufferSync1900Vol.putNoCheck(syncFilterPtr->detect1900Ptr,RXSTRIPE);
+  //  bufferSyncVol.putNoCheck(syncFilterPtr->test1Ptr,RXSTRIPE);
+  //  bufferTest.putNoCheck(syncFilterPtr->test2Ptr,RXSTRIPE);
+  bufferInputVol.putNoCheck(inputVolumePtr,RXSTRIPE);
+
+  while (bufferVideoDemod.count())
+    {
+      syncWideProc.freqPtr=bufferVideoDemod.readPointer();
+      syncNarrowProc.freqPtr=bufferVideoDemod.readPointer();
+      syncWideProc.syncVolumePtr =bufferSync1200Vol.readPointer();
+      syncNarrowProc.syncVolumePtr =bufferSync1900Vol.readPointer();
+      syncWideProc.inputVolumePtr=bufferInputVol.readPointer();
+      syncNarrowProc.inputVolumePtr=bufferInputVol.readPointer();
+
+      displaySyncEvent* ce;
+      if(syncProcPtr)
+        {
+          ce = new displaySyncEvent(syncProcPtr->syncQuality);
+        }
+      else
+        {
+          ce = new displaySyncEvent(0);
+        }
+      QApplication::postEvent(dispatcherPtr, ce);
+#ifndef QT_NO_DEBUG
+      scopeViewerData->addData(SCDATA2,dataPtr,syncWideProc.sampleCounter,RXSTRIPE);
+      scopeViewerData->addData(SCDATA4,bufferVideoDemod.readPointer(),syncWideProc.sampleCounter,RXSTRIPE);
+#endif
+
+      process();
+    }
+  //  addToLog(QString("After process readIndex:=%1 sampleCounter:=%2").arg(bufferVideoDemod.getReadIndex()).arg(syncProcPtr->sampleCounter),LOGRXFUNC);
+}
+
+void sstvRx::advanceBuffers()
+{
+  syncWideProc.sampleCounter+=RXSTRIPE;
+  syncNarrowProc.sampleCounter+=RXSTRIPE;
+  bufferVideoDemod.skip(RXSTRIPE);
+  bufferSync1200Vol.skip(RXSTRIPE);
+  bufferSync1900Vol.skip(RXSTRIPE);
+  bufferInputVol.skip(RXSTRIPE);
+}
+
+void sstvRx::rewindBuffers(uint rlen)
+{
+  syncWideProc.sampleCounter-=rlen;
+  syncNarrowProc.sampleCounter-=rlen;
+  bufferVideoDemod.rewind(rlen);
+  bufferSync1200Vol.rewind(rlen);
+  bufferSync1900Vol.rewind(rlen);
+  bufferInputVol.rewind(rlen);
+}
+
+
+
+
+void sstvRx::process()
+{
+//  unsigned int ri;
+  quint32 block;
+  quint32 syncPosition;
+  quint32 sampleCounterLatch;
+  quint32 diff;
+
+  syncProcessor::esyncProcessState syncStateWide;
+  syncProcessor::esyncProcessState syncStateNarrow;
+  syncProcessor::esyncProcessState syncState;
+  rxSSTVStatusEvent *stce;
+
+  syncWideProc.process();
+
+  syncStateWide=syncWideProc.getSyncState(syncPosition);
+
+  if(syncStateWide!=syncProcessor::MODEDETECT)
+    {
+      usingWide=true;
+      syncNarrowProc.setEnabled(false);
+      syncProcPtr=&syncWideProc;
+     }
+  else
+    {
+      syncNarrowProc.process();
+      syncStateNarrow=syncNarrowProc.getSyncState(syncPosition);
+      if(syncStateNarrow!=syncProcessor::MODEDETECT)
+        {
+          usingWide=false;
+          syncWideProc.setEnabled(false);
+          syncProcPtr=&syncNarrowProc;
+        }
+      else
+        {
+          syncProcPtr=NULL;
+          syncState=syncProcessor::MODEDETECT;
+          if(SSTVState!=HUNTING)
+            {
+              switchState(HUNTING);
+            }
+        }
+     }
+  if(syncProcPtr)
+    {
+      syncState=syncProcPtr->getSyncState(syncPosition);
+    }
+
+
+  if((syncProcPtr!=0) && (syncProcPtr->getSyncState(syncPosition)==syncProcessor::SYNCLOST))
+    {
+      switchState(SYNCLOST);
+    }
+  switch (SSTVState)
+    {
+    case HUNTING:
+      if(syncProcPtr==NULL)
+        {
+          stce= new rxSSTVStatusEvent(QString("No sync"));
+          QApplication::postEvent( dispatcherPtr, stce );  // Qt will delete it when done
+          advanceBuffers();
+          break; // no sync
+        }
+      stce= new rxSSTVStatusEvent(QString("Receiving ")+getSSTVModeNameLong(syncProcPtr->getMode()));
+      lastUsedModeStr=getSSTVModeNameShort(syncProcPtr->getMode());
+      QApplication::postEvent( dispatcherPtr, stce );  // Qt will delete it when done
+      // fall trough for first processing
+      switchState(SLANTADJUST); // for logging
+      // clear the call received via fskID
+      emit (resetCall());
+
+    case SLANTADJUST:
+      sampleCounterLatch=syncProcPtr->sampleCounter; //remember where we've got
+//      ri=bufferVideoDemod.getReadIndex();
+//      addToLog(QString("rxFunctions: sampleCounterLatch= %1,readIndex=%2").arg(sampleCounterLatch).arg(ri),LOGRXFUNC);
+      block=(syncPosition)/RXSTRIPE;
+      bufferVideoDemod.rewind(syncProcPtr->sampleCounter-block*RXSTRIPE);
+//      ri=bufferVideoDemod.getReadIndex();
+      //      addToLog(QString("sc_rewind: block=%1,new readIndex= %2").arg(block).arg(ri),LOGRXFUNC);
+      syncProcPtr->sampleCounter=block*RXSTRIPE;
+      syncProcPtr->currentModePtr->setRxSampleCounter(syncProcPtr->sampleCounter);
+      syncProcPtr->currentModePtr->redrawFast(true);
+      syncProcPtr->currentModePtr->process(bufferVideoDemod.readPointer(),syncPosition-syncProcPtr->sampleCounter,true);
+      //    scopeViewerData->addData(SCDATA2,bufferVideoDemod.readPointer(),syncProcPtr->sampleCounter,RXSTRIPE);
+      //      addToLog(QString("slant scope add demodIdx=%1; syncProcPtr->sampleCounter=%2").arg(bufferVideoDemod.getReadIndex()).arg(syncProcPtr->sampleCounter),LOGRXFUNC);
+#ifndef QT_NO_DEBUG
+      scopeViewerData->addData(SCDATA3,syncProcPtr->currentModePtr->debugStatePtr,syncProcPtr->sampleCounter,RXSTRIPE);
+#endif
+      addToLog(QString("rxFunctions: currentMode pos:=%1, syncProcPtr->sampleCounter %2").arg(syncPosition-syncProcPtr->sampleCounter).arg(syncProcPtr->sampleCounter),LOGRXFUNC);
+      //      addToLog(QString("after Current mode set: %1,syncProcPtr->sampleCounter: %2").arg(rxHoldingBuffer.getReadIndex()).arg(syncProcPtr->sampleCounter),LOGRXFUNC);
+      while(syncProcPtr->sampleCounter<sampleCounterLatch)
+        {
+          bufferVideoDemod.skip(RXSTRIPE);
+          syncProcPtr->sampleCounter+=RXSTRIPE;
+          //          addToLog(QString("loop readIndex: %1,syncProcPtr->sampleCounter: %2").arg(rxHoldingBuffer.getReadIndex()).arg(syncProcPtr->sampleCounter),LOGRXFUNC);
+          syncProcPtr->currentModePtr->process(bufferVideoDemod.readPointer());
+          //      scopeViewerData->addData(SCDATA2,bufferVideoDemod.readPointer(),syncProcPtr->sampleCounter,RXSTRIPE);
+#ifndef QT_NO_DEBUG
+          scopeViewerData->addData(SCDATA3,syncProcPtr->currentModePtr->debugStatePtr,syncProcPtr->sampleCounter,RXSTRIPE);
+#endif
+        }
+      addToLog(QString("end loop readIndex: %1,syncProcPtr->sampleCounter: %2").arg(bufferVideoDemod.getReadIndex()).arg(syncProcPtr->sampleCounter),LOGRXFUNC);
+      syncProcPtr->currentModePtr->redrawFast(false);
+      syncProcPtr->recalculateMatchArray();
+      switchState(PROCESSING);
+      advanceBuffers();
+      break;
+    case PROCESSING:
+      if(syncState!=syncProcessor::INSYNC)
+        {
+          switchState(END);
+        }
+      else if(syncProcPtr->retraceFlag)
+        {
+          addToLog(QString("retrace detected"),LOGRXFUNC);
+          saveImage();
+          //          addToLog(QString("before rewind readIndex:=%1 sampleCounter:=%2").arg(bufferVideoDemod.getReadIndex()).arg(syncProcPtr->sampleCounter),LOGRXFUNC);
+          rewindBuffers(8*RXSTRIPE);
+          syncProcPtr->resetRetraceFlag();
+          resetParams(false);
+          //          addToLog(QString("after resetParms readIndex:=%1 sampleCounter:=%2").arg(bufferVideoDemod.getReadIndex()).arg(syncProcPtr->sampleCounter),LOGRXFUNC);
+          break;
+        }
+
+
+      else
+        {
+          if(syncProcPtr->currentModePtr->process(bufferVideoDemod.readPointer())==modeBase::MBENDOFIMAGE)
+            {
+              switchState(END);
+            }
+        }
+
+      if(syncProcPtr->hasNewClock())
+        {
+          syncProcPtr->currentModePtr->init(syncProcPtr->getNewClock());
+          switchState(SLANTADJUST);
+        }
+#ifndef QT_NO_DEBUG
+      scopeViewerData->addData(SCDATA3,syncProcPtr->currentModePtr->debugStatePtr,syncProcPtr->sampleCounter,RXSTRIPE);
+#endif
+      advanceBuffers();
+      if(syncProcPtr->tempOutOfSync)
+        {
+          bufferIdx=bufferVideoDemod.getReadIndex();
+          switchState(WAITFORSYNC);
+        }
+      break;
+    case WAITFORSYNC:
+      {
+
+        if(!(syncState==syncProcessor::INSYNC))
+          {
+            switchState(END);
+          }
+        else if(syncProcPtr->retraceFlag)
+          {
+            addToLog(QString("retrace detected"),LOGRXFUNC);
+            saveImage();
+            //          addToLog(QString("before rewind readIndex:=%1 sampleCounter:=%2").arg(bufferVideoDemod.getReadIndex()).arg(syncProcPtr->sampleCounter),LOGRXFUNC);
+            rewindBuffers(8*RXSTRIPE);
+            syncProcPtr->resetRetraceFlag();
+            resetParams(false);
+            //          addToLog(QString("after resetParms readIndex:=%1 sampleCounter:=%2").arg(bufferVideoDemod.getReadIndex()).arg(syncProcPtr->sampleCounter),LOGRXFUNC);
+            break;
+          }
+
+        else
+          {
+            currentIdx=bufferVideoDemod.getReadIndex();
+            if(!syncProcPtr->tempOutOfSync)
+              {
+                bufferVideoDemod.setReadIndex(bufferIdx);
+                while(bufferVideoDemod.getReadIndex()!=currentIdx)
+                  {
+                    if(syncProcPtr->currentModePtr->process(bufferVideoDemod.readPointer())==modeBase::MBENDOFIMAGE)
+                      {
+                        switchState(END);
+                      }
+                    bufferVideoDemod.skip(RXSTRIPE);
+
+                  }
+                if(syncProcPtr->currentModePtr->process(bufferVideoDemod.readPointer())==modeBase::MBENDOFIMAGE)
+                  {
+                    switchState(END);
+                  }
+                switchState(PROCESSING);
+              }
+          }
+        advanceBuffers();
+        break;
+      }
+    case RESTART:
+      resetParams(true);
+      break;
+    case SYNCLOST:
+      saveImage();
+      diff=(syncProcPtr->sampleCounter-syncProcPtr->lastValidSyncCounter)/RXSTRIPE;
+      addToLog(QString("rewind after synclost %1").arg(diff),LOGRXFUNC);
+      rewindBuffers(diff*RXSTRIPE);
+      syncProcPtr->resetRetraceFlag();
+      resetParams(false);
+      break;
+    case WAIT:
+      break;
+    case END:
+
+      saveImage();
+      resetParams(false); // will set state to HUNTING
+      advanceBuffers();
+      break;
+    }
+}
+
+void sstvRx::saveImage()
+{
+  bool done;
+  addToLog("saveImage",LOGRXFUNC);
+  endImageSSTVRXEvent *endce;
+  if(syncProcPtr->currentModePtr->receivedLines()<(syncProcPtr->currentModePtr->imageLines()*minCompletion)/100)
+    {
+      endce = new endImageSSTVRXEvent("");
+    }
+  else
+    {
+      endce = new endImageSSTVRXEvent(getSSTVModeNameShort(syncProcPtr->getMode()));
+    }
+  endce->waitFor(&done);
+  QApplication::postEvent(dispatcherPtr, endce);
+  while(!done) { usleep(100);}
+}
+
+
+void sstvRx::switchState(eSSTVState  newState)
+{
+  addToLog(QString("%1 to %2").arg(stateStr[SSTVState]).arg(stateStr[newState]),LOGRXFUNC);
+  SSTVState=newState;
+}
+
+void sstvRx::eraseImage()
+{
+  switchState(RESTART);
+  while(SSTVState!=HUNTING)
+    {
+      QApplication::processEvents();
+    }
+}
+
+
+#ifndef QT_NO_DEBUG
+unsigned int sstvRx::setOffset(unsigned int offset,bool ask)
+{
+  unsigned int xOffset;
+  if(ask)
+    {
+      scopeOffset so;
+      so.setOffset(offset);
+      if(so.exec()==QDialog::Accepted)
+        {
+          xOffset=so.getOffset()*1000;
+        }
+    }
+  else
+    {
+      xOffset=offset*1000;
+    }
+  syncNarrowProc.setOffset(xOffset);
+  syncWideProc.setOffset(xOffset);
+  scopeViewerData->setOffset(xOffset);
+  return xOffset/1000;
+}
+#endif
+
diff --git a/qsstv/sstv/sstvrx.h b/qsstv/sstv/sstvrx.h
new file mode 100644
index 0000000..d88cc9e
--- /dev/null
+++ b/qsstv/sstv/sstvrx.h
@@ -0,0 +1,75 @@
+#ifndef SSTVRX_H
+#define SSTVRX_H
+
+#include <QObject>
+#include "appdefs.h"
+#include "utils/buffermanag.h"
+#include "syncprocessor.h"
+
+
+
+extern int minCompletion;
+
+
+
+class modeBase;
+
+class syncFilter;
+class videoFilter;
+class rectConvolution;
+class integrator;
+
+class sstvRx : public QObject
+{
+
+  Q_OBJECT
+public:
+  enum eSSTVState {HUNTING,PROCESSING,WAITFORSYNC,SLANTADJUST,RESTART,SYNCLOST,WAIT,END};
+  explicit sstvRx(QObject *parent = 0);
+  ~sstvRx();
+  void init();
+  void setFilters();
+  void run(DSPFLOAT *dataPtr, unsigned int *inputVolumePtr);
+  void eraseImage();
+  syncProcessor syncNarrowProc;
+  syncProcessor   syncWideProc;
+  #ifndef QT_NO_DEBUG
+  unsigned int setOffset(unsigned int offset,bool ask);
+#endif
+
+signals:
+  void resetCall();
+private:
+//  void getData();
+  void process();
+  void switchState(eSSTVState  newState);
+  void resetParams(bool bufferReset);
+  void saveImage();
+  void advanceBuffers();
+  void rewindBuffers(uint rlen);
+
+
+//  DSPFLOAT rxHoldingBuffer[RXSTRIPE];
+  buffer<quint16,22> bufferVideoDemod;  // 2^22= 4194304, divided by samplingrate 12000 gives 349 seconds buffering
+//  buffer<quint16,22> bufferSyncDemod;  // 2^22= 4194304, divided by samplingrate 12000 gives 349 seconds buffering
+  buffer<DSPFLOAT,22> bufferSync1200Vol;  // 2^22= 4194304, divided by samplingrate 12000 gives 349 seconds buffering
+  buffer<DSPFLOAT,22> bufferSync1900Vol;  // 2^22= 4194304, divided by samplingrate 12000 gives 349 seconds buffering
+  buffer<DSPFLOAT,22> bufferTest;  // 2^22= 4194304, divided by samplingrate 12000 gives 349 seconds buffering
+  buffer<unsigned int,22> bufferInputVol;  // 2^22= 4194304, divided by samplingrate 12000 gives 349 seconds buffering
+//  buffer<quint16,22> bufferInputVolume;
+
+  syncFilter *syncFilterPtr;
+  videoFilter *videoFilterPtr;
+  DSPFLOAT tempBuffer[RXSTRIPE];
+  rectConvolution *syncConvolvePtr;
+  integrator *volumeIntergratorPtr;
+  eSSTVState SSTVState;
+  unsigned int bufferCounter;
+  QString lastUsedModeStr;
+  unsigned int bufferIdx;
+  unsigned int currentIdx;
+  bool usingWide;
+  syncProcessor *syncProcPtr;
+};
+
+#endif // SSTVRX_H
diff --git a/qsstv/sstv/sstvtx.cpp b/qsstv/sstv/sstvtx.cpp
new file mode 100644
index 0000000..0c058e7
--- /dev/null
+++ b/qsstv/sstv/sstvtx.cpp
@@ -0,0 +1,252 @@
+#include "sstvtx.h"
+#include "appglobal.h"
+#include "configparams.h"
+#include "soundbase.h"
+#include "sstv/cw.h"
+#include "dispatcher.h"
+#include "synthes.h"
+#include "modes/modes.h"
+#include "txfunctions.h"
+
+
+sstvTx::sstvTx()
+{
+  currentMode=0;
+  oldMode=NOTVALID;
+}
+sstvTx::~sstvTx()
+{
+  if(currentMode) delete currentMode;
+}
+
+void sstvTx::init()
+{
+  sampleCounter=0;
+}
+
+
+
+
+void sstvTx::sendPreamble()
+{
+  addToLog("txFunc:sendPreamble",LOGTXFUNC);
+  if(useVOX) synthesPtr->sendTone(1.,1700.,0,false);
+  synthesPtr->sendTone(0.1,1900.,0,true);
+  synthesPtr->sendTone(0.1,1500.,0,true);
+  synthesPtr->sendTone(0.1,1900.,0,true);
+  synthesPtr->sendTone(0.1,1500.,0,true);
+  synthesPtr->sendTone(0.1,2300.,0,true);
+  synthesPtr->sendTone(0.1,1500.,0,true);
+  synthesPtr->sendTone(0.1,2300.,0,true);
+  synthesPtr->sendTone(0.1,1500.,0,true);
+  synthesPtr->sendTone(0.3,1900.,0,true);
+  synthesPtr->sendTone(0.01,1200.,0,true);
+  synthesPtr->sendTone(0.3,1900.,0,true);
+}
+
+
+
+void sstvTx::sendVIS()
+{
+  int i,l;
+  int t=txSSTVParam.VISCode;
+  addToLog("txFunc:sendVis",LOGTXFUNC);
+  if(currentMode->isNarrow())
+    {
+      l=24;
+      synthesPtr->sendTone(0.300,1900,0,true);
+      synthesPtr->sendTone(0.100,2100,0,true);
+      synthesPtr->sendTone(0.022,1900,0,true); // startbit
+      for (i=0;i<l;i++)
+        {
+          if((t&1)==1) synthesPtr->sendTone(0.022,1900,0,true);
+          else synthesPtr->sendTone(0.022,2100,0,true);
+          t>>=1;
+        }
+    }
+  else
+    {
+      if ((t&0xFF)==0x23) l=16;
+      else l=8;
+      synthesPtr->sendTone(0.030,1200,0,true); // startbit
+      for (i=0;i<l;i++)
+        {
+          if((t&1)==1) synthesPtr->sendTone(0.030,1100,0,true);
+          else synthesPtr->sendTone(0.030,1300,0,true);
+          t>>=1;
+        }
+      synthesPtr->sendTone(0.030,1200,0,true); // stopbit
+    }
+}
+
+
+
+bool sstvTx::create(esstvMode m,DSPFLOAT clock)
+{
+  if((oldMode==m) && (currentMode!=NULL))
+    {
+      currentMode->init(clock);
+      return true;
+    }
+  oldMode=m;
+  if(currentMode) delete currentMode;
+  currentMode=0;
+  switch (m)
+    {
+    case M1:
+    case M2:
+      currentMode=new modeGBR(m,TXSTRIPE,true,false);
+      break;
+    case S1:
+    case S2:
+    case SDX:
+      currentMode=new modeGBR2(m,TXSTRIPE,true,false);
+      break;
+    case R36:
+      currentMode=new modeRobot1(m,TXSTRIPE,true,false);
+      break;
+    case R24:
+    case R72:
+    case MR73:
+    case MR90:
+    case MR115:
+    case MR140:
+    case MR175:
+    case ML180:
+    case ML240:
+    case ML280:
+    case ML320:
+      currentMode=new modeRobot2(m,TXSTRIPE,true,false);
+      break;
+    case SC2_60:
+    case SC2_120:
+    case SC2_180:
+    case P3:
+    case P5:
+    case P7:
+    case MC110N:
+    case MC140N:
+    case MC180N:
+      currentMode=new modeRGB(m,TXSTRIPE,true,false);
+      break;
+    case FAX480:
+    case BW8:
+    case BW12:
+      currentMode=new modeBW(m,TXSTRIPE,true,false);
+      break;
+    case AVT24:
+    case AVT90:
+    case AVT94:
+      currentMode=new modeAVT(m,TXSTRIPE,true,false);
+      break;
+    case PD50:
+    case PD90:
+    case PD120:
+    case PD160:
+    case PD180:
+    case PD240:
+    case PD290:
+    case MP73:
+    case MP115:
+    case MP140:
+    case MP175:
+      currentMode=new modePD(m,TXSTRIPE,true,false);
+      break;
+
+    case MP73N:
+    case MP110N:
+    case MP140N:
+      currentMode=new modePD(m,TXSTRIPE,true,true);
+      break;
+    default:
+      m=NOTVALID;
+      break;
+    }
+  if (m!=NOTVALID)
+    {
+      initializeSSTVParametersIndex(m,true);
+      QString s=getSSTVModeNameLong(m);
+      addToLog("create: create TX mode",LOGTXFUNC);
+      currentMode->init(clock);
+      return true;
+    }
+  return false;
+}
+
+double sstvTx::FSKIDTime()
+{
+  double tim;
+  double charTime=0.022*6;
+  tim=(myCallsign.size()+3)*charTime;
+  tim+=0.422;
+  return tim;
+}
+
+double sstvTx::calcTxTime(int overheadTime)
+{
+  double tim=0;
+  //  tim= soundIOPtr->getPlaybackStartupTime();
+  tim+=SILENCEDELAY;
+  initializeSSTVParametersIndex(sstvModeIndexTx,true);
+  int t=txSSTVParam.VISCode;
+  tim+=1.41; //preamble;
+  if ((t&0xFF)==0x23) tim+=18.*0.03;
+  else tim+=10.*0.03;
+  tim+=txSSTVParam.imageTime;
+
+  if(enableCW)
+    {
+      tim+=0.5 ;//CW silence gap
+      initCW(cwText);
+      tim+=getCWDuration();
+      tim+=0.3; // trailer;
+    }
+  else
+    {
+      tim+=FSKIDTime();
+    }
+  tim+=overheadTime;
+  return tim;
+}
+
+bool sstvTx::sendImage(imageViewer *ivPtr)
+{
+  modeBase::eModeBase mb;
+  if(txSSTVParam.mode==FAX480)
+    {
+      for (int i=0;i<1220;i++)
+        {
+          synthesPtr->sendTone(0.00205,1500,0,true);
+          synthesPtr->sendTone(0.00205,2300,0,true);
+        }
+    }
+  else
+    {
+      sendPreamble();
+      sendVIS();
+    }
+  addToLog("txFunc: sendImage",LOGTXFUNC);
+  mb=currentMode->transmitImage(ivPtr);
+  if(mb==modeBase::MBABORTED) return false;
+  else  return true;
+}
+
+void sstvTx::applyTemplate(QString templateFilename,bool useTemplate,imageViewer *ivPtr)
+{
+  create(sstvModeIndexTx,txClock);
+
+  ivPtr->setParam(templateFilename,useTemplate, txSSTVParam.numberOfPixels,txSSTVParam.numberOfDisplayLines);
+}
+
+void sstvTx::abort()
+{
+  if(currentMode) currentMode->abort();
+}
+
+
+bool sstvTx::aborted()
+{
+  if(currentMode) return currentMode->aborted();
+  else return true;
+
+}
diff --git a/qsstv/sstv/sstvtx.h b/qsstv/sstv/sstvtx.h
new file mode 100644
index 0000000..7675376
--- /dev/null
+++ b/qsstv/sstv/sstvtx.h
@@ -0,0 +1,35 @@
+#ifndef SSTVTX_H
+#define SSTVTX_H
+#include "sstvparam.h"
+
+
+class modeBase;
+class imageViewer;
+
+class sstvTx
+{
+public:
+  sstvTx();
+  ~sstvTx();
+  void init();
+  double calcTxTime(int overheadTime);
+  bool sendImage(imageViewer *ivPtr);
+  void abort();
+  bool aborted();
+  void applyTemplate(QString templateFilename, bool useTemplate, imageViewer *ivPtr);
+
+
+private:
+  modeBase *currentMode;
+  bool create(esstvMode m,DSPFLOAT clock);
+  void sendPreamble();
+  void sendVIS();
+  esstvMode oldMode;
+  unsigned long sampleCounter;
+  double FSKIDTime();
+
+
+
+};
+
+#endif // SSTVTX_H
diff --git a/qsstv/sstv/syncprocessor.cpp b/qsstv/sstv/syncprocessor.cpp
index b04d813..4cd2e95 100644
--- a/qsstv/sstv/syncprocessor.cpp
+++ b/qsstv/sstv/syncprocessor.cpp
@@ -1,49 +1,106 @@
 #include "syncprocessor.h"
-#include "qsstvglobal.h"
+#include "appglobal.h"
+#include "sstvparam.h"
+#include "configparams.h"
+#include "dispatchevents.h"
+#include "dispatcher.h"
+#include "modes/modes.h"
+
 #ifndef QT_NO_DEBUG
 #include "scope/scopeview.h"
 #endif
-#include "dsp/filterparam.h"
-#include "configparams.h"
-#include "dispatcher.h"
-#include <QApplication>
-#include <QDebug>
 
-/*!
-  \class syncProcessor Filters the incoming signal using a narrow bandpassfilter centered around 1200 Hz
+#define LINETOLERANCEMODEDETECT 0.015
+#define LINETOLERANCEINSYNC 0.008
+#define SYNCAVGINTEGRATOR 0.09
+#define FILTERDELAYCORRECTION  -8
+#define MINVOLUME 300
 
-  The basspand filter is wide enough to detect the 1100Hz-1300Hz used during retarce, carrying the VisCode.
-  Event generated: verticalRetraceEvent
-  <br> isInSync: test for sync status \sa getSyncPosition()
+//#define DISABLERETRACE
+//#define DISABLEDETECT
+//#define DISABLENARROW
 
+ssenitivity sensitivityArray[2]=
+{
+  // minMatchedLines maxLineDistanceModeDetect maxLineDistanceInSync onVolume offVolume  startToMax;
+  {         6,                2,                       7,              1.7,     0.9 ,      1.5},
+  {         6,                2,                       7 ,             1.7,     0.9 ,      1.5}
+};
 
-*/
 
-const QString squelchStr[NUMSENSITIVITIES]=
+const QString syncStateStr[syncProcessor::SYNCVALID+1]=
 {
-  "Strong",
-  "Medium",
-  "Weak",
-  "DX"
+  "SYNCOFF",
+  "SYNCUP",
+  "SYNCSTART",
+  "SYNCON",
+  "SYNCDOWN",
+  "SYNCEND",
+  "SYNCVALID"
 };
 
-ssenitivity sensitivityArray[NUMSENSITIVITIES]= /**< TODO */
+const QString stateStr[syncProcessor::RETRACEWAIT+1]=
 {
-  {0.70,  0.45, 1000, 7},
-  {0.60,  0.45, 1000, 15},
-  {0.60,  0.45, 100, 20},
-  {0.60,  0.45, 100, 999}
-
+  "Mode detect",
+  "In Sync",
+  "Sync Lost New Mode",
+  "Sync Lost False syncs",
+  "Sync Lost Missing Lines",
+  "Sync Lost",
+  "Retrace Wait"
 };
 
-/**
- * @brief
- *
- * @param parent
- */
-syncProcessor::syncProcessor(QObject *parent) :  QObject(parent)
+
+syncProcessor::syncProcessor(bool narrow, QObject *parent) :  QObject(parent),streamDecode(narrow)
 {
-  syncFilter=NULL;
+  detectNarrow=narrow;
+  currentModePtr=NULL;
+  visMode=NOTVALID;
+  maxLineSamples=getMaxLineSamples();
+  //  syncFound=false;
+  if(!detectNarrow)
+    {
+      connect(streamDecode.getFskDecoderPtr(),SIGNAL(callReceived(QString)),SLOT(slotNewCall(QString)));
+      connect(streamDecode.getVisDecoderPtr(),SIGNAL(visCodeWideDetected(int,uint)),SLOT(slotVisCodeDetected(int,uint)));
+    }
+  else
+    {
+      connect(streamDecode.getVisDecoderPtr(),SIGNAL(visCodeNarrowDetected(int,uint)),SLOT(slotVisCodeDetected(int,uint)));
+    }
+
+}
+
+syncProcessor::~syncProcessor()
+{
+  int i;
+  for(i=0;i<=ENDNARROW;i++)
+    {
+      matchArray[i].clear();
+    }
+  if(currentModePtr!=NULL) delete currentModePtr;
+}
+
+void syncProcessor::reset()
+{
+  sampleCounter=0;
+  init();
+  if(!detectNarrow) streamDecode.reset();
+  //  scopeViewerSyncNarrow->clear();
+  //  scopeViewerSyncWide->clear();
+#ifndef QT_NO_DEBUG
+  scopeViewerSyncNarrow->setCurveName("SYNC VOL",SCDATA1);
+  scopeViewerSyncNarrow->setCurveName("SYNC AVG",SCDATA2);
+  scopeViewerSyncNarrow->setCurveName("SYNC STATE",SCDATA3);
+  scopeViewerSyncNarrow->setCurveName("FREQ",SCDATA4);
+  scopeViewerSyncNarrow->setAxisTitles("Samples","int","State");
+
+  scopeViewerSyncWide->setCurveName("SYNC VOL",SCDATA1);
+  scopeViewerSyncWide->setCurveName("SYNC AVG",SCDATA2);
+  scopeViewerSyncWide->setCurveName("SYNC STATE",SCDATA3);
+  scopeViewerSyncWide->setCurveName("FREQ",SCDATA4);
+  scopeViewerSyncWide->setAxisTitles("Samples","int","State");
+#endif
+
 }
 
 /**
@@ -52,674 +109,1026 @@ syncProcessor::syncProcessor(QObject *parent) :  QObject(parent)
  */
 void syncProcessor::init()
 {
-  freqPtr=syncFilter->filteredDataPtr();
-  syncVolumePtr=syncFilter->volumePtr();
-  rxVolumePtr=rxFilter->volumePtr();
-  sampleCounter=0;
+  enabled=true;
+  if(detectNarrow)
+    {
+      idxStart=STARTNARROW;
+      idxEnd=ENDNARROW;
+    }
+  else
+    {
+      idxStart=STARTWIDE;
+      idxEnd=ENDWIDE;
+    }
+
+  if(sstvModeIndexRx!=0)
+    {
+      if((sstvModeIndexRx>=idxStart) && (sstvModeIndexRx<=idxEnd))
+        {
+          idxEnd=idxStart=(esstvMode)(sstvModeIndexRx-1);
+        }
+      else
+        {
+          enabled=false;
+        }
+    }
+  else if(visMode!=NOTVALID)
+    {
+      if((visMode>=idxStart) && (visMode<=idxEnd))
+        idxEnd=idxStart=visMode;
+    }
+  visMode=NOTVALID; // and reset the visMode
+  syncProcesState=MODEDETECT;
+  modifiedClock=rxClock/SUBSAMPLINGFACTOR;
   syncArrayIndex=0;
-  shadowSyncArrayIndex=0;
+  syncArray[0].init();
+  retraceFlag=false;
   syncState=SYNCOFF;
-  syncFound=false;
-  slantAdjustLine=6;
-  signalQuality=0;
-  modifiedClock=rxClock/SUBSAMPLINGRATIO;
-  newClock=false;
-  idxStart=M1;
-  idxEnd=FAX480;
-  volumeOffCounter=0;
-  syncDeviation=SYNCDEVIATION;
-  retraceDetected=false;
-  if(sstvModeIndex!=0)
-    {
-      idxEnd=idxStart=(esstvMode)(sstvModeIndex-1);
-    }
-#ifndef QT_NO_DEBUG
-  scopeViewerSync->setCurveName("SYNC VOL",SCDATA1);
-  scopeViewerSync->setCurveName("Sync State",SCDATA2);
-  scopeViewerSync->setCurveName("RX VOL",SCDATA3);
-  scopeViewerSync->setCurveName("SYNC Freq",SCDATA4);
-  scopeViewerSync->setAxisTitles("Samples","int","State");
-#endif
   displaySyncEvent* ce;
-  ce = new displaySyncEvent(0,0);
+  ce = new displaySyncEvent(0); // reset sync vuMeter
   QApplication::postEvent(dispatcherPtr, ce);
-
+  addToLog("init called",LOGSYNCSTATE);
+  clearMatchArray();
+  currentMode=NOTVALID;
+  lineTolerance=LINETOLERANCEMODEDETECT;
+  minMatchedLines=sensitivityArray[squelch].minMatchedLines;
 }
 
-#ifndef QT_NO_DEBUG
-void syncProcessor::setOffset(unsigned int dataScopeOffset)
-{
-  xOffset=dataScopeOffset;
-  scopeViewerSync->setOffset(xOffset);
-}
-#endif
 
-/**
- * @brief
- *
- */
+//void syncProcessor::reset()
+//{
+//  sampleCounter=0;
+//  init();
+//}
+
+
 void syncProcessor::process()
 {
-  if(!syncFound) syncQuality=0;
+  //  if(!syncFound) syncQuality=0;
 
-//  addToLog(QString("sync samplecounter:%1").arg(sampleCounter),LOGSYNC1);
+#ifdef DISABLENARROW
+  if(!detectNarrow)
+    {
+#endif
+      streamDecode.process(freqPtr,sampleCounter);
+      if(enabled)
+        {
+          extractSync();
+        }
+#ifdef DISABLENARROW
+    }
+#endif
 
-  extractSync();
-  #ifndef QT_NO_DEBUG
-  scopeViewerSync->addData(SCDATA1,syncVolumePtr,sampleCounter,RXSTRIPE);
-  scopeViewerSync->addData(SCDATA2,syncStateBuffer,sampleCounter,RXSTRIPE);
-  scopeViewerSync->addData(SCDATA3,rxVolumePtr,sampleCounter,RXSTRIPE);
-  scopeViewerSync->addData(SCDATA4,freqPtr,sampleCounter,RXSTRIPE);
+#ifndef QT_NO_DEBUG
+  if(detectNarrow)
+    {
+      scopeViewerSyncNarrow->addData(SCDATA1,syncVolumePtr,sampleCounter,RXSTRIPE);
+      scopeViewerSyncNarrow->addData(SCDATA2,inputVolumePtr,sampleCounter,RXSTRIPE);
+      scopeViewerSyncNarrow->addData(SCDATA3,syncStateBuffer,sampleCounter,RXSTRIPE);
+      scopeViewerSyncNarrow->addData(SCDATA4,freqPtr,sampleCounter,RXSTRIPE);
+    }
+  else
+    {
+      scopeViewerSyncWide->addData(SCDATA1,syncVolumePtr,sampleCounter,RXSTRIPE);
+      scopeViewerSyncWide->addData(SCDATA2,inputVolumePtr,sampleCounter,RXSTRIPE);
+      scopeViewerSyncWide->addData(SCDATA3,syncStateBuffer,sampleCounter,RXSTRIPE);
+      scopeViewerSyncWide->addData(SCDATA4,freqPtr,sampleCounter,RXSTRIPE);
+    }
 #endif
-  sampleCounter+=RXSTRIPE;
 }
 
-/**
- * @brief
- *
- */
+
+
 void syncProcessor::extractSync()
 {
   int i;
-  int syncDurationCount=0;
-
-  DSPFLOAT syncAvgFreq=0;
-
+  int lastSync;
   for(i=0;i<RXSTRIPE;i++)
     {
-      sampleCounterIndexed=sampleCounter+i;
-      if(rxVolumePtr[i]<sensitivityArray[squelch].minVolume)
+      if(inputVolumePtr[i]<MINVOLUME)
         {
-//          addToLog(QString("volume off %1").arg(rxVolumePtr[i]),LOGSYNC1);
-          syncState=SYNCOFF;
-          volumeOffCounter++;
+          switchSyncState(SYNCOFF,sampleCounter+i);
+#ifndef QT_NO_DEBUG
+          syncStateBuffer[i]=(unsigned char)syncState*STATESCALER;
+#endif
+          continue;
         }
-      else
+      switch(syncState)
         {
-          if(volumeOffCounter>0) volumeOffCounter--;
-          if(syncState==SYNCOFF)
+        case SYNCVALID:
+        case SYNCOFF:
+          if(syncVolumePtr[i]>(inputVolumePtr[i]/sensitivityArray[squelch].onVolume))
+            {
+              trackMax=syncVolumePtr[i];
+              holdOffCount=0;
+              holdOffTimeout=20;
+              syncArray[syncArrayIndex].start=sampleCounter+i;
+              syncArray[syncArrayIndex].startVolume=syncVolumePtr[i];
+              switchSyncState(SYNCUP,sampleCounter+i);
+            }
+          break;
+        case SYNCUP:
+          if(holdOffTimeout-- ==0)
+            {
+              switchSyncState(SYNCOFF,sampleCounter+i);
+            }
+          if(trackMax<syncVolumePtr[i])
             {
-              if(syncVolumePtr[i]>(sensitivityArray[squelch].switchOn*rxVolumePtr[i]))
+              trackMax=syncVolumePtr[i];
+              syncArray[syncArrayIndex].maxVolume=trackMax;
+              if(++holdOffCount>4)
                 {
-//                   addToLog(QString("volume switch on %1").arg(rxVolumePtr[i]),LOGSYNC1);
-                  syncState=SYNCON;
-                  visCode=0;
-                  visCounter=0;
-                  visAvg=0.;
-                  syncDurationCount=0;
-                  syncAvgFreq=1200;
-                  syncArray[syncArrayIndex].start=sampleCounter+i;
+                  holdOffCount=0;
+                  switchSyncState(SYNCSTART,sampleCounter+i);
                 }
+            }
+          break;
+        case SYNCSTART:
+          //track Maximum
+          if(trackMax<syncVolumePtr[i])
+            {
+              trackMax=syncVolumePtr[i];
+              holdOffCount=0;
+              syncArray[syncArrayIndex].maxVolume=trackMax;
 
             }
           else
             {
-              if(syncVolumePtr[i]<(sensitivityArray[squelch].switchOff*rxVolumePtr[i]))
+              if(holdOffCount++==10)
                 {
-//                  addToLog(QString("volume switch off %1").arg(rxVolumePtr[i]),LOGSYNC1);
-                  syncState=SYNCOFF;
-                  syncArray[syncArrayIndex].end=sampleCounter+i;
-                  syncArray[syncArrayIndex].width=syncArray[syncArrayIndex].end-syncArray[syncArrayIndex].start;
-                  syncArray[syncArrayIndex].freq=syncAvgFreq;
-
-                  if(syncArray[syncArrayIndex].width>(MINSYNCWIDTH*SAMPLERATE))
-                    {
-                      if(syncArray[syncArrayIndex].width>(RETRACEWIDTH*SAMPLERATE))
-                        {
-                          syncArray[syncArrayIndex].retrace=true;
-                          modeDetect(true);
-                         }
-                      else
-                        {
-                          visCode=0;
-                          syncArray[syncArrayIndex].retrace=false;
-                          modeDetect(false);
-
-                        }
-
-                      incrementSyncArray();
-                    }
+                  switchSyncState(SYNCON,sampleCounter+i);
                 }
-              else // we are still detecting a sync
+            }
+          break;
+        case SYNCON:
+          if(trackMax<syncVolumePtr[i]) //keep tracking maximum
+            {
+              trackMax=syncVolumePtr[i];
+              syncArray[syncArrayIndex].maxVolume=trackMax;
+            }
+          if(syncVolumePtr[i]<syncArray[syncArrayIndex].startVolume*sensitivityArray[squelch].offVolume)
+            {
+              syncArray[syncArrayIndex].end=sampleCounter+i;
+              holdOffCount=20;
+              switchSyncState(SYNCDOWN,sampleCounter+i);
+            }
+          break;
+
+        case SYNCDOWN:
+          if(syncVolumePtr[i]<syncArray[syncArrayIndex].startVolume*sensitivityArray[squelch].offVolume)
+            {
+              if(--holdOffCount==0)
                 {
-                  visCounter++;
-                  syncDurationCount++;
-                  if((syncDurationCount>10) && (syncDurationCount<50))
-                    {
-                      syncAvgFreq=syncAvgFreq+0.1*(freqPtr[i]-syncAvgFreq);
-                    }
-                  if(visCounter>100)
-                    {
-                      visAvg+=freqPtr[i];
-                    }
-                  if(visCounter==200)
-                    {
-                      visAvg/=100.;
-                      visCode=visCode>>1;
-                      if(visAvg<=1200.) visCode=visCode | 0X100;
-                      addToLog(QString("visfreq %1, counter %2, code=%3").arg(visAvg).arg(visCounter).arg(visCode),LOGSYNC2);
-                     }
-                  if(visCounter > (unsigned int)(0.030*SAMPLERATE)) //reset visCounter per bit
-                    {
-                      visCounter=0;
-                      visAvg=0.;
-                    }
+                  switchSyncState(SYNCEND,sampleCounter+i);
                 }
             }
+          else
+            {
+              switchSyncState(SYNCON,sampleCounter+i);
+            }
+          break;
+
+        case SYNCEND:
+
+          if(validateSync())
+            {
+              switchSyncState(SYNCVALID,sampleCounter+i);
+            }
+          else
+            {
+              switchSyncState(SYNCOFF,sampleCounter+i);
+            }
+          break;
         }
-      syncStateBuffer[i]=(unsigned int)syncState*STATEMULTIPLIER;
+#ifndef QT_NO_DEBUG
+      syncStateBuffer[i]=(unsigned char)syncState*STATESCALER;
+#endif
     }
-  if(syncFound)
+
+  if(syncProcesState==INSYNC)
     {
-      if(volumeOffCounter>(samplesPerLine*sensitivityArray[squelch].syncLost))
+      lastSync=syncArray[activeChainPtr->last()->to].end;
+      if((sampleCounter+RXSTRIPE-RXSTRIPE/7)>(lastSync+10*samplesPerLine))
         {
-          restart();
+          tempOutOfSync=true;
+        }
+      missingLines=(uint) round(((sampleCounter+RXSTRIPE-RXSTRIPE/7)-(lastSync+samplesPerLine))/samplesPerLine+1);
+      calcSyncQuality();
+    }
+  else if(visMode!=NOTVALID)
+    {
+      if(sampleCounter>visTimeout)
+        {
+          visMode=NOTVALID;
+          init();
         }
     }
-}
 
+}
 
+void syncProcessor::slotNewCall(QString call)
+{
+  emit callReceived(call);
+  retraceFlag=true;
+}
 
-/**
- * @brief
- *
- */
-void syncProcessor::modeDetect(bool atRetrace)
+void syncProcessor::slotVisCodeDetected(int mode,uint visSampleCounter)
 {
-//  bool done;
-  shadowSyncArray[shadowSyncArrayIndex]=syncArray[syncArrayIndex];
-  dumpSyncArray(false,syncArrayIndex);
-  if(!atRetrace) modeDetectByLine();
+  if((mode>=idxStart) && (mode<=idxEnd))
+    {
+      visMode=(esstvMode)mode;
+      idxStart=idxEnd=(esstvMode)mode;
+      minMatchedLines=3;
+      visTimeout=visSampleCounter+4*getLineLength(visMode,modifiedClock);
+    }
   else
     {
-      if(syncFound==true)
-        {
-          //  we have a retrace during image capturing
-//          verticalRetraceEvent* ce;
-//          ce = new 	verticalRetraceEvent();
-//          ce->waitFor(&done);
-//          QApplication::postEvent(dispatcherPtr, ce);
-//          addToLog("Vertical retrace while imagecapturing",LOGSYNC1);
-          retraceDetected=true;
-          return;
-        }
-      moveToTop(syncArrayIndex);
-      if((mode=lookupVIS(visCode))!=NOTVALID)
-        {
-          syncFound=true;
-          syncQuality=4;
-          syncPosition=syncArray[0].end; /// this always indicates a valid retrace
-          syncArrayIndex=0;
-          addToLog(QString("modeDetect: after retrace syncpos:=%1").arg(syncPosition),LOGSYNC1);
-          samplesPerLine=lineLength(mode,modifiedClock);
-          syncWd=syncWidth(mode,modifiedClock);
-          addToLog(QString("syncProcessor:modeDetect Viscode used: %1,mode=%2").arg(QString::number(visCode,16)).arg(mode),LOGSYNC1);
-//          logfile->addToAux(QString("Index\tStart\tEnd\tClosestLine\tRetrace\t%1").arg(samplesPerLine));
-          return;
-        }
-      else if(visCode!=0)
-        {
-          syncFound=false;
-          addToLog(QString("syncProcessor:modeDetect Viscode rejected: %1").arg(QString::number(visCode,16)),LOGSYNC1);
-        }
+      visMode=NOTVALID;
     }
 }
 
-
-/**
- * @brief use sync interval to detect mode
- *
- * The syncArrayIndex is pointing to the last valid entry in the array (i.e. it is post incremented)
- * We need a minimal number of syncs to determine the mode.
- *
- */
-
-void syncProcessor::modeDetectByLine()
+bool syncProcessor::validateSync()
 {
-  int i;
-  esstvMode selectedMode;
-  unsigned int highest=0;
-  selectedMode=NOTVALID;
-  if(syncArrayIndex<3) return; // we need enough sync entries
-  for(i=idxStart;i<idxEnd;i++)
-   {
-     modeArray[i].clear();
-     getMatchingSyncPulse((esstvMode) i);
-     if((modeArray[i].match>highest) && (modeArray[i].match>=3))
-       {
-         if(modeArray[i].consecutiveSyncs<3) continue;
-         highest=modeArray[i].match;
-         selectedMode=(esstvMode)i;
-       }
-   }
-  if(syncFound==true)
-    {
-      trackSyncs(selectedMode);
-      return;
+  bool result;
+  //  if(syncArray[syncArrayIndex].endVolume<500)
+  //    {
+  //      result=false;
+  //    }
+  if(syncArray[syncArrayIndex].maxVolume<syncArray[syncArrayIndex].startVolume*sensitivityArray[squelch].startToMax)
+    {
+      result=false;
     }
-  if(selectedMode==NOTVALID) return;
-  if(modeArray[selectedMode].consecutiveSyncs<3) return;
-  // we have a good match
+#ifndef DISABLERETRACE
+  else if(syncArray[syncArrayIndex].diffStartEnd()>=MINRETRACEWIDTH)
+    {
+      syncArray[syncArrayIndex].retrace=true;
+      result=true;
+    }
+  else if(syncArray[syncArrayIndex].diffStartEnd()>=MINRETRACEWIDTH/4)
+    {
+      if((syncArrayIndex>2)
+         && (syncArray[syncArrayIndex].end-syncArray[syncArrayIndex-1].start)>=MINRETRACEWIDTH
+         && (syncArray[syncArrayIndex].start-syncArray[syncArrayIndex-1].end)<=MINRETRACEWIDTH/5)
+        {
+          syncArray[syncArrayIndex-1].end=syncArray[syncArrayIndex].end;
+          syncArray[syncArrayIndex-1].retrace=true;
+          syncArray[syncArrayIndex-1].diffStartEnd(); // just calculate the width;
+          syncArrayIndex--;
+        }
+      result=true;
+    }
+#endif
+  else if((syncArray[syncArrayIndex].diffStartEnd()>=0.004*SAMPLERATE) && (syncArray[syncArrayIndex].diffStartEnd()<=0.025*SAMPLERATE))
+    {
+      syncArray[syncArrayIndex].retrace=false;
+      //      addToLog(QString("index %1, mid:=%2").arg(syncArrayIndex).arg(syncArray[syncArrayIndex].mid),LOGSYNCACCEPTED);
+      result=true;
+    }
+  else
+    {
+      addToLog(QString("Sync rejected:%1 end:%2 width %3").arg(syncArray[syncArrayIndex].start)
+               .arg(syncArray[syncArrayIndex].end).arg(syncArray[syncArrayIndex].diffStartEnd()),LOGSYNCREJECTED);
+      result=false;
+    }
+  if(result)
+    {
+      checkSyncArray();
+      switch(syncProcesState)
+        {
+        case MODEDETECT:
+          if(findMatch())
+            {
+              visMode=NOTVALID; //reset visMode;
+#ifndef DISABLEDETECT
+              //we have a new mode
+              if(!createModeBase())
+                {
+                  addToLog("Error creating modeBase",LOGALL);
+                  result=false;
+                }
+              else
+                {
+                  falseSyncs=0;
+                  lineTolerance=LINETOLERANCEINSYNC;
+                  // when we have S1,S2 or SDX then we have to set the syncposition at the beginning of the green line
+                  //          syncPosition=currentModePtr->adjustSyncPosition(syncArray[0].end)- FILTERDELAYCORRECTION; // type 1 sync end
+                  unsigned int syncCorrected;;
+                  syncWidth=getSyncWidth(currentMode ,modifiedClock);
+                  if(syncArray[0].retrace)
+                    {
+                      syncCorrected=syncArray[0].end;
+                    }
+                  else
+                    {
+                      syncCorrected=(syncArray[0].start+syncArray[0].end)/2+syncWidth/2;
+                    }
 
-  //dumpSyncArray();
-  mode=selectedMode;
-  samplesPerLine=lineLength(mode,modifiedClock);
-  syncWd=syncWidth(mode,modifiedClock);
-  //find first occurence
-  moveToTop(modeArray[(int)selectedMode].firstSyncIndex);
-  syncPosition=syncArray[0].end;
-//  logfile->addToAux(QString("Index\tStart\tEnd\tClosestLine\tRetrace\t%1").arg(samplesPerLine));
-  cleanupSyncArray(selectedMode);
+                  syncPosition=currentModePtr->adjustSyncPosition(syncCorrected,syncArray[0].retrace)+FILTERDELAYCORRECTION; // type 2 sync end
+                  tempOutOfSync=false;
+                  slantAdjustLine=6;
+                  slantAdjust(true);
+                  switchProcessState(INSYNC);
+
+                }
+#endif
+            }
+          break;
+        case INSYNC:
+          trackSyncs();
+          break;
+        case SYNCLOSTNEWMODE:
+        case SYNCLOSTFALSESYNC:
+        case SYNCLOSTMISSINGLINES:
+        case SYNCLOST:
+          addToLog("synclost detected",LOGSYNCSTATE);
+          break;
+        case RETRACEWAIT:
+          break;
 
-  syncFound=true; // must be after cleaunupSyncArray
-  syncQuality=4;;
-  addToLog(QString("syncFound at: %1 mode=%2").arg(syncPosition).arg(selectedMode),LOGSYNC1);
+        }
+      syncArrayIndex++;
+      syncArray[syncArrayIndex].init();
+    }
+  return result;
 }
 
 
-void syncProcessor::getMatchingSyncPulse(esstvMode idx)
+void  syncProcessor::trackSyncs()
 {
-  int i;
-  bool adjecent=true;
-  DSPFLOAT ratio,length,syncW;
-  unsigned int offset;
-  unsigned int pos;
-  int start,result;
-  ssyncArray *ptr;
-  int syncIndex;
-  if(syncFound)
-    {
-      ptr=shadowSyncArray;
-      syncIndex=shadowSyncArrayIndex;
+  //  calcSyncQuality();
+  if(addToChain(currentMode,activeChainPtr->last()->to))
+    {
+      falseSyncs=0;
+      missingLines=0;
+      if(tempOutOfSync)
+        {
+          // check if we can resynchronize
+          if(activeChainPtr->last()->lineSpacing<=2)
+            {
+              tempOutOfSync=false;
+            }
+        }
     }
   else
     {
-      ptr=syncArray;
-      syncIndex=syncArrayIndex;
+      falseSyncs++;
     }
-  length=lineLength(idx,modifiedClock);
-  syncW=syncWidth(idx,modifiedClock);
-  offset=ptr[syncIndex].end- (int)rint(syncW/2);
-  start=syncIndex-1;
-  if(offset<=length) return;
-  pos=offset-length;
-  modeArray[idx].clear();
-  ratio=1000;
-  for(i=0;i<=syncIndex;i++)
+  if(retraceFlag)
     {
-      ptr[i].inUse=false;
+      switchProcessState(RETRACEWAIT);
+      return;
     }
-  while(1)
+  if(currentModeMatchChanged)
     {
-      if((result=matchingSync(start,pos,syncW,syncFound))>=0)
+      currentModeMatchChanged=false;
+      calculateLineNumber(activeChainPtr->last()->from,activeChainPtr->last()->to);
+      lastSyncTest=activeChainPtr->last()->endTo;
+      slantAdjust(false);
+      if(falseSlantSync>=10)
         {
-          pos=ptr[result].end-(int)rint(syncW/2);
-          start=result-1;
-          if(ptr[result].spurious<2)
-            {
-              modeArray[idx].match++;
-              modeArray[idx].firstSyncIndex=result;
-              ptr[result].inUse=1;
-              if(adjecent==true) modeArray[idx].consecutiveSyncs++;
-            }
-         }
-      else
+          switchProcessState(SYNCLOSTFALSESYNC);
+        }
+    }
+}
+
+void  syncProcessor::calcSyncQuality()
+{
+  int k;
+  quint16 fs=0;
+  syncQuality=10-(missingLines*5/25);
+  //calc false syncs in the last 10
+  if(activeChainPtr->count()>=10)
+    {
+      for(k=activeChainPtr->count()-10;k<activeChainPtr->count()-1;k++)
         {
-          adjecent=false;
+          fs+=activeChainPtr->at(k)->to-activeChainPtr->at(k)->from-1;
         }
-      modeArray[idx].lineNumber++;
-      if(pos<length) break;
-      if(pos<ptr[0].start)break;
-      pos-=length;
     }
 
-  if( modeArray[idx].consecutiveSyncs>=3)
+  syncQuality-=((falseSyncs*5)/30);
+  syncQuality-=(falseSlantSync*2);
+  if(syncQuality<0) syncQuality=0;
+  if((syncQuality<=0) && (squelch!=1))
     {
-      ratio=((double)(ptr[syncIndex].end-ptr[modeArray[idx].firstSyncIndex].end))/(length*(double) modeArray[idx].match);
-      ratio*=(double) modeArray[idx].match/(double) modeArray[idx].consecutiveSyncs;
+      switchProcessState(SYNCLOST);
     }
-  modeArray[idx].ratio=ratio;
+
 }
 
 
+void  syncProcessor::calculateLineNumber(uint fromIdx,uint toIdx)
+{
+  quint16 lnbr;
+  double fract;
+  lineCompare(samplesPerLine,0,toIdx,lnbr,fract);
+  syncArray[toIdx].length=syncArray[toIdx].end-syncArray[fromIdx].end;
+  syncArray[toIdx].lineNumber=lnbr;
+  lastUpdatedSync=toIdx;
+}
 
-/**
- * @brief check if we find a syncpulse at position pos
- *
- * @param start index of last position in syncArray
- * @param pos  samplecounter value of the sync
- * @param syncWidth
- * @return int  index of syncArray where we found the sync at position pos, -1 if not found
- */
-int syncProcessor::matchingSync(int start, unsigned int pos, DSPFLOAT syncWidth, bool shadow)
+void syncProcessor::checkSyncArray()
 {
-  int i;
-  int spurious=0;
-  DSPFLOAT sw;
-  ssyncArray *ptr;
-  if(shadow) ptr=shadowSyncArray;
-  else ptr=syncArray;
-  for(i=start;i>=0;i--)
+
+  if(syncArray[syncArrayIndex].retrace)
     {
-      if(i>=SYNCARRAYLENGTH)
+      syncArray[0]=syncArray[syncArrayIndex];
+      syncArrayIndex=0;
+      //      syncPosition=syncArray[0].end + FILTERDELAYCORRECTION;
+      addToLog(QString("Found retrace: start:%1 end:%2  width %3").arg(syncArray[0].start).arg(syncArray[0].end).arg(syncArray[0].end-syncArray[0].start),LOGSYNCACCEPTED);
+      if(syncProcesState==INSYNC)
         {
-//          qDebug() << "index error";
+          retraceFlag=true;
+          syncProcesState=RETRACEWAIT;
         }
-      sw=(DSPFLOAT)(ptr[i].end-ptr[i].start);
-      if(ptr[i].retrace==true)
-        {
-          if((pos>ptr[i].end-MAXSYNCWIDTH*modifiedClock) && (pos<ptr[i].end)) return i;
-        }
-      else if((syncWidth>(1.2*sw))||(syncWidth<(0.8*sw)))
+    }
+
+  if(syncArrayIndex>=(MAXSYNCENTRIES-1))
+    {
+      //shift syncArray
+      dropTop();
+    }
+  addToLog(QString("Found sync: start:%1 end:%2 width %3 at %4").arg(syncArray[syncArrayIndex].start).arg(syncArray[syncArrayIndex].end).arg(syncArray[syncArrayIndex].end-syncArray[syncArrayIndex].start).arg(syncArrayIndex),LOGSYNCACCEPTED);
+}
+
+
+
+bool syncProcessor::findMatch()
+{
+  int i,j,k,m;
+  int fs;
+  uint minTotLines=9999;
+  double minFract=1;
+  int idx=-1;
+  QList<modeMatchList *> changeList;
+  QList <int> modeList;
+  QList<uint> totalLinesList;
+  QList<double> totalFractList;
+  addToLog (QString(" checking match for syncArrayIndex %1 at %2").arg(syncArrayIndex).arg(syncArray[syncArrayIndex].end),LOGSYNCMATCH);
+  for(i=idxStart;i<=idxEnd;i++)
+    {
+      syncWidth=getSyncWidth((esstvMode)i ,modifiedClock);
+      if(addToMatch((esstvMode)i))
         {
-          continue;
+          for(j=0;j<matchArray[i].count();j++)
+            {
+              if(matchArray[i][j]->count()>=(int)minMatchedLines)
+                {
+                  changeList.append(matchArray[i][j]);
+                  modeList.append(i);
+                }
+
+            }
         }
-      else if((pos>ptr[i].start) && (pos<ptr[i].end))
+    }
+  for (m=0;m<changeList.count();m++)
+    {
+      totalLinesList.append(calcTotalLines( changeList.at(m)));
+      totalFractList.append(calcTotalFract( changeList.at(m)));
+    }
+  for (m=0;m<changeList.count();m++)
+    {
+      if((minTotLines>=totalLinesList.at(m)) && (totalFractList.at(m)<=minFract))
         {
-          ptr[i].spurious=spurious;
-          return i;
+          idx=m;
+          minTotLines=totalLinesList.at(m);
+          minFract=totalFractList.at(m);
         }
-      if(pos>ptr[i].end) return -1;
-      spurious++;
     }
-  return -1;
-}
 
-/*!
-returns 0 if not in Sync
-returns 1 if in Sync without a retrace
-returns 2 if in Sync and retrace -- the syncPosition is at the end of the retrace
-*/
-int syncProcessor::isInSync()
-{
-  int result=0;
-  if(syncFound)
+  if(idx>=0)
     {
-      result++;
-      if(syncArray[0].retrace==true)
+      currentMode=(esstvMode)modeList.at(idx);
+      activeChainPtr=changeList.at(idx);
+      samplesPerLine=getLineLength(currentMode,modifiedClock);
+      fs=0;
+      for(k=0;k<activeChainPtr->count()-1;k++)
         {
-          result++;
+          fs+=activeChainPtr->at(k)->to-activeChainPtr->at(k)->from-1;
         }
+      if (fs>20)
+        {
+          clearMatchArray();
+          return false;
+        }
+      cleanupMatchArray();
+      return true;
     }
 
-  return result;
+  return false;
 }
 
 
-/**
- * @brief
- *
- */
-void syncProcessor::incrementSyncArray()
+uint syncProcessor::calcTotalLines(modeMatchList *mlPtr)
 {
-  if (syncArrayIndex==(SYNCARRAYLENGTH-1))
+  int i;
+  uint lines=0;
+  for(i=0;i<mlPtr->count();i++)
     {
-      memmove(syncArray,&syncArray[1],sizeof(ssyncArray)*(SYNCARRAYLENGTH-1));
+      lines+=mlPtr->at(i)->lineSpacing;
     }
-  else syncArrayIndex++;
-  //copy syncArray to shadowSyncArray
-  {
-    if (shadowSyncArrayIndex==(SYNCARRAYLENGTH-1))
-      {
-        memmove(shadowSyncArray,&shadowSyncArray[1],sizeof(ssyncArray)*(SYNCARRAYLENGTH-1));
-      }
-    else shadowSyncArrayIndex++;
-  }
+  return lines;
 }
 
-/*!  shift up the syncArray so that syncArray[index] is at the top.
-*/
-void syncProcessor::moveToTop(int index)
+double syncProcessor::calcTotalFract(modeMatchList *mlPtr)
 {
-  if(index==0) return;
-  memmove(syncArray,syncArray+index,sizeof(ssyncArray)*(syncArrayIndex+1-index));
-  syncArrayIndex-=index;
-  shadowSyncArrayIndex=0; // reset shadowIndex
+
+  int i;
+  double fract=0;
+  for(i=0;i<mlPtr->count();i++)
+    {
+      fract+=mlPtr->at(i)->fraction;
+    }
+  return fract;
+
 }
 
 
-void syncProcessor::cleanupSyncArray(esstvMode modeIndex)
+bool syncProcessor::addToMatch(esstvMode mode)
 {
-  unsigned int i,stpos;
-  getMatchingSyncPulse(modeIndex);
-  for(i=0;i<syncArrayIndex;) // keep last one
-  {
-    if(!syncArray[i].inUse)
-    {
-      deleteSyncEntry(i);
-    }
-    else
+  int  i;
+  
+  if(syncArrayIndex<1) return false;
+  for(i=syncArrayIndex-1;i>=0;i--)
     {
-      syncArray[i].lineNumber=(int) round(((double)(syncArray[i].end-syncArray[0].end))/samplesPerLine);
-      i++;
-    }
-   }
-  syncArray[syncArrayIndex].lineNumber=(int) round(((double)(syncArray[syncArrayIndex].end-syncArray[0].end))/samplesPerLine);
-  for(i=1;i<=syncArrayIndex;i++)
-    {
-      if(syncArray[0].retrace) stpos=syncArray[i-1].end-syncWidth(modeIndex,modifiedClock)/2;
-      else stpos=syncArray[i-1].start +(syncArray[i-1].end-syncArray[i-1].start)/2;
-      syncArray[i].length=(syncArray[i].start +(syncArray[i].end-syncArray[i].start)/2)-stpos;
+
+      if(addToChain(mode,i))
+        {
+          return true;
+        }
     }
-  dumpSyncArray(false,0);
+  return false;
 }
 
 
-
-void syncProcessor::deleteSyncEntry(int index)
+bool syncProcessor::addToChain(esstvMode mode,  uint fromIdx)
 {
-  memmove(syncArray+index,syncArray+index+1,sizeof(ssyncArray)*(syncArrayIndex-index));
-  syncArrayIndex--;
-//  if(syncQuality>0) syncQuality--;
-}
+  int i;
+  double fract;
+  quint16 lnbr;
 
-/*!
- The modeDetect tries to find the sstv mode based on the line length. If there are a number (based on the squelch) of consecutive correct lines the syncFound and the mode are set. The syncArray is the searched for the first valid line length and the pointer is set at the end of the  sync pulse.
-*/
+  samplesPerLine=getLineLength(mode,modifiedClock);
+  
+  if(!lineCompare(samplesPerLine,fromIdx,syncArrayIndex,lnbr,fract))
+    {
+      return false;
+    }
 
 
+  if((syncArray[syncArrayIndex].diffStartEnd()<syncWidth*0.75)
+     || (syncArray[syncArrayIndex].diffStartEnd()>syncWidth*2)
+     || (syncArray[fromIdx].diffStartEnd()<syncWidth*0.75))
+    {
 
-void syncProcessor::dumpSyncArray(bool withShadow, int start)
-{
-  int st=start;
-  if(start==0)
+      return false;
+    }
+
+  if (syncArray[fromIdx].diffStartEnd()>syncWidth*2)
     {
-      addToLog(QString("index=%1 start=%2 end=%3 width=%4 linelength=n/a  frequency=%5 volume=%6")
-               .arg(0).arg(syncArray[0].start).arg(syncArray[0].end)
-               .arg(syncArray[0].end-syncArray[0].start).arg(syncArray[0].freq).arg(rxVolumePtr[0]),LOGSYNC2);
-      st=1;
+      if(fromIdx!=0 || !syncArray[0].retrace)
+        {
+          return false;
+        }
     }
 
-  for(uint i=st;i<=syncArrayIndex;i++)
+
+  if(syncProcesState==MODEDETECT)
     {
-      addToLog(QString("index=%1 start=%2 end=%3 width=%4 linelength=%5 frequency=%6 volume=%7")
-               .arg(i).arg(syncArray[i].start).arg(syncArray[i].end)
-               .arg(syncArray[i].end-syncArray[i].start).arg(syncArray[i].end-syncArray[i-1].end)
-               .arg(syncArray[i].freq).arg(rxVolumePtr[0]),LOGSYNC2);
+      if(lnbr>sensitivityArray[squelch].maxLineDistanceModeDetect)
+        {
+          return false;
+        }
     }
-  if(withShadow)
+
+  bool found=false;
+  if(matchArray[mode].count()==0) // we don't have a chain yet
     {
-      if(start==0)
+      matchArray[mode].append(new modeMatchList);
+      matchArray[mode][0]->append(new smatchEntry(fromIdx,syncArrayIndex,lnbr,fract,syncArray[fromIdx].end,syncArray[syncArrayIndex].end));
+      addToLog(QString("Match: mode=%1,new chain=%2 syncIndex=%3 end=%4").arg(getSSTVModeNameShort(mode)).arg(matchArray[mode].count()-1).arg(syncArrayIndex).arg(syncArray[syncArrayIndex].end),LOGSYNCMATCH);
+    }
+  else
+    {
+      // can we append this to an existing chain?
+      for(i=0;i<matchArray[mode].count();i++)
         {
-          addToLog(QString("syncProcessor: shadowSyncArrayDump index=%1 start=%2 end=%3 width=%4 linelength=n/a  frequency=%5 volume=%6")
-                   .arg(0).arg(shadowSyncArray[0].start).arg(shadowSyncArray[0].end)
-                   .arg(shadowSyncArray[0].end-shadowSyncArray[0].start).arg(shadowSyncArray[0].freq).arg(rxVolumePtr[0]),LOGSYNC2);
-                st=1;
+          if(matchArray[mode][i]->last()->to==fromIdx)
+            {
+              if((syncProcesState==INSYNC) && (i==0) )
+                {
+                  currentModeMatchChanged=true;
+                }
+              matchArray[mode][i]->append(new smatchEntry(fromIdx,syncArrayIndex,lnbr,fract,syncArray[fromIdx].end,syncArray[syncArrayIndex].end));
+              addToLog(QString("Match: mode=%1,chain=%2 syncIndex=%3 end=%4").arg(getSSTVModeNameShort(mode)).arg(i).arg(syncArrayIndex).arg(syncArray[syncArrayIndex].end),LOGSYNCMATCH);
+              found=true;
+              break;
+            }
         }
-      for(uint i=st;i<=shadowSyncArrayIndex;i++)
+      if(!found)
         {
-          addToLog(QString("syncProcessor: shadowSyncArrayDump index=%1 start=%2 end=%3 width=%4 linelength=%5 frequency=%6 volume=%7")
-                   .arg(i).arg(shadowSyncArray[i].start).arg(shadowSyncArray[i].end)
-                   .arg(shadowSyncArray[i].end-shadowSyncArray[i].start).arg(shadowSyncArray[i].end-shadowSyncArray[i-1].end)
-                   .arg(shadowSyncArray[i].freq).arg(rxVolumePtr[0]),LOGSYNC2);
+          matchArray[mode].append(new modeMatchList);
+          matchArray[mode].last()->append(new smatchEntry(fromIdx,syncArrayIndex,lnbr,fract,syncArray[fromIdx].end,syncArray[syncArrayIndex].end));
+          addToLog(QString("Match: mode=%1,new chain=%2 syncIndex=%3 end=%4").arg(getSSTVModeNameShort(mode)).arg(matchArray[mode].count()-1).arg(syncArrayIndex).arg(syncArray[syncArrayIndex].end),LOGSYNCMATCH);
         }
+      
     }
+  return true;
 }
 
-int syncProcessor::getSignalQuality()
+
+void syncProcessor::clearMatchArray()
 {
-  if(!syncFound)
+  int i,j;
+  for(i=idxStart;i<=idxEnd;i++)
     {
-      syncQuality=0;
-      lostLines=0;
-      return 0;
+      for(j=0;j<matchArray[i].count();j++)
+        {
+          removeMatchArrayChain((esstvMode)i,0);
+        }
+      matchArray[i].clear();
     }
-  if(syncArrayIndex<7)
+  activeChainPtr=NULL;
+  switchProcessState(MODEDETECT);
+}
+
+void syncProcessor::removeMatchArrayChain(esstvMode mode,int chainIdx)
+{
+  int i;
+  for(i=0;i<matchArray[mode][chainIdx]->count();i++)
     {
-      syncQuality=4;
+      delete matchArray[mode][chainIdx]->at(i);
     }
-//  qDebug() << "diff" << sampleCounterIndexed-syncArray[syncArrayIndex-1].end << "index" << syncArrayIndex-1;
-//  qDebug() << "samplesPerLine" << samplesPerLine << "lost" <<sensitivityArray[squelch].syncLost;
-  if((sampleCounterIndexed-syncArray[syncArrayIndex-1].end)>(samplesPerLine*sensitivityArray[squelch].syncLost))
+  matchArray[mode][chainIdx]->clear();
+  delete matchArray[mode][chainIdx];
+  matchArray[mode].takeAt(chainIdx);
+}
+
+void syncProcessor::cleanupMatchArray()
+{
+  int i,j;
+  //  double fract=0;
+  //  quint16 lnbr=0;
+  for(i=idxStart;i<=idxEnd;i++)
     {
-      syncQuality=0;
+      for(j=0;j<matchArray[i].count();)
+        {
+          if(activeChainPtr!=matchArray[i][j])
+            {
+              removeMatchArrayChain((esstvMode)i,j);
+            }
+          else
+            {
+              j++;
+            }
+        }
     }
 
-  if(lostLines!=0)
+  //  if(syncArray[0].retrace)
+  //    {
+  //      if((currentMode==S1) || (currentMode==S2))
+  //        {
+  //          //check if this is a valid retrace
+  //          // prepend active chainPtr with the retrace position
+  //          activeChainPtr->prepend(new smatchEntry(0,activeChainPtr->at(0)->from ,lnbr,fract,syncArray[0].end,syncArray[activeChainPtr->at(0)->to].end));
+  //        }
+  //    }
+
+
+
+
+
+  for(i=0;i<activeChainPtr->count();i++)
     {
-      if(lostLines>sensitivityArray[squelch].syncLost/3) syncQuality--;
-      if(lostLines>sensitivityArray[squelch].syncLost/2) syncQuality--;
-      if(syncQuality<0) syncQuality=0;
-      addToLog(QString("lostLines %1, sq:=%2").arg(lostLines).arg(syncQuality),LOGSYNC1);
-      lostLines=0;
+      syncArray[activeChainPtr->at(i)->from].inUse=true;
+      syncArray[activeChainPtr->at(i)->to].inUse=true;
     }
-  else
+  for(i=0;i<syncArrayIndex;)
     {
-      addToLog(QString("sq:=%2").arg(syncQuality),LOGSYNC1);
-      if(syncQuality<10) syncQuality++;
+      if(!syncArray[i].inUse)
+        {
+          deleteSyncArrayEntry(i);
+        }
+      else
+        {
+          i++;
+        }
+    }
+  for(i=0;i<syncArrayIndex;i++)
+    {
+      calculateLineNumber(i,i+1);
     }
-  return syncQuality;
 }
 
-
-void syncProcessor::trackSyncs(esstvMode selectedMode)
+void syncProcessor::dropTop()
 {
-  double temp;
-  double tempr;
+  deleteSyncArrayEntry(0);
+}
 
-  if((selectedMode!=mode)&&(selectedMode!=NOTVALID))
+void syncProcessor::deleteSyncArrayEntry(uint entry)
+{
+  int i,j,k;
+  modeMatchList *ml;
+  //  smatchEntry *tempPtr;
+  if(entry>=syncArrayIndex) return;
+  // delete or adapt the matchArrays
+  for(i=idxStart;i<=idxEnd;i++)   //all modes
     {
-//      qDebug() << "new mode detected";
-   //   dumpSyncArray();
+      for(j=0;j<matchArray[i].count();) //all chains
+        {
+          for(k=0;k<matchArray[i][j]->count();)
+            {
+              ml=matchArray[i][j];
+              if (ml->at(k)->from==entry)
+                {
+                  delete matchArray[i][j]->takeAt(k);
+                }
+              else
+                {
+                  if(ml->at(k)->from>entry)
+                    {
+                      ml->at(k)->from--;
+                    }
+                  if(ml->at(k)->to>entry)
+                    {
+                      ml->at(k)->to--;
+                    }
+                  k++;
+                }
+            }
+          if(matchArray[i][j]->count()==0)
+            {
+              delete matchArray[i].takeAt(j);
+            }
+          else
+            {
+              j++;
+            }
+        }
     }
-  temp=(double)(syncArray[syncArrayIndex].end-syncArray[syncArrayIndex-1].end);
-  tempr =round(temp/samplesPerLine)*samplesPerLine+0.00000001; // make it non-zero to avoid divide by zero
-  temp=temp/tempr;
-  if(fabs(1-temp)>SYNCDEVIATION)
+  for(i=entry;i<(int)syncArrayIndex;i++)
     {
-//      addToLog(QString("delete sync entry %1").arg(syncArrayIndex),LOGSYNC1);
-      deleteSyncEntry(syncArrayIndex);
-      return;
+      syncArray[i]=syncArray[i+1];
     }
-  ssyncArray *ptr=&syncArray[syncArrayIndex];
-  addToLog(QString("SyncArrayIndex %1").arg(syncArrayIndex),LOGSYNC1);
+  syncArrayIndex--;
+}
+
+
+
+void syncProcessor::recalculateMatchArray()
+{
+}
 
-  if(syncArrayIndex>0)
+bool syncProcessor::lineCompare(DSPFLOAT samPerLine, int srcIdx, int dstIdx, quint16 &lineNumber, double &fraction)
+{
+  double delta;
+  double intPart;
+  delta=(double)(syncArray[dstIdx].end-syncArray[srcIdx].end);
+  fraction=modf(delta/samPerLine,&intPart);
+  if(fraction>=0.5)
     {
-      ptr->length=ptr->end-syncArray[syncArrayIndex-1].end;
+      fraction=(1-fraction);
+      intPart+=1.;
     }
-  else  ptr->length=0;
-  syncArray[syncArrayIndex].lineNumber=(int) round(((double)(syncArray[syncArrayIndex].end-syncArray[0].end))/samplesPerLine);
-  lostLines=syncArray[syncArrayIndex].lineNumber-syncArray[syncArrayIndex-1].lineNumber-1;
-  if(getSignalQuality()<3)
+  fraction=fraction/intPart;
+  lineNumber=(int)intPart;
+  return (fraction<lineTolerance);
+}
+
+void syncProcessor::resetRetraceFlag()
+{
+  retraceFlag=false;
+  clearMatchArray();
+}
+
+
+bool  syncProcessor::createModeBase()
+{
+  bool done=false;
+  if(currentModePtr) delete currentModePtr;
+  currentModePtr=NULL;
+  switch (currentMode)
     {
-      restart();
-      return;
+    case M1:
+    case M2:
+      currentModePtr=new modeGBR(currentMode,RXSTRIPE,false,false);
+      break;
+    case S1:
+    case S2:
+    case SDX:
+      currentModePtr=new modeGBR2(currentMode,RXSTRIPE,false,false);
+      break;
+    case R36:
+      currentModePtr=new modeRobot1(currentMode,RXSTRIPE,false,false);
+      break;
+    case R24:
+    case R72:
+    case MR73:
+    case MR90:
+    case MR115:
+    case MR140:
+    case MR175:
+    case ML180:
+    case ML240:
+    case ML280:
+    case ML320:
+      currentModePtr=new modeRobot2(currentMode,RXSTRIPE,false,false);
+      break;
+    case SC2_60:
+    case SC2_120:
+    case SC2_180:
+    case P3:
+    case P5:
+    case P7:
+    case MC110N:
+    case MC140N:
+    case MC180N:
+      currentModePtr=new modeRGB(currentMode,RXSTRIPE,false,false);
+      break;
+    case FAX480:
+    case BW8:
+    case BW12:
+      currentModePtr=new modeBW(currentMode,RXSTRIPE,false,false);
+      break;
+    case AVT24:
+    case AVT90:
+    case AVT94:
+      currentModePtr=new modeAVT(currentMode,RXSTRIPE,false,false);
+      break;
+    case PD50:
+    case PD90:
+    case PD120:
+    case PD160:
+    case PD180:
+    case PD240:
+    case PD290:
+    case MP73:
+    case MP115:
+    case MP140:
+    case MP175:
+      currentModePtr=new modePD(currentMode,RXSTRIPE,false,false);
+      break;
+    case MP73N:
+    case MP110N:
+    case MP140N:
+      currentModePtr=new modePD(currentMode,RXSTRIPE,false,true);
+      break;
+    default:
+      currentMode=NOTVALID;
+      break;
     }
-  if(!autoSlantAdjust) return;
-  if ((mode>=AVT24) && (mode <= AVT94)) return;
-  if (syncArray[syncArrayIndex].lineNumber<slantAdjustLine) return;
-  if(lostLines<2)
+  if (currentMode!=NOTVALID)
     {
-      slantAdjust();
+      initializeSSTVParametersIndex(currentMode,false);
+      QString s=getSSTVModeNameLong(currentMode);
+      addToLog(QString("create RX mode: %1").arg(getSSTVModeNameShort(currentMode)),LOGSYNCSTATE);
+      currentModePtr->init(modifiedClock);
+      startImageRXEvent* ce = new startImageRXEvent(QSize(currentModePtr->imagePixels(),currentModePtr->imageLines()));
+      ce->waitFor(&done);
+      QApplication::postEvent(dispatcherPtr, ce);
+      while(!done)
+        {
+          QApplication::processEvents();
+        }
     }
+  return (currentMode!=NOTVALID);
 }
 
 
-void syncProcessor::restart()
-{
-//  bool done=false;
-
-//  //      dumpSyncArray(false,0);
-//  syncLostEvent* ce;
-//  ce = new 	syncLostEvent();
-//  ce->waitFor(&done);
-//  QApplication::postEvent(dispatcherPtr, ce);
-//  while(!done) { qApp->processEvents();}
-  addToLog("sync lost",LOGSYNC1);
-  syncFound=false;
-}
-
-bool syncProcessor::regression(DSPFLOAT &a,DSPFLOAT &b,int start, int end)
+void syncProcessor::regression(DSPFLOAT &a,DSPFLOAT &b,bool initial)
 {
   /* calculate linear regression
     formula x=a+by
     b=sum((x[i]-xm)*(y[i]-ym))/sum((y[i]-ym)*(y[i]-ym))
     a=xm-b*ym
   */
-  int i,j;
-  unsigned int tempCount=0;
+  int j;
 
+  int count=activeChainPtr->count();
+  falseSlantSync=0;
   DSPFLOAT sum_x,sum_y,sum_xx,sum_xy;
   sum_x=sum_y=sum_xx=sum_xy=a=b=0;
-  for(j=1,i=start;i<=end;i++,j++)
+  unsigned int endZero;
+  unsigned int tempCount=0;
+  //  if(currentMode==S1 || currentMode==S2)
+  //    {
+  //      j=1;
+  //      endZero=syncArray[1].end-samplesPerLine;
+  //    }
+  //  else
+  {
+    j=0;
+    endZero=syncArray[0].end;
+  }
+  for(;j<count;j++)
     {
-      slantArray[j].y= (DSPFLOAT)(syncArray[i].end-syncArray[start-1].end);
-      slantArray[j].x= round(slantArray[j].y/samplesPerLine)*samplesPerLine;
-//      qDebug() << slantArray[j].x << slantArray[j].y << slantArray[j].x-slantArray[j].y;
-      if(slantArray[j].x-slantArray[j].y<150)
+
+      if((activeChainPtr->at(j)->fraction>0.006)&&(!initial))
+        {
+          continue;
+        }
+
+      slantXYArray[tempCount].y=(DSPFLOAT)(syncArray[activeChainPtr->at(j)->to].end-endZero);
+      slantXYArray[tempCount].x= syncArray[activeChainPtr->at(j)->to].lineNumber*samplesPerLine;
+      addToLog(QString("pos: %1, x=%2 y=%3 syncIndex:%4, diff %5").arg(tempCount).arg(slantXYArray[tempCount].x).arg(slantXYArray[tempCount].y).arg(activeChainPtr->at(j)->to).arg(slantXYArray[tempCount].x-slantXYArray[tempCount].y) ,LOGSLANT);
+      if((fabs(slantXYArray[tempCount].x-slantXYArray[tempCount].y)>150.)&&(!initial))
         {
-        sum_x+=slantArray[tempCount].x;
-        sum_y+=slantArray[tempCount].y;
-        sum_xx+=slantArray[tempCount].x*slantArray[tempCount].x;
-        sum_xy+=slantArray[tempCount].x*slantArray[tempCount].y;
-        tempCount++;
+          falseSlantSync++;
+          continue;
         }
+      sum_x+=slantXYArray[tempCount].x;
+      sum_y+=slantXYArray[tempCount].y;
+      sum_xx+=slantXYArray[tempCount].x*slantXYArray[tempCount].x;
+      sum_xy+=slantXYArray[tempCount].x*slantXYArray[tempCount].y;
+      lastValidSyncCounter=syncArray[activeChainPtr->at(j)->to].end;
+      tempCount++;
     }
-  if(tempCount < 5) return false;
   b=((tempCount)*sum_xy-(sum_x*sum_y))/((tempCount)*sum_xx-(sum_x*sum_x));
   a=sum_y/(tempCount)-(b*sum_x)/(tempCount);
-  return true;
 }
 
 
 
-void syncProcessor::slantAdjust()
+bool syncProcessor::slantAdjust(bool initial)
 {
   DSPFLOAT a,b;
-  if ((mode>=AVT24) && (mode <= AVT94)) return ;
-  if(mode==NOTVALID) return ;
-//  logfile->addToAux(QString("%1\t%2\t%3\t%4")
-//                    .arg(syncArrayIndex)
-//                    .arg(syncArray[syncArrayIndex].start)
-//                    .arg(syncArray[syncArrayIndex].end)
-//                    .arg(syncArray[syncArrayIndex].retrace)
-//                    );
+  if ((currentMode>=AVT24) && (currentMode <= AVT94)) return true;
+  if(currentMode==NOTVALID) return true;
+  falseSlantSync=0;
+  if(!initial)
+    {
+      if(syncArray[activeChainPtr->last()->to].lineNumber<slantAdjustLine) return false;
+    }
+
+  regression(a,b,initial);
 
-  if (((mode==S1)||(mode==S2)||(mode==SDX))&&(syncArray[0].retrace==true))
+  //  addToLog(QString("regr. params line %1 a:%2 b:%3").arg(slantAdjustLine).arg(a).arg(b),LOGSLANT);
+  slantAdjustLine+=5;
+  if(!autoSlantAdjust) return false;
+  if(initial)
     {
-      if(!regression(a,b,2,syncArrayIndex)) return;
+      if((fabs(1.-b)>0.02) || (fabs(a)>100)) return false;
     }
   else
     {
-      if(!regression(a,b,1,syncArrayIndex)) return;
+      if((fabs(1.-b)>0.005) || (fabs(a)>50)) return false;
     }
-  addToLog(QString("step:%1 a=%2 b=%3, modified rxclock=%4").arg(syncArrayIndex).arg(a).arg(b).arg(modifiedClock*b),LOGSLANT);
-  slantAdjustLine+=7;
-  if((fabs(1.-b)>0.00001)||(fabs(a)>1))
+  if  (((fabs(1.-b)>0.00001)  || (fabs(a)>1)  )    && autoSlantAdjust)
     {
       newClock=true;
       modifiedClock*=b;
-      samplesPerLine=lineLength(mode,modifiedClock); //recalculate the samples per line
-      addToLog("new clock accepted",LOGSLANT);
-      syncPosition=syncArray[0].end+(long)round(a);
+      samplesPerLine=getLineLength(currentMode,modifiedClock); //recalculate the samples per line
+      addToLog(QString("new clock accepted: %1 a=%2,b=%3").arg(modifiedClock).arg(a).arg(b),LOGSLANT);
+
+      syncArray[0].end+=(long)round(a);
+      syncArray[0].start+=(long)round(a);
+
+      unsigned int syncCorrected;
+      if(syncArray[0].retrace)
+        {
+          syncCorrected=syncArray[0].end;
+        }
+      else
+        {
+          syncCorrected=(syncArray[0].start+syncArray[0].end)/2+getSyncWidth(currentMode,modifiedClock)/2;
+        }
+
+      syncPosition=currentModePtr->adjustSyncPosition(syncCorrected,syncArray[0].retrace)+FILTERDELAYCORRECTION; // type 2 sync end
+
+      recalculateMatchArray();
       addToLog(QString("slantAdjust: modified  syncpos:=%1").arg(syncPosition),LOGSLANT);
-      syncDeviation=SYNCDEVIATION/3.;
+
+      return true;
     }
 
+  return false;
 }
 
 
 
+void syncProcessor::switchSyncState(esyncState newState,quint32 sampleCntr)
+{
+  Q_UNUSED(sampleCntr)
+  if(syncState!=newState)
+    {
+      addToLog(QString("switching from %1 to %2 at %3").arg(syncStateStr[syncState]).arg(syncStateStr[newState]).arg(sampleCntr),LOGSYNCSTATE);
+      syncState=newState;
+    }
+}
 
+void syncProcessor::switchProcessState(esyncProcessState  newState)
+{
+  addToLog(QString("syncProcessState %1 to %2").arg(stateStr[syncProcesState]).arg(stateStr[newState]),LOGSYNCPROCESSSTATE);
+  if((newState==SYNCLOSTFALSESYNC) || (newState==SYNCLOSTNEWMODE)||(newState==SYNCLOSTMISSINGLINES) || (newState==SYNCLOST))
+    {
+      newState=SYNCLOST;
+    }
+  syncProcesState=newState;
+}
 
+#ifndef QT_NO_DEBUG
+void syncProcessor::setOffset(unsigned int dataScopeOffset)
+{
+  xOffset=dataScopeOffset;
+  scopeViewerSyncNarrow->setOffset(xOffset);
+  scopeViewerSyncWide->setOffset(xOffset);
+}
+#endif
diff --git a/qsstv/sstv/syncprocessor.h b/qsstv/sstv/syncprocessor.h
index 96bb9cb..171ffbc 100644
--- a/qsstv/sstv/syncprocessor.h
+++ b/qsstv/sstv/syncprocessor.h
@@ -1,162 +1,243 @@
 #ifndef SYNCPROCESSOR_H
 #define SYNCPROCESSOR_H
-#include "qsstvdefs.h"
-#include "dsp/filter.h"
-#include "sstvparam.h"
 
-#define SYNCARRAYLENGTH 512
-#define SYNCDEVIATION 0.008
-#define STATEMULTIPLIER 1000
-#define NUMSENSITIVITIES 4
+#include <sstvparam.h>
+#include "visfskid.h"
+#include <QObject>
+#include <QList>
+#include "filters.h"
+
+#define MAXSYNCENTRIES 2048
+#define STATESCALER 100
+
+
 
-extern const QString squelchStr[NUMSENSITIVITIES];
+class modeBase;
 
-struct ssyncArray
+
+struct ssenitivity
 {
-  ssyncArray()
+  unsigned int minMatchedLines;
+  unsigned int maxLineDistanceModeDetect;
+  unsigned int maxLineDistanceInSync;
+  DSPFLOAT onVolume;
+  DSPFLOAT offVolume;
+  DSPFLOAT startToMax;
+
+//  DSPFLOAT minVolume;
+//  DSPFLOAT currentVolumeRatio;
+//  DSPFLOAT switchOff;
+//  unsigned int minMatchedLines;
+//  unsigned int maxSyncsLost;
+//  unsigned int maxLineDistance;
+//  DSPFLOAT prevMaxIntegrator;
+//  DSPFLOAT trackMaxIntegrator;
+//  DSPFLOAT falseSyncs;
+
+};
+
+struct ssyncEntry
+{
+  ssyncEntry()
   {
     init();
   }
+
   void init()
   {
-    start=end=length=width=0;
-    retrace=false;
-    keep=false;
+    start=0;
+    end=0;
+    startVolume=0;
+//    endVolume=0;
+//    midVolume=0;
+    maxVolume=0;
+    width=0;
     inUse=false;
+    retrace=false;
     lineNumber=0;
-    spurious=0;
+    length=0;
   }
-  unsigned int start;
-  unsigned int end;
-  unsigned int width;
-  unsigned int length;
-  unsigned int lineNumber;
-  unsigned int spurious;
-  DSPFLOAT freq;
-  DSPFLOAT maxVol;
-  bool retrace;
-  bool keep;
+  int diffStartEnd()
+  {
+    width=end-start;
+    return width;
+  }
+  uint start;
+  uint startVolume;
+  uint end;
+//  uint endVolume;
+//  uint midVolume;
+  uint maxVolume;
+  uint width;
   bool inUse;
+  bool retrace;
+  uint lineNumber;
+  uint length;
 };
 
-struct smodeArray
+struct smatchEntry
 {
-  void clear()
+  smatchEntry()
   {
-    match=0;
-    lineNumber=0;
-    consecutiveSyncs=0;
-    firstSyncIndex=0;
-    ratio=0;
+    init();
   }
-  unsigned int match;
-  unsigned int lineNumber;
-  unsigned int consecutiveSyncs;
-  unsigned int firstSyncIndex;
-  DSPFLOAT ratio;
-};
 
-struct ssenitivity
-{
-  DSPFLOAT switchOn;
-  DSPFLOAT switchOff;
-  DSPFLOAT minVolume;
-  unsigned int syncLost;
+  smatchEntry(uint fromIdx,uint toIdx,uint lineSpace,double fract,uint endFromSample,uint endToSample)
+  {
+    from=fromIdx;
+    to=toIdx;
+    lineSpacing=lineSpace;
+    fraction=fract;
+    endFrom=endFromSample;
+    endTo=endToSample;
+  }
+  void init()
+  {
+    from=0;
+    to=0;
+    lineSpacing=0;
+    fraction=0;
+    endFrom=0;
+    endTo=0;
+  }
+  uint from;
+  uint to;
+  uint lineSpacing;
+  double fraction;
+  uint endFrom;
+  uint endTo;
 };
 
-struct sslantArray
+struct sslantXY
 {
   DSPFLOAT x;
   DSPFLOAT y;
 };
 
-#include <QObject>
+typedef QList<smatchEntry *> modeMatchList;
+typedef QList<modeMatchList *>  modeMatchChain;
 
 class syncProcessor : public QObject
 {
-  enum esyncState {SYNCOFF,SYNCON,SYNCVALID};
   Q_OBJECT
 public:
-  explicit syncProcessor(QObject *parent = 0);
+  enum esyncState {SYNCOFF,SYNCUP,SYNCSTART,SYNCON,SYNCDOWN,SYNCEND,SYNCVALID};
+  enum esyncProcessState {MODEDETECT,INSYNC,SYNCLOSTNEWMODE,SYNCLOSTFALSESYNC,SYNCLOSTMISSINGLINES,SYNCLOST,RETRACEWAIT};
+  explicit syncProcessor(bool narrow,QObject *parent = 0);
+  ~syncProcessor();
   void init();
-  void setFilters(filter *rx,filter *sync) {rxFilter=rx; syncFilter=sync;}
+  void reset();
   void process();
-  int isInSync();
-  bool hasRetrace(){return retraceDetected;}
+  esyncProcessState getSyncState(quint32  &syncPos) {syncPos=syncPosition; return syncProcesState; }
+  esstvMode getMode() {return currentMode;}
+  void resetRetraceFlag();
   bool hasNewClock()
   {
     bool nc=newClock;
     newClock=false;
     return nc;
   }
-  unsigned long getSyncPosition() { return syncPosition;}
-
-  esstvMode getMode() {return  mode ;}
-  //	DSPFLOAT *getSyncBufferPtr() {return syncBufferPtr;}
+  void recalculateMatchArray();
   DSPFLOAT getNewClock() {return modifiedClock;}
-  void setOffset(unsigned int dataScopeOffset);
-    int syncQuality;
+  void setEnabled(bool enable) {enabled=enable;}
 
-  
-signals:
-  
-public slots:
-private:
-  filter *rxFilter;
-  filter *syncFilter;
-  unsigned int sampleCounter;
-  unsigned int sampleCounterIndexed;
-  void extractSync();
-  void incrementSyncArray();
-  void modeDetect(bool atRetrace);
-  void modeDetectByLine();
-  void getMatchingSyncPulse(esstvMode idx);
-  int  matchingSync(int start,unsigned int pos,DSPFLOAT syncWidth, bool shadow);
-  void moveToTop(int index);
-  void cleanupSyncArray(esstvMode modeIndex);
-  void deleteSyncEntry(int index);
-  void dumpSyncArray(bool withShadow,int start=0);
-  int getSignalQuality();
-  void trackSyncs(esstvMode selectedMode);
-  bool regression(DSPFLOAT &a,DSPFLOAT &b,int start, int end);
-  void slantAdjust();
-  void restart();
-
-  int *syncVolumePtr;
-  int *rxVolumePtr;
-  int *freqPtr;
+
+  quint32 sampleCounter;
+  quint32 syncPosition;
+  quint32 lastValidSyncCounter;
+  DSPFLOAT trackMax;
+  int      syncQuality;
+  modeBase *currentModePtr;
+
+  quint16      *freqPtr;
+  DSPFLOAT     *syncVolumePtr;
+  unsigned int *inputVolumePtr;
+  videoFilter  *videoFilterPtr;
+  bool         retraceFlag;
+  bool tempOutOfSync;
+
+#ifndef QT_NO_DEBUG
+  void setOffset(unsigned int dataScopeOffset);
+  unsigned int xOffset;
   unsigned int syncStateBuffer[RXSTRIPE];
-  esyncState syncState;
-  ssyncArray syncArray[SYNCARRAYLENGTH];
-  unsigned int syncArrayIndex;
-  ssyncArray shadowSyncArray[SYNCARRAYLENGTH];
-  unsigned int shadowSyncArrayIndex;
-  smodeArray modeArray[AVT24];
-  int signalQuality;
+#endif
 
-  unsigned int visCode;
-  unsigned int visCounter;
-  DSPFLOAT visAvg;
-  unsigned int volumeOffCounter;
+public slots:
+  void slotNewCall(QString call);
+  void slotVisCodeDetected(int, uint visSampleCounter);
 
-  esstvMode mode;
+signals:
+  void callReceived(QString);
 
-  DSPFLOAT modifiedClock;
-  DSPFLOAT samplesPerLine;
-  DSPFLOAT syncWd;
-  unsigned int syncPosition;
-  bool syncFound;
-  unsigned int slantAdjustLine;
-  sslantArray slantArray [SYNCARRAYLENGTH];
+private:
+  quint32 maxLineSamples;
+  quint16 syncArrayIndex;
+  ssyncEntry syncArray[MAXSYNCENTRIES];
+  modeMatchChain matchArray[ENDNARROW+1];
+  quint16 slantAdjustLine;
+  esstvMode currentMode;
+  esyncState syncState;
+  esyncProcessState syncProcesState;
   bool newClock;
-  DSPFLOAT syncDeviation;
-
   esstvMode idxStart;
   esstvMode idxEnd;
-  unsigned int xOffset;
+  DSPFLOAT modifiedClock;
+  DSPFLOAT samplesPerLine;
+  streamDecoder streamDecode;
+  DSPFLOAT lineTolerance;
+  modeMatchList *activeChainPtr;
+
+  bool currentModeMatchChanged;
+  uint lastSyncTest;
+  uint lastUpdatedSync;
+  sslantXY slantXYArray[MAXSYNCENTRIES];
+  esstvMode visMode;
+
+  void extractSync();
+  bool validateSync();
+  bool findMatch();
+  bool addToMatch(esstvMode mode);
+  bool addToChain(esstvMode mode, uint fromIdx);
+  bool lineCompare(DSPFLOAT samPerLine, int srcIdx, int dstIdx, quint16 &lineNumber, double &fraction);
+  void switchSyncState(esyncState newState, quint32 sampleCntr);
+  void switchProcessState(esyncProcessState  newState);
+  uint calcTotalLines(modeMatchList *mlPtr);
+  double calcTotalFract(modeMatchList *mlPtr);
+  void clearMatchArray();
+  void removeMatchArrayChain(esstvMode mode,int chainIdx);
+  void cleanupMatchArray();
+  void dropTop();
+  void deleteSyncArrayEntry(uint entry);
+  bool createModeBase();
+  void checkSyncArray();
+  void trackSyncs();
+  void calcSyncQuality();
+  void calculateLineNumber(uint fromIdx, uint toIdx);
+  void regression(DSPFLOAT &a, DSPFLOAT &b, bool initial);
+  bool slantAdjust(bool initial);
+  DSPFLOAT syncWidth;
+  qint8 holdOffCount;
+  qint8 holdOffTimeout;
+
+// signal quality
+  quint16 falseSlantSync;
+  quint16 unmatchedSyncs;
+  quint16 falseSyncs;
+  quint16 avgLineSpacing;
+  quint16 missingLines;
+
+  bool detectNarrow;
+  bool enabled;
+  uint  minMatchedLines;
+  uint  visTimeout;
 
-  unsigned int lostLines;
-  bool retraceDetected;
 };
 
+
+
+
 #endif // SYNCPROCESSOR_H
+
+
+
+
diff --git a/qsstv/sstv/visfskid.cpp b/qsstv/sstv/visfskid.cpp
new file mode 100644
index 0000000..f923c5e
--- /dev/null
+++ b/qsstv/sstv/visfskid.cpp
@@ -0,0 +1,665 @@
+#include "visfskid.h"
+#include <QDebug>
+
+
+const QString fskStateStr[fskIdDecoder::GETID+1]=
+{
+  "FSKINIT",
+  "WAITS1900",
+  "WAITE1900",
+  "WAITS2100",
+  "WAITE2100",
+  "GETID"
+};
+
+const QString visStateStr[visDecoder::GETCODE+1]=
+{
+  "VISINIT",
+  "WAITS1200",
+  "WAITE1200",
+  "WAITS1900",
+  "WAITE1900",
+  "GETCODE"
+};
+
+//const QString retraceStateStr[retraceDetector::RETRACEWAITEND+1]=
+//{
+//  "RETRACEINIT",
+//  "RETRACESTART",
+//  "RETRACEEND",
+//};
+
+
+
+fskDecoder::fskDecoder()
+{
+  sampleCounter=0;
+}
+
+
+bool fskDecoder::waitStartFreq(unsigned int freqL,unsigned int freqH)
+{
+  if((avgFreq>=freqL) && (avgFreq<=freqH))
+    {
+      if(avgCounter<avgCount) avgCounter++;
+      else
+        {
+          timeoutCounter=0;
+          return true;
+        }
+    }
+  else
+    {
+      if(avgCounter) avgCounter--;
+    }
+  return false;
+}
+
+bool fskDecoder::waitStartFreq(unsigned int freqL, unsigned int freqH, unsigned long maxWait, bool &timeout)
+{
+  if((avgFreq>=freqL) && (avgFreq<=freqH))
+    {
+      if(avgCounter<avgCount) avgCounter++;
+      else
+        {
+          timeoutCounter=0;
+          return true;
+        }
+    }
+  else
+    {
+      if(avgCounter) avgCounter--;
+    }
+  if (timeoutCounter++>maxWait)
+    {
+      timeout=true;
+    }
+  else
+    {
+      timeout=false;
+    }
+  return false;
+}
+
+bool fskDecoder::waitEndFreq(unsigned int freqL,unsigned int freqH)
+{
+  if((avgFreq<freqL) || (avgFreq>freqH))
+    {
+      if(avgCounter) avgCounter--;
+      else return true;
+    }
+  else
+    {
+      if(avgCounter<avgCount) avgCounter++;
+    }
+  return false;
+}
+
+bool fskDecoder::waitEndFreq(unsigned int freqL, unsigned int freqH, unsigned long maxWait, bool &timeout)
+{
+  if((avgFreq<freqL) || (avgFreq>freqH))
+    {
+      if(avgCounter<avgCount) avgCounter++;
+      else
+        {
+          timeoutCounter=0;
+          return true;
+        }
+    }
+  else
+    {
+      if(avgCounter) avgCounter--;
+    }
+  if (timeoutCounter++>maxWait)
+    {
+      timeout=true;
+    }
+  else
+    {
+      timeout=false;
+    }
+  return false;
+}
+
+
+
+
+void fskDecoder::init()
+{
+  avgCounter=0;
+  bitCounter=0;
+  code=0;
+  checksum=0;
+  sampleCounter=0;
+  timeoutCounter=0;
+
+}
+
+
+
+fskIdDecoder::fskIdDecoder()
+{
+  fskState=FSKINIT;
+}
+
+
+
+
+bool fskIdDecoder::assemble(bool reset)
+{
+  if(reset)
+    {
+      checksum=0;
+      headerFound=false;
+      endFound=false;
+      fskIDStr.clear();
+      return true;
+    }
+  if(!headerFound) // waiting for start
+    {
+      if(symbol==0x2A)
+        {
+          addToLog("headerFound",LOGFSKID);
+          headerFound=true;
+          return false;
+        }
+      return true; // indicate resync
+
+    }
+  if(symbol==0x01)
+    {
+      endFound=true;
+      return false;
+    }
+  if(endFound)
+    {
+      if(checksum!=symbol)
+        {
+          fskIDStr.clear();
+        }
+      emit callReceived(fskIDStr);
+      fskIDStr.clear();
+      return true;
+    }
+  else
+    {
+      checksum=checksum^symbol;
+      fskIDStr.append(symbol+0x20);
+      addToLog(QString("fskstr %1 %2").arg(fskIDStr).arg(QString::number(symbol,16)),LOGFSKID);
+      if(fskIDStr.length()>9)
+        {
+          fskIDStr.clear();
+          return true;
+        }
+    }
+  return false;
+}
+
+void fskIdDecoder::reset()
+{
+  avgCount=FSKAVGCOUNT;
+  switchState(FSKINIT,0);
+  init();
+}
+
+QString fskIdDecoder::getFSKId()
+{
+  QString tmp(fskIDStr);
+  fskIDStr.clear();
+  return  tmp;
+}
+
+void fskIdDecoder::switchState(efskState newState,unsigned int i)
+{
+  Q_UNUSED(i);
+  addToLog(QString("%1 to %2 at samplecounter:%3 samplecounter%4").arg(fskStateStr[fskState]).arg(fskStateStr[newState]).arg(sampleCounter+i).arg(sampleCounter+i),LOGFSKID);
+  fskState=newState;
+}
+
+
+void fskIdDecoder::extract(unsigned int syncSampleCtr, bool )
+{
+  int i;
+  syncSampleCounter=syncSampleCtr;
+  bool timeout;
+  for(i=0;i<RXSTRIPE;i++)
+    {
+      avgFreq=freqPtr[i];
+      switch (fskState)
+        {
+        case FSKINIT:
+          sampleCounter=0;
+          avgCounter=0;
+          switchState(WAITSTART1500,i);
+          break;
+        case WAITSTART1500:
+          if(waitStartFreq(1400,1600))
+            {
+              switchState(WAITEND1500,i);
+              startSampleCounter=sampleCounter+i;
+            }
+          break;
+        case WAITEND1500:
+          {
+            if(waitEndFreq(1400,1600))
+              {
+                if(((sampleCounter+i-startSampleCounter)>=FSKMIN1500) && ((sampleCounter+i-startSampleCounter)<2*FSKMIN1500))
+                  {
+                    switchState(WAITSTART2100,i);
+                    timeoutCounter=0;
+                  }
+                else switchState(FSKINIT,i);
+              }
+          }
+          break;
+
+        case WAITSTART2100:
+          if(waitStartFreq(2000,2200,100,timeout))
+            {
+              switchState(WAITEND2100,i);
+              startSampleCounter=sampleCounter+i;
+            }
+          else if(timeout)
+            {
+              switchState(FSKINIT,i);
+            }
+          break;
+
+
+        case WAITEND2100:
+          {
+            if(waitEndFreq(2000,2200))
+              {
+                if(((sampleCounter+i-startSampleCounter)>=FSKMIN2100) && ((sampleCounter+i-startSampleCounter)<2*FSKMIN2100))
+                  {
+                    switchState(WAITSTART1900,i);
+                    timeoutCounter=0;
+                  }
+                else switchState(FSKINIT,i);
+              }
+          }
+          break;
+
+        case WAITSTART1900:
+          if(waitStartFreq(1800,2000,50,timeout))
+            {
+              switchState(WAITEND1900,i);
+              startSampleCounter=sampleCounter+i;
+            }
+          else if(timeout)
+            {
+              switchState(FSKINIT,i);
+            }
+          break;
+        case WAITEND1900:
+          {
+            if((sampleCounter+i-startSampleCounter)>=(FSKBIT/2-avgCount-56))
+              {
+                switchState(GETID,i);
+                startSampleCounter=sampleCounter+i;
+                assemble(true);
+                bitCounter=0;
+                symbol=0;
+              }
+          }
+          break;
+        case GETID:
+          if((sampleCounter+i-startSampleCounter)>=FSKBIT)
+            {
+
+              startSampleCounter=sampleCounter+i;
+              symbol>>=1;
+
+              if(avgFreq<2000)
+                {
+                  symbol|=0x20;
+                }
+              addToLog(QString("bit %1, %2 - %3 ").arg(bitCounter).arg(sampleCounter+i).arg(QString::number(symbol,2)),LOGFSKID);
+              bitCounter++;
+              if(bitCounter==6)
+                {
+                  if(assemble(false))
+                    {
+                      switchState(FSKINIT,i);
+                    }
+                  bitCounter=0;
+                }
+            }
+          break;
+        }
+    }
+  sampleCounter+=RXSTRIPE;
+}
+
+
+
+// VISDECODER
+// h1 1900 Hz 300
+// p1 1200 Hz 10
+// h2 1900 Hz 300
+// c1 1200 Hz 30
+// d0 1100 Hz 30 (1)  - 1300 Hz (0)
+// d1 1100 Hz 30 (1)  - 1300 Hz (0)
+// d2 1100 Hz 30 (1)  - 1300 Hz (0)
+// d3 1100 Hz 30 (1)  - 1300 Hz (0)
+// d4 1100 Hz 30 (1)  - 1300 Hz (0)
+// d5 1100 Hz 30 (1)  - 1300 Hz (0)
+// d6 1100 Hz 30 (1)  - 1300 Hz (0)
+// d7 1100 Hz 30 (1)  - 1300 Hz (0)
+// c2 1200 Hz 30
+visDecoder::visDecoder()
+{
+  visState=VISINIT;
+}
+
+
+void visDecoder::reset()
+{
+  avgCount=VISAVGCOUNT;
+  switchState(VISINIT,0);
+  init();
+}
+
+uint visDecoder::getCode()
+{
+  return code;
+}
+
+void visDecoder::switchState(evisState newState,unsigned int i)
+{
+  Q_UNUSED(i);
+  addToLog(QString("%1 to %2 at samplecounter:%3 samplecounter%4").arg(visStateStr[visState]).arg(visStateStr[newState]).arg(sampleCounter+i).arg(sampleCounter+i),LOGFSKID);
+  visState=newState;
+}
+
+
+void visDecoder::extract(unsigned int syncSampleCtr, bool narrow)
+{
+  syncSampleCounter=syncSampleCtr;
+  if (narrow) extractNarrow();
+  else extractWide();
+}
+
+
+void visDecoder::extractNarrow()
+{
+
+  int i;
+  unsigned int syncTemp;
+  Q_UNUSED(syncTemp);
+  bool timeout=false;
+  for(i=0;i<RXSTRIPE;i++)
+    {
+      syncTemp=syncSampleCounter+i;
+      avgFreq=freqPtr[i];
+      switch (visState)
+        {
+        case VISINIT:
+          sampleCounter=0;
+          avgCounter=0;
+          switchState(WAITSTART1900,i);
+          break;
+
+        case WAITSTART1900:
+          if(waitStartFreq(1800,2000))
+            {
+              switchState(WAITEND1900,i);
+              startSampleCounter=sampleCounter+i;
+            }
+          break;
+        case WAITEND1900:
+          {
+            if(waitEndFreq(1800,2000))
+              {
+
+                if(((sampleCounter+i-startSampleCounter)>=VISMIN1900) && ((sampleCounter+i-startSampleCounter)<2*VISMIN1900))
+                  {
+                    switchState(WAITSTART2100,i);
+                  }
+                else switchState(VISINIT,i);
+              }
+          }
+          break;
+        case WAITSTART2100:
+          if(waitStartFreq(2000,2200,50,timeout))
+            {
+              switchState(WAITEND2100,i);
+              startSampleCounter=sampleCounter+i;
+            }
+          else if(timeout)
+            {
+              switchState(VISINIT,i);
+            }
+          break;
+         case WAITEND2100:
+          if(waitEndFreq(2000,2200,1250,timeout))
+            {
+              switchState(WAITSTARTBIT,i);
+              startSampleCounter=sampleCounter+i;
+            }
+           else if(timeout)
+             {
+                switchState(VISINIT,i);
+             }
+            break;
+        case WAITSTARTBIT:
+          if(waitEndFreq(1800,2000,VISBITNARROW/2,timeout))
+              {
+                switchState(VISINIT,i);  // too short
+              }
+            if (timeout)
+              {
+                validCode=false;
+                switchState(GETCODE,i);
+                startSampleCounter=sampleCounter+i;
+                bitCounter=0;
+                bit=1;
+                symbol=0;
+              }
+               break;
+        case GETCODE:
+          if((sampleCounter+i-startSampleCounter)>=VISBITNARROW)
+            {
+              startSampleCounter=sampleCounter+i;
+              if(avgFreq<2000)
+                {
+                  symbol|=bit; //24 bits
+                }
+              addToLog(QString("bit %1, %2 - %3 ").arg(bitCounter).arg(syncSampleCounter+i).arg(QString::number(symbol,2)),LOGFSKID);
+              bitCounter++;
+              bit<<=1;
+              if(bitCounter==24)
+                {
+                  // check for validity
+                  if((symbol&0xFFF)!=0x56D)
+                    {
+                      validCode=false;
+                    }
+                  else
+                    {
+                      quint8 NVIS =((symbol>>12)&0x3F);
+                      quint8 XNVIS=((symbol>>18)&0x3F);
+                      if((NVIS^0x15)!=XNVIS)
+                        {
+                          validCode=false;
+                        }
+                      else
+                        {
+                          validCode=true;
+                          if((mode=lookupVIS(symbol))!=NOTVALID)
+                            {
+                              emit visCodeNarrowDetected((int)mode,syncSampleCounter+i);
+                            }
+                        }
+                     switchState(VISINIT,i);
+                    }
+                }
+              addToLog(QString("bit %1, %2 - %3 ").arg(bitCounter).arg(syncSampleCounter+i).arg(QString::number(symbol,2)),LOGFSKID);
+            }
+          break;
+        default:
+          switchState(VISINIT,i);
+          break;
+        }
+    }
+  sampleCounter+=RXSTRIPE;
+}
+
+
+
+
+void visDecoder::extractWide()
+{
+  int i;
+  bool timeout=false;
+  for(i=0;i<RXSTRIPE;i++)
+    {
+      avgFreq=freqPtr[i];
+      switch (visState)
+        {
+        case VISINIT:
+          sampleCounter=0;
+          avgCounter=0;
+          switchState(WAITSTART1900,i);
+          break;
+
+        case WAITSTART1900:
+          if(waitStartFreq(1800,2000))
+            {
+              switchState(WAITEND1900,i);
+              startSampleCounter=sampleCounter+i;
+            }
+          break;
+        case WAITEND1900:
+          {
+            if(waitEndFreq(1800,2000))
+              {
+
+                if(((sampleCounter+i-startSampleCounter)>=VISMIN1900) && ((sampleCounter+i-startSampleCounter)<2*VISMIN1900))
+                  {
+                    addToLog(QString("end1900 at %1").arg(syncSampleCounter+i),LOGVISCODE);
+                    switchState(WAITSTART1200,i);
+                    timeoutCounter=0;
+                  }
+                else switchState(VISINIT,i);
+              }
+          }
+          break;
+        case WAITSTART1200:
+          if(waitStartFreq(1100,1300,50,timeout))
+            {
+              addToLog(QString("start1200 at %1").arg(syncSampleCounter+i),LOGVISCODE);
+              switchState(WAITEND1200,i);
+              startSampleCounter=sampleCounter+i;
+              timeoutCounter=0;
+            }
+          else if(timeout)
+            {
+              switchState(VISINIT,i);
+            }
+          break;
+        case WAITEND1200:
+          {
+            if(waitEndFreq(1100,1300,VISBITWIDE/2-50,timeout))
+              {
+                switchState(VISINIT,i);  // too short
+              }
+            if (timeout)
+              {
+                validCode=false;
+                switchState(GETCODE,i);
+                startSampleCounter=sampleCounter+i;
+                addToLog(QString("startbit at %1").arg(syncSampleCounter+i),LOGVISCODE);
+                bitCounter=0;
+                bit=1;
+                symbol=0;
+              }
+          }
+          break;
+        case GETCODE:
+          if((sampleCounter+i-startSampleCounter)>=VISBITWIDE)
+            {
+              if(avgFreq>1400)
+                {
+                  //end of VIS detected
+                  validCode=true;
+                  addToLog(QString("end bits at %1").arg(syncSampleCounter+i),LOGVISCODE);
+                  if (bitCounter<=11)
+                  {
+                    symbol&=0xFF;
+                  }
+                  else
+                    {
+                      symbol&=0xFFFF;
+                    }
+                  // check for validity
+                  if((mode=lookupVIS(symbol))!=NOTVALID)
+                    {
+                      emit visCodeWideDetected((int)mode,syncSampleCounter+i);
+                    }
+
+                  switchState(VISINIT,i);
+                }
+              else
+                {
+                  startSampleCounter=sampleCounter+i;
+                  //              symbol>>=1;
+
+                  if(avgFreq<1200)
+                    {
+                      symbol|=bit; //16 bits
+                    }
+                  addToLog(QString("bit %1, %2 - %3 ").arg(bitCounter).arg(syncSampleCounter+i).arg(QString::number(symbol,2)),LOGVISCODE);
+                  bitCounter++;
+                  bit<<=1;
+                }
+            }
+          break;
+        default:
+          switchState(VISINIT,i);
+          break;
+        }
+    }
+  sampleCounter+=RXSTRIPE;
+}
+
+
+streamDecoder::streamDecoder(bool narrow)
+{
+  fskCoder.setDataPtr(avgBuffer);
+  visCoder.setDataPtr(avgBuffer);
+//  retracer.setDataPtr(avgBuffer);
+  isNarrow=narrow;
+}
+
+
+void streamDecoder::reset()
+{
+  avgFreq=0;
+  fskCoder.reset();
+  visCoder.reset();
+//  retracer.reset();
+}
+
+void streamDecoder::process(quint16 *freqPtr , unsigned int syncSampleCtr)
+{
+
+  int i;
+  for(i=0;i<RXSTRIPE;i++)
+    {
+      avgFreq=avgFreq*(1-FREQAVG)+FREQAVG*(DSPFLOAT)freqPtr[i];
+      avgBuffer[i]=avgFreq;
+    }
+
+    fskCoder.extract(syncSampleCtr,isNarrow);
+    visCoder.extract(syncSampleCtr,isNarrow);
+  //  retracer.extract();
+}
+
+
+
+
+
+
+
+
diff --git a/qsstv/sstv/visfskid.h b/qsstv/sstv/visfskid.h
new file mode 100644
index 0000000..3d19b83
--- /dev/null
+++ b/qsstv/sstv/visfskid.h
@@ -0,0 +1,154 @@
+#ifndef VISFSKID_H
+#define VISFSKID_H
+#include "appglobal.h"
+#include <QObject>
+#include "sstvparam.h"
+
+
+#define FSKMIN1500 ((SAMPLERATE*200)/1000)
+#define FSKMIN2100 ((SAMPLERATE*70)/1000)
+#define FSKMIN1900 ((SAMPLERATE*18)/1000)
+#define FSKBIT     ((SAMPLERATE*22)/1000)
+#define FSKAVGCOUNT   25
+#define VISAVGCOUNT   25
+#define RETRACEAVGCOUNT   100
+
+#define FREQAVG 0.05
+
+#define VISMIN1900  ((SAMPLERATE*200)/1000)
+#define VISMINWIDE1200   ((SAMPLERATE*25)/1000)
+#define VISBITWIDE      ((SAMPLERATE*30)/1000)
+
+#define VISMINNARROW2100  ((SAMPLERATE*80)/1000)
+#define VISBITNARROW      ((SAMPLERATE*22)/1000)
+
+
+
+
+#define MINRETRACEWIDTH ((SAMPLERATE*290)/1000)
+
+class fskDecoder :  public QObject
+{
+  Q_OBJECT
+public:
+  fskDecoder();
+  virtual void extract(unsigned int syncSampleCtr, bool narrow)=0;
+  void setDataPtr(DSPFLOAT *dataPtr) {freqPtr=dataPtr;}
+  virtual void reset()=0;
+
+
+ protected:
+  unsigned char bitCounter;
+  quint32 symbol;
+  quint32 bit;
+
+  unsigned char checksum;
+    unsigned int  code;
+  unsigned int sampleCounter;
+  unsigned int startSampleCounter;
+  unsigned int syncSampleCounter;
+  unsigned int timeoutCounter;
+  bool validCode;
+  DSPFLOAT *freqPtr;
+  DSPFLOAT avgFreq;
+  uint avgCounter;
+  uint avgCount;
+  unsigned int count1500;
+  unsigned int count2100;
+  unsigned int count1900;
+
+  bool waitStartFreq(unsigned int freqL, unsigned int freqH);
+  bool waitEndFreq(unsigned int freqL,unsigned int freqH);
+  bool waitStartFreq(unsigned int freqL,unsigned int freqH,unsigned long maxWait,bool &timeout);
+  bool waitEndFreq(unsigned int freqL, unsigned int freqH, unsigned long maxWait, bool &timeout);
+  void init();
+};
+
+class fskIdDecoder : public fskDecoder
+{
+  Q_OBJECT
+public:
+  enum efskState  {FSKINIT,WAITSTART1500,WAITEND1500,WAITSTART1900,WAITEND1900,WAITSTART2100,WAITEND2100,GETID};
+  fskIdDecoder();
+  void extract(unsigned int syncSampleCtr, bool);
+  void reset();
+  QString getFSKId();
+
+signals:
+  void callReceived(QString);
+
+private:
+  void switchState(efskState   newState, unsigned int i);
+  bool assemble(bool reset);
+  unsigned int fskIDChar;
+  QString fskStr;
+
+  unsigned int fskAVGCounter;
+  QString fskIDStr;
+  bool headerFound;
+  bool endFound;
+  efskState  fskState;
+};
+
+
+
+
+class visDecoder : public fskDecoder
+{
+  Q_OBJECT
+public:
+  enum evisState  {VISINIT,WAITSTART1200,WAITEND1200,WAITSTART1900,WAITEND1900,WAITSTART2100,WAITEND2100,WAITSTARTBIT,GETCODE};
+  visDecoder();
+  void extract(unsigned int syncSampleCtr, bool narrow);
+  void extractNarrow();
+  void extractWide();
+  void reset();
+  uint getCode();
+  esstvMode mode;
+signals:
+  void visCodeNarrowDetected(int,uint);
+  void visCodeWideDetected(int,uint );
+
+private:
+  void switchState(evisState   newState, unsigned int i);
+  evisState  visState;
+};
+
+
+
+//class retraceDetector: public fskDecoder
+//{
+//public:
+//  retraceDetector();
+//  enum eretraceState  {RETRACEINIT,RETRACEWAITSTART,RETRACEWAITEND};
+//  void extract(unsigned int syncSampleCtr);
+//  void reset();
+//private:
+//  void switchState(eretraceState   newState, unsigned int i);
+//  eretraceState  retraceState;
+//};
+
+class streamDecoder
+{
+public:
+  streamDecoder(bool narrow);
+  void reset();
+  void process(quint16 *freqPtr, unsigned int syncSampleCtr);
+  uint getVisCode() {return visCoder.getCode();}
+  fskIdDecoder *getFskDecoderPtr() {return &fskCoder;}
+  visDecoder *getVisDecoderPtr() {return &visCoder;}
+private:
+  DSPFLOAT avgFreq;
+  DSPFLOAT avgBuffer[RXSTRIPE];
+  fskIdDecoder fskCoder;
+  visDecoder visCoder;
+//  retraceDetector retracer;
+  quint16 freqPtr();
+  bool isNarrow;
+
+
+
+};
+
+
+#endif // VISFSKID_H
diff --git a/qsstv/txfunctions.cpp b/qsstv/txfunctions.cpp
deleted file mode 100644
index 4607b48..0000000
--- a/qsstv/txfunctions.cpp
+++ /dev/null
@@ -1,740 +0,0 @@
-/***************************************************************************
- *   Copyright (C) 2000-2008 by Johan Maes                                 *
- *   on4qz at telenet.be                                                      *
- *   http://users.telenet.be/on4qz                                         *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   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.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- ***************************************************************************/
-#include "txfunctions.h"
-#include "qsstvglobal.h"
-#include "configparams.h"
-#include <qmutex.h>
-//#include "imagecoder.h"
-#include "dsp/synthes.h"
-#include "sstv/modes/modes.h"
-#include "dispatcher.h"
-#include "sstv/cw.h"
-#include <QApplication>
-#include <assert.h>
-#include "txwidget.h"
-#include "sound/soundio.h"
-#include "sound/waterfalltext.h"
-#include "utils/hybridcrypt.h"
-#include "rig/rigcontrol.h"
-
-
-
-#define SILENCEDELAY 0.600           // send silence after transmission
-
-
-QMutex txMutex;
-
-esstvMode modeIndexTx;
-int templateIndex;
-bool useTemplate;
-bool useCW;
-bool useVOX;
-
-txFunctions::txFunctions()
-{
-  synthesPtr=new synthesizer(txClock);
-  currentMode=0;
-  oldMode=NOTVALID;
-  txState=TXIDLE;
-  started=false;
-  txDRM=new drmTransmitter;
-  txList.clear();
-  useHybrid=false;
-}
-
-txFunctions::~txFunctions()
-{
-  delete synthesPtr;
-  if(currentMode) delete currentMode;
-}
-
-void txFunctions::run()
-{
-  abort=false;
-  init();
-  while(!abort)
-    {
-      progressTXEvent *ce;
-      started=true;
-      switch (txState)
-        {
-        case TXIDLE:
-          msleep(10);
-        break;
-        case TXACTIVE:
-          msleep(1);
-        break;
-        case TXSENDTONE:
-          waitTxOn();
-          addToLog("txFunc: entered TXSENDTONE",LOGTXFUNC);
-          synthesPtr->sendTone(toneDuration,toneLowerFrequency,toneUpperFrequency,false);
-          addToLog("txFunc: TXSENDTONE waiting for end",LOGTXFUNC);
-          waitEnd();
-          txState=TXIDLE;
-        break;
-        case TXSENDDRM:
-          waitTxOn();
-//          synthesPtr->sendTone(5,1900,1900,false);
-          waterfallTime=waterfallPtr->getDuration(endPicWF);
-          waterfallTime+=waterfallPtr->getDuration(startPicWF);
-          initDRMImage();
-          ce=new progressTXEvent(calcTxTime(true,waterfallTime));
-          QApplication::postEvent( dispatcherPtr, ce );  // Qt will delete it when done
-          addToLog("start of wf",LOGTXFUNC);
-          waterfallPtr->setText(startPicWF);
-          synthesPtr->sendWFText();
-          addToLog("start of txDrm",LOGTXFUNC);
-          txDRM->start(true);
-
-          addToLog("end of txDrm",LOGTXFUNC);
-          if(txState==TXSENDDRM) // abort if txState is idle
-            {
-              waterfallPtr->setText(endPicWF);
-              synthesPtr->sendWFText();
-              addToLog("end of wf",LOGTXFUNC);
-              addToLog("txFunc: TXSENDDRM waiting for end",LOGTXFUNC);
-              waitEnd();
-            }
-          txState=TXIDLE;
-        break;
-        case TXSENDDRMBSR:
-          waitTxOn();
-          waterfallTime=waterfallPtr->getDuration(bsrWF);
-          ce=new progressTXEvent(calcTxTime(true,waterfallTime));
-          QApplication::postEvent( dispatcherPtr, ce );  // Qt will delete it when done
-          synthesPtr->sendWFText();
-          txDRM->start(true);
-          addToLog("txFunc: TXSENDDRMBSR waiting for end",LOGTXFUNC);
-          waitEnd();
-          txState=TXIDLE;
-        break;
-
-        case TXSENDDRMFIX:
-          waitTxOn();
-          waterfallTime=waterfallPtr->getDuration(fixWF);
-          ce=new progressTXEvent(calcTxTime(true,waterfallTime));
-          QApplication::postEvent( dispatcherPtr, ce );  // Qt will delete it when done
-          synthesPtr->sendWFText();
-          txDRM->start(true);
-          addToLog("txFunc: TXSENDDRMFIX waiting for end",LOGTXFUNC);
-          if(txState==TXSENDDRMFIX) // abort if txState is idle
-            {
-              waterfallPtr->setText(endPicWF);
-              synthesPtr->sendWFText();
-              addToLog("end of wf",LOGTXFUNC);
-              addToLog("txFunc: TXSENDDRM waiting for end",LOGTXFUNC);
-              waitEnd();
-            }
-          txState=TXIDLE;
-        break;
-        case TXSENDDRMTXT:
-          waitTxOn();
-        break;
-        case TXSENDID:
-          waitTxOn();
-          addToLog("txFunc: entered TXSENDID",LOGTXFUNC);
-          ce=new progressTXEvent(waterfallPtr->getDuration(NULL));
-          QApplication::postEvent( dispatcherPtr, ce );  // Qt will delete it when done
-          synthesPtr->sendWFText();
-          addToLog("txFunc: TXSENDID waiting for end",LOGTXFUNC);
-          waitEnd();
-          txState=TXIDLE;
-        break;
-
-        case TXFAXSTART:
-          waitTxOn();
-          addToLog("txFunc: TXFAXSTART",LOGTXFUNC);
-          //            initSSTVImage();
-          faxStart();
-          addToLog("txFunc: TXFAXSTART waiting for end",LOGTXFUNC);
-          waitEnd();
-          txState=TXIDLE;
-        break;
-
-        case TXSSTVIMAGE:
-          waitTxOn();
-          addToLog("txFunc: entered TXIMAGE",LOGTXFUNC);
-          //            initSSTVImage();
-          ce=new progressTXEvent(calcTxTime(false,0));
-          QApplication::postEvent( dispatcherPtr, ce );  // Qt will delete it when done
-          if(txSSTVParam.mode==FAX480)
-            {
-              for (int i=0;i<1220;i++)
-                {
-                  synthesPtr->sendTone(0.00205,1500,0,true);
-                  synthesPtr->sendTone(0.00205,2300,0,true);
-                }
-            }
-          else
-            {
-              sendPreamble();
-              sendVIS();
-            }
-          addToLog("txFunc: sendImage",LOGTXFUNC);
-          sendImage();
-          addToLog("txFunc: endImage",LOGTXFUNC);
-          txState=TXSSTVPOST;
-        break;
-        case TXSSTVPOST:
-          addToLog("txFunc: TXSSTVPOST ",LOGTXFUNC);
-          if (useCW)
-            {
-              sendCW();
-            }
-          else
-            {
-              sendFSKID();
-            }
-
-          waitEnd();
-          txState=TXIDLE;
-        break;
-        case TXTEST:
-          sendTestPattern();
-        break;
-
-        }
-    }
-  started=false;
-  addToLog("txFunc stopped",LOGTXFUNC);
-  abort=false;
-}
-
-
-
-void txFunctions::init()
-{
-  txState=TXIDLE;
-  addToLog("txFunc: Init",LOGTXFUNC);
-	sampleCounter=0;
-}
-
-void txFunctions::waitTxOn()
-{
-  double txDelay;
-  txDelay=rigController->getTxDelay();
-  if(txDelay!=0)
-    {
-      synthesPtr->sendSilence(txDelay);
-    }
-}
-
-void txFunctions::stopAndWait()
-{
-
-  stopDRM=true;
-  if(!isRunning()) return;
-  if(currentMode) currentMode->abort();
-  addToLog("txFunc: stop initiated",LOGTXFUNC);
-  logStatus();
-  txState=TXIDLE;
-  while(txState!=TXIDLE)
-    {
-      if(!isRunning()) return;
-      qApp->processEvents();
-    }
-  addToLog("txFunc: stop executed",LOGTXFUNC);
-  stopTXEvent *ce = new  stopTXEvent();
-  QApplication::postEvent(dispatcherPtr, ce);
-}
-
-
-
-
-bool txFunctions::create(esstvMode m,DSPFLOAT clock)
-{
-  if(oldMode==m)
-    {
-      currentMode->init(clock);
-      return true;
-    }
-  oldMode=m;
-  if(currentMode) delete currentMode;
-  currentMode=0;
-  switch (m)
-    {
-      case M1:
-      case M2:
-        currentMode=new modeGBR(m,TXSTRIPE,true);
-      break;
-      case S1:
-      case S2:
-      case SDX:
-        currentMode=new modeGBR2(m,TXSTRIPE,true);
-      break;
-      case R36:
-        currentMode=new modeRobot1(m,TXSTRIPE,true);
-      break;
-      case R24:
-      case R72:
-          currentMode=new modeRobot2(m,TXSTRIPE,true);
-    break;
-      case SC2_60:
-      case SC2_120:
-      case SC2_180:
-      case P3:
-      case P5:
-      case P7:
-          currentMode=new modeRGB(m,TXSTRIPE,true);
-      break;
-      case FAX480:
-      case BW8:
-      case BW12:
-          currentMode=new modeBW(m,TXSTRIPE,true);
-      break;
-      case AVT24:
-      case AVT90:
-      case AVT94:
-          currentMode=new modeAVT(m,TXSTRIPE,true);
-      break;
-      case PD50:
-      case PD90:
-      case PD120:
-      case PD160:
-      case PD180:
-      case PD240:
-      case PD290:
-      case MP73:
-      case MP115:
-      case MP140:
-      case MP175:
-          currentMode=new modePD(m,TXSTRIPE,true);
-      break;
-      default:
-        m=NOTVALID;
-      break;
-    }
-  if (m!=NOTVALID)
-    {
-      initializeSSTVParametersIndex(m,true);
-      QString s=getSSTVModeNameLong(m);
-      addToLog("create: create TX mode",LOGTXFUNC);
-      assert(currentMode);
-     currentMode->init(clock);
-      return true;
-    }
-  return false;
-}
-
-
-
-
-
-void txFunctions::sendTestPattern()
-{
-  if(patternNumber==TPBURST) syncBurst();
-}
-
-
-
-/** send a burst of syncs */
-/*
-void txFunctions::syncBurst()
-{
-  // we will send 5msec 1200Hz followed by 50 msec silence
-//	synthesPtr->sendTone(0.005,1200.);
-  for (int i=300;i<3000;i++)
-    {
-      synthesPtr->sendTone(0.005,(double) i);
-    }
-  synthesPtr->sendSilence(0.100);;
-}
-*/
-
-/** send a burst of syncs */
-void txFunctions::syncBurst()
-{
-  // send 5msec 1200Hz followed by 50 msec silence
-//	synthesPtr->sendTone(0.005,1200.);
-  for (int i=0;i<50;i++)
-    {
-      synthesPtr->sendTone(0.005,1200,0,true);
-      synthesPtr->sendTone(0.020,1700,0,true);
-    }
-  synthesPtr->sendSilence(0.100);;
-}
-
-void txFunctions::faxStart()
-{
-  // send 300Hz modulated 1500Hz/2300Hz tone
-//	synthesPtr->sendTone(0.005,1200.);
-  for (int i=0;i<100;i++)
-    {
-      synthesPtr->sendTone(0.0333,1500,0,true);
-      synthesPtr->sendTone(0.0333,2300,0,true);
-    }
-  synthesPtr->sendSilence(0.100);
-}
-
-
-
-
-void txFunctions::startTestPattern(uint tpnum)
-{
-  patternNumber=tpnum;
-  txState=TXTEST;
-}
-
-
-//void txFunctions:: initSSTVImage()
-//{
-//  create(modeIndexTx,txClock);
-//}
-
-void txFunctions:: sendPreamble()
-{
-  addToLog("txFunc:sendPreamble",LOGTXFUNC);
-  if(useVOX) synthesPtr->sendTone(1.,1700.,0,false);
-  synthesPtr->sendTone(0.1,1900.,0,true);
-  synthesPtr->sendTone(0.1,1500.,0,true);
-  synthesPtr->sendTone(0.1,1900.,0,true);
-  synthesPtr->sendTone(0.1,1500.,0,true);
-  synthesPtr->sendTone(0.1,2300.,0,true);
-  synthesPtr->sendTone(0.1,1500.,0,true);
-  synthesPtr->sendTone(0.1,2300.,0,true);
-  synthesPtr->sendTone(0.1,1500.,0,true);
-  synthesPtr->sendTone(0.3,1900.,0,true);
-  synthesPtr->sendTone(0.01,1200.,0,true);
-  synthesPtr->sendTone(0.3,1900.,0,true);
-}
-
-
-
-void txFunctions:: sendVIS()
-{
-  int i,l;
-  int t=txSSTVParam.VISCode;
-  addToLog("txFunc:sendVis",LOGTXFUNC);
-  if ((t&0xFF)==0x23) l=16;
-  else l=8;
-  synthesPtr->sendTone(0.030,1200,0,false); // startbit
-  for (i=0;i<l;i++)
-    {
-      if((t&1)==1) synthesPtr->sendTone(0.030,1100,0,true);
-      else synthesPtr->sendTone(0.030,1300,0,true);
-      t>>=1;
-    }
-  synthesPtr->sendTone(0.030,1200,0,true); // stopbit
-}
-
-
-void txFunctions::sendCW()
-{
-  addToLog("txFunc:sendCW",LOGTXFUNC);
-  float tone;
-  float duration;
-  initCW(cwText);
-  synthesPtr->sendSilence(0.5);
-  while(sendTextCW(tone,duration))
-    {
-      synthesPtr->sendTone(duration,tone,0,true);
-    }
-}
-
-void txFunctions::waitEnd()
-{
-  synthesPtr->sendTone(SILENCEDELAY,00,0,false); // send silence
-  addToLog("waitEnd() posting endTXImage",LOGTXFUNC);
-  endImageTXEvent *ce=new endImageTXEvent;
-  QApplication::postEvent(dispatcherPtr, ce );  // Qt will delete it when done
-}
-
-double txFunctions::calcTxTime(bool isDRM,int overheadTime)
-{
-  double tim=0;
-  float tone;
-  float duration;
-  tim= soundIOPtr->getPlaybackStartupTime();
-  tim+=SILENCEDELAY;
-  if(!isDRM)
-    {
-      initializeSSTVParametersIndex(modeIndexTx,true);
-      int t=txSSTVParam.VISCode;
-      initCW(cwText);
-      tim+=1.41; //preamble;
-      if ((t&0xFF)==0x23) tim+=18.*0.03;
-      else tim+=10.*0.03;
-      tim+=txSSTVParam.imageTime;
-      tim+=0.5 ;//CW silence gap
-      if(useCW)
-        {
-          while(sendTextCW(tone,duration))
-            {
-              tim+=duration;
-            }
-        }
-      tim+=0.3; // trailer;
-    }
-  else
-    {
-      tim+=overheadTime;
-      tim+=txDRM->getDuration();
-    }
-  addToLog(QString("txFunc: calcTimeTx %1").arg(tim),LOGTXFUNC);
-  return tim;
-}
-
-
-
-
-void txFunctions::sendImage()
-{
-  addToLog("txFunc: sendImage",LOGTXFUNC);
-  currentMode->transmitImage(txWidgetPtr->getImageViewerPtr());
-}
-
-void txFunctions::initDRMImage()
-{
-  eRSType rsType;
-  reedSolomonCoder rsd;
-  QString fn;
-  QString ext;
-  QFileInfo finf;
-  hybridCrypt hc;
-  // we need to save it as a jpg file
-  if(!useHybrid)
-    {
-      finf.setFile(txWidgetPtr->getImageViewerPtr()->getFilename());
-      fn=QDateTime::currentDateTime().toUTC().toString("yyyyMMddHHmmss");
-      fn+="-"+finf.baseName();
-      ext=finf.suffix();
-    }
-  else
-    {
-     finf.setFile(hybridFilename);
-     fn= finf.baseName();
-     ext=finf.suffix();
-    }
-  fixBlockList.clear();
-
-  if(txList.count()>5) txList.removeFirst();
-  txList.append(txSession());
-  txList.last().filename=fn;
-  txList.last().extension=ext;
-  if(!useHybrid)
-    {
-      txList.last().drmParams=drmTxParameters;
-      txWidgetPtr->getImageViewerPtr()->copyToBuffer(&(txList.last().ba));
-      rsType=(eRSType)txList.last().drmParams.reedSolomon;
-      baDRM=txList.last().ba;
-      if(rsType!=RSTNONE)
-        {
-          rsd.encode(baDRM,txList.last().extension,rsType);
-          txDRM->init(&baDRM,txList.last().filename,rsTypeStr[rsType],txList.last().drmParams);
-        }
-      else
-        {
-          txDRM->init(&baDRM,txList.last().filename,txList.last().extension,txList.last().drmParams);
-        }
-    }
-  else
-    {
-      txList.last().drmParams.bandwith=1; // bw 2.2
-      txList.last().drmParams.robMode=2;  // mode E
-      txList.last().drmParams.interleaver=0; // long
-      txList.last().drmParams.protection=0; // high
-      txList.last().drmParams.qam=0; // 4bit QAM
-      txList.last().drmParams.callsign=myCallsign;
-
-      // we have to fill in the body
-      txList.last().ba.clear();
-      hc.enCrypt(&txList.last().ba);
-      txDRM->init(&txList.last().ba,txList.last().filename,txList.last().extension,txList.last().drmParams);
-    }
-
-
-  // transportID is set
-  txList.last().transportID=txTransportID;
-}
-
-
-void txFunctions::initDRMBSR(QByteArray *ba)
-{
-  baDRM=*ba;
-  fixBlockList.clear();
-  txDRM->init(&baDRM,"bsr","bin",drmTxParameters);
-  addToLog(QString("bsr.bin send %1").arg(baDRM.size()),LOGPERFORM);
-}
-
-bool txFunctions::initDRMFIX(QString fileName,QString extension,eRSType rsType,int mode)
-{
-  reedSolomonCoder rsd;
-  QFile fi(fileName);
-  if(fi.open(QIODevice::ReadOnly)<=0) return false;
-  baDRM=fi.readAll();
-  if(rsType!=RSTNONE)
-    {
-      rsd.encode(baDRM,extension,rsType);
-      txDRM->init(&baDRM,fileName,rsTypeStr[rsType],modeToParams(mode));
-    }
-  else
-    {
-      txDRM->init(&baDRM,fileName,extension,modeToParams(mode));
-    }
-  return true;
-}
-
-bool txFunctions::initDRMFIX(txSession *sessionPtr)
-{
-  reedSolomonCoder rsd;
-  eRSType rsType;
-  rsType=(eRSType)sessionPtr->drmParams.reedSolomon;
-  baDRM=sessionPtr->ba;
-  if(rsType!=RSTNONE)
-    {
-      rsd.encode(baDRM,sessionPtr->extension,rsType);
-      txDRM->init(&baDRM,sessionPtr->filename,rsTypeStr[rsType],sessionPtr->drmParams);
-    }
-  else
-    {
-      txDRM->init(&baDRM,sessionPtr->filename,sessionPtr->extension,sessionPtr->drmParams);
-    }
-  return true;
-}
-
-
-void txFunctions::sendDRMFIX()
-{
-//  QByteArray ba;
-//  QFile fi(rxImagesPath+"/bsr.bin");
-//  if(fi.open(QIODevice::ReadOnly)<=0) return;
-//  ba=fi.readAll();
-//  txDRM->init(&ba,"bsr","bin",drmTxParameters);
-//  addToLog(QString("bsr.bin send").arg(ba.size()),LOGPERFORM);
-//  txDRM->start();
-}
-
-
-void txFunctions::logStatus()
-{
-  QString stat,statr;
-  if(isRunning()) statr="true"; else statr="false";
-  addToLog(QString("TX Is running %1").arg(statr),LOGDISPAT);
-  stat="TX state: ";
-  switch (txState)
-    {
-    case TXIDLE: stat+="IDLE";  break;
-    case TXACTIVE: stat+="ACTIVE";  break;
-    case TXSENDTONE: stat+="SENDTONE";  break;
-    case TXSENDID: stat+="SENDID";  break;
-    case TXSENDDRM: stat+="SENDDRM";  break;
-    case TXSENDDRMBSR: stat+="SENDDRMBSR";  break;
-    case TXSENDDRMFIX: stat+="SENDDRMFIX";  break;
-    case TXSENDDRMTXT: stat+="SENDDRMTXT";  break;
-    case TXSSTVIMAGE: stat+="SSTVIMAGE";  break;
-    case TXSSTVPOST: stat+="SSTVPOST";  break;
-    case TXFAXSTART: stat+="FAXSTART";  break;
-    case TXTEST: stat+="TEST";  break;
-    }
-  addToLog(stat,LOGTXFUNC);
-}
-
-txSession *txFunctions::getSessionPtr(uint transportID)
-{
-  int i;
-  for(i=0;i<txList.count();i++)
-    {
-      if(txList.at(i).transportID==transportID)
-        {
-          return &txList[i];
-        }
-    }
-  return NULL;
-}
-
-
-void txFunctions:: sendFSKChar(int IDChar)
-{
-  int TxBit;
-
-    for (int i=0;i<6;i++)
-   {
-     TxBit = IDChar & 0x01;
-     IDChar = IDChar >> 1;
-     if (TxBit == 0x01)
-  synthesPtr->sendTone(0.022,1900.,0,true);
-     else
-  synthesPtr->sendTone(0.022,2100.,0,true);
-    }
-}
-
-// sendFSKID by DL3YAP
-
-void txFunctions:: sendFSKID()
-{
-  int idx;
-  int l;
-  int IDChar;
-  int Checksum;
-
-
-  if (myCallsign.isEmpty()) return;
-  // addToLog("txFunc:sendFSKID",LOGFSKID);
-
-   QTextStream out(stdout);
-
-  l=myCallsign.size();
-  idx=0;
-  Checksum=0;
- // synthesPtr->sendTone(2.0,00,0,false);
-  synthesPtr->sendTone(0.3,1500.,0,false);
-  synthesPtr->sendTone(0.1,2100.,0,true);
-  synthesPtr->sendTone(0.022,1900.,0,true);
-
-  IDChar = 0x2A;
-  sendFSKChar(IDChar);
-
-  QChar IDText=	QChar(myCallsign[idx]);
-  IDChar=int(IDText.toLatin1());
-
-  IDChar = (IDChar - 0x20);
-  Checksum = IDChar;
-
-  while (idx < l)
-  {
-    sendFSKChar(IDChar);
-    idx++;
-    QChar IDText=QChar(myCallsign[idx]);
-    IDChar=int(IDText.toLatin1());
-    IDChar = (IDChar - 0x20);
-
-    if (idx < l)
-    {
-      Checksum = Checksum ^ IDChar;
-    }
-  }
-
-  IDChar = 0x01;
-
-  sendFSKChar(IDChar);
-
-  IDChar = Checksum & 0x3F ;
-
-  sendFSKChar(IDChar);
-
-  // synthesPtr->sendTone(0.022,2100.,0,true);
-  synthesPtr->sendTone(0.1,1900.,0,true);
-}
-
-
-
-
-
diff --git a/qsstv/txfunctions.h b/qsstv/txfunctions.h
deleted file mode 100644
index 8352d9d..0000000
--- a/qsstv/txfunctions.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/***************************************************************************
- *   Copyright (C) 2000-2008 by Johan Maes                                 *
- *   on4qz at telenet.be                                                      *
- *   http://users.telenet.be/on4qz                                         *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   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.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- ***************************************************************************/
-#ifndef TXFUNC_H
-#define TXFUNC_H
-#include <QThread>
-#include "dsp/filterparam.h"
-#include "sstv/sstvparam.h"
-#include "sstv/modes/modebase.h"
-#include "drmtx/drmtransmitter.h"
-#include "utils/reedsolomoncoder.h"
-
-class imageCoder;
-
-#define TPBURST 0
-
-extern esstvMode modeIndexTx;
-extern int templateIndex;
-extern bool useTemplate;
-extern bool useCW;
-extern bool useVOX;
-
-class drmTransmitter;
-
-struct txSession
-{
-  drmTxParams drmParams;
-  QByteArray ba;  // contains the image data in jpg, jp2 .... format
-  uint transportID;
-  QString filename;
-  QString extension;
-};
-
-class txFunctions: public QThread
-{
-public:
-  enum etxState
-    {
-    TXIDLE,	//!< in idle loop
-    TXACTIVE,
-    TXSENDTONE,
-    TXSENDID,
-    TXSENDDRM,
-    TXSENDDRMBSR,
-    TXSENDDRMFIX,
-    TXSENDDRMTXT,
-    TXSSTVIMAGE,
-    TXSSTVPOST,
-    TXFAXSTART,
-    TXTEST
-    };
-public:
-  txFunctions();
-  ~txFunctions();
-  bool create(esstvMode m,DSPFLOAT clock);
-  modeBase *currentMode;
-  void run();
-  void stopAndWait();
-  bool hasStarted() {return started;}
-  void setTXState(etxState d) { txState=d;}
-  etxState getTXState() { return txState;}
-  void syncBurst();
-  void faxStart();
-  void setDRMTxParams(drmTxParams params)
-  {
-    drmTxParameters=params;
-  }
-  txSession *getSessionPtr(uint transportID);
-
-  void enableNoise(bool en,double level=0.)
-  {
-    if (level==0)
-      {
-        noiseEnabled=en;
-      }
-  }
-  void setFilter(efilterType filterType);
-  void startTestPattern(uint tpnum);
-  //  void setCall(const QString &str);
-  //  void setToOperator(const QString &str);
-  //  void setRSV(const QString &str);
-  void setToneParam(double duration,double lowerFreq,double upperFreq=0)
-  {
-    toneDuration=duration;
-    toneLowerFrequency=lowerFreq;
-    toneUpperFrequency=upperFreq;
-  }
-  double calcTxTime(bool isDRM, int  overheadTime);
-  void logStatus();
-  void initDRMBSR(QByteArray *ba);
-  bool initDRMFIX(QString fileName, QString extension, eRSType rsType, int mode);
-  bool initDRMFIX(txSession *sessionPtr);
-  void setHybrid(bool h,QString hbfn=QString::Null())
-  {
-    useHybrid=h;
-    hybridFilename=hbfn;
-  }
-private:
-  bool abort;
-  void init();
-  unsigned long sampleCounter;
-  bool noiseEnabled;
-
-  short int filter(double sample);
-  void write(double sample);
-
-  etxState txState;
-  uint patternNumber;
-  void sendTestPattern();
-  void sendPreamble();
-  void sendVIS();
-  void sendImage();
-  void initDRMImage();
-  void sendDRMFIX();
-  void sendCW();
-  void sendFSKChar(int IDChar);
-  void sendFSKID();
-  void waitTxOn();
-  //  void initSSTVImage();
-  void waitEnd();
-  double toneDuration;
-  double toneLowerFrequency;
-  double toneUpperFrequency;
-  esstvMode oldMode;
-  bool started;
-  drmTransmitter *txDRM;
-  drmTxParams drmTxParameters;
-  QByteArray baDRM;
-  double waterfallTime;
-  QList <txSession> txList;
-  bool useHybrid;
-  QString hybridFilename;
-};
-
-#endif
-
-
diff --git a/qsstv/utils/arraydumper.cpp b/qsstv/utils/arraydumper.cpp
new file mode 100644
index 0000000..2fc7eed
--- /dev/null
+++ b/qsstv/utils/arraydumper.cpp
@@ -0,0 +1,244 @@
+#include "arraydumper.h"
+#include "appglobal.h"
+
+
+
+
+
+void arrayDump(QString label,short int *data, unsigned int len,bool toAux,bool singleColumn)
+{
+  unsigned int i,j;
+  QString dumpStr,tmp;
+  if(!singleColumn)
+  {
+  for( i=0;i<len;i+=16)
+    {
+      dumpStr=label+" ";
+      for(j=0;(j<16)&&((i+j)<len);j++)
+        {
+//          tmp=QString::number(data[i+j],16).right(4);
+        tmp=QString::number(data[i+j]).right(6);
+          while(tmp.length()<4) tmp.prepend("0");
+          dumpStr+=tmp+" ";
+        }
+      dumpStr.chop(1);
+      if(toAux)
+        {
+          logFilePtr->addToAux(dumpStr);
+        }
+      else
+        {
+          addToLog(dumpStr,LOGALL);
+        }
+    }
+  }
+  else
+  {
+    dumpStr=label+" ";
+    if(toAux) logFilePtr->addToAux(dumpStr);
+    else   addToLog(dumpStr,LOGALL);
+    for(i=0;i<len;i++)
+    {
+//      tmp=QString::number(data[i+j],16).right(4);
+      tmp=QString::number(data[i]).right(6);
+      if(toAux) logFilePtr->addToAux(tmp);
+      else   addToLog(tmp,LOGALL);
+    }
+  }
+}
+
+void arrayDump(QString label,int *data, unsigned int len,bool toAux)
+{
+  unsigned int i,j;
+  QString dumpStr,tmp;
+  for( i=0;i<len;i+=16)
+    {
+      dumpStr=label+" ";
+      for(j=0;(j<16)&&((i+j)<len);j++)
+        {
+          tmp=QString::number(data[i+j],16).right(4);
+          while(tmp.length()<4) tmp.prepend("0");
+          dumpStr+=tmp+" ";
+        }
+      dumpStr.chop(1);
+      if(toAux)
+        {
+          logFilePtr->addToAux(dumpStr);
+        }
+      else
+        {
+          addToLog(dumpStr,LOGALL);
+        }
+    }
+}
+
+void arrayDump(QString label,quint16 *data, unsigned int len,bool inHex,bool toAux)
+{
+  unsigned int i,j;
+  QString dumpStr,tmp;
+  for( i=0;i<len;i+=16)
+    {
+      dumpStr=label+" ";
+      for(j=0;(j<16)&&((i+j)<len);j++)
+        {
+          if(inHex)
+            {
+              tmp=QString::number(data[i+j],16);
+              while(tmp.length()<4) tmp.prepend("0");
+            }
+          else
+            {
+              tmp=QString::number(data[i+j]).rightJustified(5);
+            }
+          dumpStr+=tmp+" ";
+        }
+      dumpStr.chop(1);
+      if(toAux)
+        {
+          logFilePtr->addToAux(dumpStr);
+        }
+      else
+        {
+          addToLog(dumpStr,LOGALL);
+        }
+    }
+}
+
+void arrayDump(QString label, quint32* data, unsigned int len,bool inHex, bool toAux)
+{
+  unsigned int i,j;
+  QString dumpStr,tmp;
+  for( i=0;i<len;i+=16)
+    {
+      dumpStr=label+" ";
+      for(j=0;(j<16)&&((i+j)<len);j++)
+        {
+          if(inHex)
+            {
+              tmp=QString::number(data[i+j],16);
+              while(tmp.length()<8) tmp.prepend("0");
+            }
+          else
+            {
+              tmp=QString::number(data[i+j]).rightJustified(10);
+            }
+
+          dumpStr+=tmp+" ";
+        }
+      dumpStr.chop(1);
+      if(toAux)
+        {
+          logFilePtr->addToAux(dumpStr);
+        }
+      else
+        {
+          addToLog(dumpStr,LOGALL);
+        }
+    }
+}
+
+void arrayDump(QString label, float *data, unsigned int len, bool toAux, bool singleColumn)
+{
+  unsigned int i,j;
+  QString dumpStr,tmp;
+  if(!singleColumn)
+  {
+  for( i=0;i<len;i+=16)
+    {
+      dumpStr=label+" ";
+      for(j=0;(j<16)&&((i+j)<len);j++)
+        {
+          tmp=QString::number(data[i+j],'g',9).right(12);
+          while(tmp.length()<8) tmp.prepend(" ");
+          dumpStr+=tmp+" ";
+        }
+      dumpStr.chop(1);
+      if(toAux)
+        {
+          logFilePtr->addToAux(dumpStr);
+        }
+      else
+        {
+          addToLog(dumpStr,LOGALL);
+        }
+    }
+  }
+  else
+  {
+    dumpStr=label+" ";
+    if(toAux) logFilePtr->addToAux(dumpStr);
+    else   addToLog(dumpStr,LOGALL);
+    for(i=0;i<len;i++)
+    {
+      tmp=QString::number(data[i],'g',9).right(12);
+      if(toAux) logFilePtr->addToAux(tmp);
+      else   addToLog(tmp,LOGALL);
+    }
+  }
+}
+
+
+
+
+//void arrayComplexDump(QString label,CVectorEx<_COMPLEX> data,unsigned int len,bool toAux)
+//{
+//  CVectorEx<_COMPLEX> vct=data;
+//  _COMPLEX c;
+//  unsigned int i,j;
+////  unsigned int len;
+////  len=vct.Size()/8;
+//  QString dumpStr,tmp;
+
+//  for( i=0;i<len;i+=16)
+//    {
+//      dumpStr=label+" ";
+//      for(j=0;(j<16)&&((i+j)<len);j++)
+//        {
+//          c=vct[i+j];
+//          tmp=QString::number(c.real())+","+QString::number(c.imag());
+////          while(tmp.length()<2) tmp.prepend("0");
+//          dumpStr+=tmp+" ";
+//        }
+//      dumpStr.chop(1);
+//      if(toAux)
+//        {
+//          logFilePtr->addToAux(dumpStr);
+//        }
+//      else
+//        {
+//          addToLog(dumpStr,LOGALL);
+//        }
+//    }
+//}
+
+
+
+
+//void arrayBinDump(QString label,CVector<_BINARY> data,unsigned int len,bool toAux)
+//{
+//  CVector<_BINARY> vct=data;
+//  unsigned int i,j;
+////  unsigned int len;
+////  len=vct.Size()/8;
+//  QString dumpStr,tmp;
+
+//  for( i=0;i<len;i+=16)
+//    {
+//      dumpStr=label+" ";
+//      for(j=0;(j<16)&&((i+j)<len);j++)
+//        {
+//          tmp=QString::number(vct.Separate(8),16).right(2);
+//          while(tmp.length()<2) tmp.prepend("0");
+//          dumpStr+=tmp+" ";
+//        }
+//      dumpStr.chop(1);
+//      if(toAux)
+//        {
+//          logFilePtr->addToAux(dumpStr);
+//        }
+//      else
+//        {
+//          addToLog(dumpStr,LOGALL);
+//        }
+//    }
+//}
diff --git a/qsstv/utils/arraydumper.h b/qsstv/utils/arraydumper.h
new file mode 100644
index 0000000..1b4c5fe
--- /dev/null
+++ b/qsstv/utils/arraydumper.h
@@ -0,0 +1,14 @@
+#ifndef ARRAYDUMPER_H
+#define ARRAYDUMPER_H
+#include <QString>
+//#include "vector.h"
+
+void arrayDump(QString label, short int *data, unsigned int len, bool toAux, bool singleColumn);
+void arrayDump(QString label,quint16 *data, unsigned int len,bool inHex,bool toAux);
+void arrayDump(QString label, int *data, unsigned int len, bool toAux);
+void arrayDump(QString label, float *data, unsigned int len, bool toAux, bool singleColumn);
+void arrayDump(QString label, quint32 *data, unsigned int len, bool inHex, bool toAux);
+//void arrayBinDump(QString label, CVector<_BINARY> data, unsigned int len, bool toAux);
+//void arrayComplexDump(QString label,CVectorEx<_COMPLEX> data,unsigned int len,bool toAux);
+
+#endif // ARRAYDUMPER_H
diff --git a/qsstv/utils/buffermanag.h b/qsstv/utils/buffermanag.h
index 1809682..d836fcb 100644
--- a/qsstv/utils/buffermanag.h
+++ b/qsstv/utils/buffermanag.h
@@ -23,7 +23,7 @@
 #define BUFFERMANAG_H
 #include <string.h>
 #include <QMutex>
-#include "qsstvglobal.h"
+#include "appglobal.h"
 #include <QDebug>
 
 
@@ -32,8 +32,14 @@ template <class T,unsigned int N> class buffer
 public:
   buffer()
   {
+    memblock=new T[1<<N];
     reset();
   }
+  ~buffer()
+  {
+    delete [] memblock;
+  }
+
   unsigned int count()
   {
 
@@ -41,7 +47,6 @@ public:
   }
   unsigned int spaceLeft()
   {
-
     return ((1<<N)-count()-1);
   }
   unsigned int getBufferSize() {return (1<<N);}
@@ -173,6 +178,14 @@ public:
     mutex.unlock();
     return true;
   }
+
+  void setReadIndex(unsigned int idx)
+  {
+    idx&= ((1<<N)-1);
+    readIndex=idx;
+  }
+
+
   T at(unsigned int i)
   {
     i&=((1<<N)-1);
@@ -194,7 +207,7 @@ public:
   }
 
 private:
-  T memblock [1<<N];
+  T *memblock;
   unsigned int readIndex;
   unsigned int writeIndex;
   QMutex mutex;
diff --git a/qsstv/utils/color.cpp b/qsstv/utils/color.cpp
new file mode 100644
index 0000000..0f20784
--- /dev/null
+++ b/qsstv/utils/color.cpp
@@ -0,0 +1,777 @@
+/*
+ * The copyright in this software is being made available under the 2-clauses 
+ * BSD License, included below. This software may be subject to other third 
+ * party and contributor rights, including patent rights, and no such rights
+ * are granted under this license.
+ *
+ * Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2014, Professor Benoit Macq
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux 
+ * Copyright (c) 2003-2014, Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+#include <assert.h>
+
+//#include "opj_apps_config.h"
+#include "openjpeg-2.1/openjpeg.h"
+#include "color.h"
+
+
+/*--------------------------------------------------------
+Matrix for sYCC, Amendment 1 to IEC 61966-2-1
+
+Y :   0.299   0.587    0.114   :R
+Cb:  -0.1687 -0.3312   0.5     :G
+Cr:   0.5    -0.4187  -0.0812  :B
+
+Inverse:
+
+R: 1        -3.68213e-05    1.40199      :Y
+G: 1.00003  -0.344125      -0.714128     :Cb - 2^(prec - 1)
+B: 0.999823  1.77204       -8.04142e-06  :Cr - 2^(prec - 1)
+
+-----------------------------------------------------------*/
+static void sycc_to_rgb(int offset, int upb, int y, int cb, int cr,
+	int *out_r, int *out_g, int *out_b)
+{
+	int r, g, b;
+
+	cb -= offset; cr -= offset;
+	r = y + (int)(1.402 * (float)cr);
+	if(r < 0) r = 0; else if(r > upb) r = upb; *out_r = r;
+
+	g = y - (int)(0.344 * (float)cb + 0.714 * (float)cr);
+	if(g < 0) g = 0; else if(g > upb) g = upb; *out_g = g;
+
+	b = y + (int)(1.772 * (float)cb);
+	if(b < 0) b = 0; else if(b > upb) b = upb; *out_b = b;
+}
+
+static void sycc444_to_rgb(opj_image_t *img)
+{
+	int *d0, *d1, *d2, *r, *g, *b;
+	const int *y, *cb, *cr;
+	unsigned int maxw, maxh, max, i;
+	int offset, upb;
+
+	upb = (int)img->comps[0].prec;
+	offset = 1<<(upb - 1); upb = (1<<upb)-1;
+
+	maxw = (unsigned int)img->comps[0].w; maxh = (unsigned int)img->comps[0].h;
+	max = maxw * maxh;
+
+	y = img->comps[0].data;
+	cb = img->comps[1].data;
+	cr = img->comps[2].data;
+
+	d0 = r = (int*)malloc(sizeof(int) * (size_t)max);
+	d1 = g = (int*)malloc(sizeof(int) * (size_t)max);
+	d2 = b = (int*)malloc(sizeof(int) * (size_t)max);
+
+	for(i = 0U; i < max; ++i)
+	{
+		sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
+		++y; ++cb; ++cr; ++r; ++g; ++b;
+	}
+	free(img->comps[0].data); img->comps[0].data = d0;
+	free(img->comps[1].data); img->comps[1].data = d1;
+	free(img->comps[2].data); img->comps[2].data = d2;
+
+}/* sycc444_to_rgb() */
+
+static void sycc422_to_rgb(opj_image_t *img)
+{	
+	int *d0, *d1, *d2, *r, *g, *b;
+	const int *y, *cb, *cr;
+	unsigned int maxw, maxh, max;
+	int offset, upb;
+	unsigned int i, j;
+
+	upb = (int)img->comps[0].prec;
+	offset = 1<<(upb - 1); upb = (1<<upb)-1;
+
+	maxw = (unsigned int)img->comps[0].w; maxh = (unsigned int)img->comps[0].h;
+	max = maxw * maxh;
+
+	y = img->comps[0].data;
+	cb = img->comps[1].data;
+	cr = img->comps[2].data;
+
+	d0 = r = (int*)malloc(sizeof(int) * (size_t)max);
+	d1 = g = (int*)malloc(sizeof(int) * (size_t)max);
+	d2 = b = (int*)malloc(sizeof(int) * (size_t)max);
+
+	for(i=0U; i < maxh; ++i)
+	{
+		for(j=0U; j < (maxw & ~(unsigned int)1U); j += 2U)
+		{
+			sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
+			++y; ++r; ++g; ++b;
+			sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
+			++y; ++r; ++g; ++b; ++cb; ++cr;
+		}
+		if (j < maxw) {
+			sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
+			++y; ++r; ++g; ++b; ++cb; ++cr;
+		}
+	}
+	free(img->comps[0].data); img->comps[0].data = d0;
+	free(img->comps[1].data); img->comps[1].data = d1;
+	free(img->comps[2].data); img->comps[2].data = d2;
+
+#if defined(USE_JPWL) || defined(USE_MJ2)
+	img->comps[1].w = maxw; img->comps[1].h = maxh;
+	img->comps[2].w = maxw; img->comps[2].h = maxh;
+#else
+	img->comps[1].w = (OPJ_UINT32)maxw; img->comps[1].h = (OPJ_UINT32)maxh;
+	img->comps[2].w = (OPJ_UINT32)maxw; img->comps[2].h = (OPJ_UINT32)maxh;
+#endif
+	img->comps[1].dx = img->comps[0].dx;
+	img->comps[2].dx = img->comps[0].dx;
+	img->comps[1].dy = img->comps[0].dy;
+	img->comps[2].dy = img->comps[0].dy;
+
+}/* sycc422_to_rgb() */
+
+static void sycc420_to_rgb(opj_image_t *img)
+{
+	int *d0, *d1, *d2, *r, *g, *b, *nr, *ng, *nb;
+	const int *y, *cb, *cr, *ny;
+	unsigned int maxw, maxh, max;
+	int offset, upb;
+	unsigned int i, j;
+
+	upb = (int)img->comps[0].prec;
+	offset = 1<<(upb - 1); upb = (1<<upb)-1;
+
+	maxw = (unsigned int)img->comps[0].w; maxh = (unsigned int)img->comps[0].h;
+	max = maxw * maxh;
+
+	y = img->comps[0].data;
+	cb = img->comps[1].data;
+	cr = img->comps[2].data;
+
+	d0 = r = (int*)malloc(sizeof(int) * (size_t)max);
+	d1 = g = (int*)malloc(sizeof(int) * (size_t)max);
+	d2 = b = (int*)malloc(sizeof(int) * (size_t)max);
+
+	for(i=0U; i < (maxh & ~(unsigned int)1U); i += 2U)
+	{
+		ny = y + maxw;
+		nr = r + maxw; ng = g + maxw; nb = b + maxw;
+
+		for(j=0; j < (maxw & ~(unsigned int)1U); j += 2U)
+		{
+			sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
+			++y; ++r; ++g; ++b;
+			sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
+			++y; ++r; ++g; ++b;
+
+			sycc_to_rgb(offset, upb, *ny, *cb, *cr, nr, ng, nb);
+			++ny; ++nr; ++ng; ++nb;
+			sycc_to_rgb(offset, upb, *ny, *cb, *cr, nr, ng, nb);
+			++ny; ++nr; ++ng; ++nb; ++cb; ++cr;
+		}
+		if(j < maxw)
+		{
+			sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
+			++y; ++r; ++g; ++b;
+
+			sycc_to_rgb(offset, upb, *ny, *cb, *cr, nr, ng, nb);
+			++ny; ++nr; ++ng; ++nb; ++cb; ++cr;
+		}
+		y += maxw; r += maxw; g += maxw; b += maxw;
+	}
+	if(i < maxh)
+	{
+		for(j=0U; j < (maxw & ~(unsigned int)1U); j += 2U)
+		{
+			sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
+
+			++y; ++r; ++g; ++b;
+
+			sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
+
+			++y; ++r; ++g; ++b; ++cb; ++cr;
+		}
+		if(j < maxw)
+		{
+			sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
+		}
+	}
+
+	free(img->comps[0].data); img->comps[0].data = d0;
+	free(img->comps[1].data); img->comps[1].data = d1;
+	free(img->comps[2].data); img->comps[2].data = d2;
+
+#if defined(USE_JPWL) || defined(USE_MJ2)
+	img->comps[1].w = maxw; img->comps[1].h = maxh;
+	img->comps[2].w = maxw; img->comps[2].h = maxh;
+#else
+	img->comps[1].w = (OPJ_UINT32)maxw; img->comps[1].h = (OPJ_UINT32)maxh;
+	img->comps[2].w = (OPJ_UINT32)maxw; img->comps[2].h = (OPJ_UINT32)maxh;
+#endif
+	img->comps[1].dx = img->comps[0].dx;
+	img->comps[2].dx = img->comps[0].dx;
+	img->comps[1].dy = img->comps[0].dy;
+	img->comps[2].dy = img->comps[0].dy;
+
+}/* sycc420_to_rgb() */
+
+void color_sycc_to_rgb(opj_image_t *img)
+{
+	if(img->numcomps < 3)
+	{
+		img->color_space = OPJ_CLRSPC_GRAY;
+		return;
+	}
+
+	if((img->comps[0].dx == 1)
+	&& (img->comps[1].dx == 2)
+	&& (img->comps[2].dx == 2)
+	&& (img->comps[0].dy == 1)
+	&& (img->comps[1].dy == 2)
+	&& (img->comps[2].dy == 2))/* horizontal and vertical sub-sample */
+  {
+		sycc420_to_rgb(img);
+  }
+	else
+	if((img->comps[0].dx == 1)
+	&& (img->comps[1].dx == 2)
+	&& (img->comps[2].dx == 2)
+	&& (img->comps[0].dy == 1)
+	&& (img->comps[1].dy == 1)
+	&& (img->comps[2].dy == 1))/* horizontal sub-sample only */
+  {
+		sycc422_to_rgb(img);
+  }
+	else
+	if((img->comps[0].dx == 1)
+	&& (img->comps[1].dx == 1)
+	&& (img->comps[2].dx == 1)
+	&& (img->comps[0].dy == 1)
+	&& (img->comps[1].dy == 1)
+	&& (img->comps[2].dy == 1))/* no sub-sample */
+  {
+		sycc444_to_rgb(img);
+  }
+	else
+  {
+		fprintf(stderr,"%s:%d:color_sycc_to_rgb\n\tCAN NOT CONVERT\n", __FILE__,__LINE__);
+		return;
+  }
+	img->color_space = OPJ_CLRSPC_SRGB;
+
+}/* color_sycc_to_rgb() */
+
+#if defined(OPJ_HAVE_LIBLCMS2) || defined(OPJ_HAVE_LIBLCMS1)
+
+#ifdef OPJ_HAVE_LIBLCMS1
+/* Bob Friesenhahn proposed:*/
+#define cmsSigXYZData   icSigXYZData
+#define cmsSigLabData   icSigLabData
+#define cmsSigCmykData  icSigCmykData
+#define cmsSigYCbCrData icSigYCbCrData
+#define cmsSigLuvData   icSigLuvData
+#define cmsSigGrayData  icSigGrayData
+#define cmsSigRgbData   icSigRgbData
+#define cmsUInt32Number DWORD
+
+#define cmsColorSpaceSignature icColorSpaceSignature
+#define cmsGetHeaderRenderingIntent cmsTakeRenderingIntent
+
+#endif /* OPJ_HAVE_LIBLCMS1 */
+
+/*#define DEBUG_PROFILE*/
+void color_apply_icc_profile(opj_image_t *image)
+{
+	cmsHPROFILE in_prof, out_prof;
+	cmsHTRANSFORM transform;
+	cmsColorSpaceSignature in_space, out_space;
+	cmsUInt32Number intent, in_type, out_type, nr_samples;
+	int *r, *g, *b;
+	int prec, i, max, max_w, max_h;
+	OPJ_COLOR_SPACE oldspace;
+
+	in_prof = 
+	 cmsOpenProfileFromMem(image->icc_profile_buf, image->icc_profile_len);
+#ifdef DEBUG_PROFILE
+  FILE *icm = fopen("debug.icm","wb");
+  fwrite( image->icc_profile_buf,1, image->icc_profile_len,icm);
+  fclose(icm);
+#endif
+
+	if(in_prof == NULL) return;
+
+	in_space = cmsGetPCS(in_prof);
+	out_space = cmsGetColorSpace(in_prof);
+	intent = cmsGetHeaderRenderingIntent(in_prof);
+
+	
+	max_w = (int)image->comps[0].w;
+  max_h = (int)image->comps[0].h;
+	prec = (int)image->comps[0].prec;
+	oldspace = image->color_space;
+
+	if(out_space == cmsSigRgbData) /* enumCS 16 */
+   {
+	if( prec <= 8 )
+  {
+	in_type = TYPE_RGB_8;
+	out_type = TYPE_RGB_8;
+  }
+	else
+  {
+	in_type = TYPE_RGB_16;
+	out_type = TYPE_RGB_16;
+  }
+	out_prof = cmsCreate_sRGBProfile();
+	image->color_space = OPJ_CLRSPC_SRGB;
+   }
+	else
+	if(out_space == cmsSigGrayData) /* enumCS 17 */
+   {
+	in_type = TYPE_GRAY_8;
+	out_type = TYPE_RGB_8;
+	out_prof = cmsCreate_sRGBProfile();
+	image->color_space = OPJ_CLRSPC_SRGB;
+   }
+	else
+	if(out_space == cmsSigYCbCrData) /* enumCS 18 */
+   {
+	in_type = TYPE_YCbCr_16;
+	out_type = TYPE_RGB_16;
+	out_prof = cmsCreate_sRGBProfile();
+	image->color_space = OPJ_CLRSPC_SRGB;
+   }
+	else
+   {
+#ifdef DEBUG_PROFILE
+fprintf(stderr,"%s:%d: color_apply_icc_profile\n\tICC Profile has unknown "
+"output colorspace(%#x)(%c%c%c%c)\n\tICC Profile ignored.\n",
+__FILE__,__LINE__,out_space,
+	(out_space>>24) & 0xff,(out_space>>16) & 0xff,
+	(out_space>>8) & 0xff, out_space & 0xff);
+#endif
+	return;
+   }
+
+#ifdef DEBUG_PROFILE
+fprintf(stderr,"%s:%d:color_apply_icc_profile\n\tchannels(%d) prec(%d) w(%d) h(%d)"
+"\n\tprofile: in(%p) out(%p)\n",__FILE__,__LINE__,image->numcomps,prec,
+	max_w,max_h, (void*)in_prof,(void*)out_prof);
+
+fprintf(stderr,"\trender_intent (%u)\n\t"
+"color_space: in(%#x)(%c%c%c%c)   out:(%#x)(%c%c%c%c)\n\t"
+"       type: in(%u)              out:(%u)\n",
+	intent,
+	in_space,
+	(in_space>>24) & 0xff,(in_space>>16) & 0xff,
+	(in_space>>8) & 0xff, in_space & 0xff,
+
+	out_space,
+	(out_space>>24) & 0xff,(out_space>>16) & 0xff,
+	(out_space>>8) & 0xff, out_space & 0xff,
+
+	in_type,out_type
+ );
+#else
+  (void)prec;
+  (void)in_space;
+#endif /* DEBUG_PROFILE */
+
+	transform = cmsCreateTransform(in_prof, in_type,
+	 out_prof, out_type, intent, 0);
+
+#ifdef OPJ_HAVE_LIBLCMS2
+/* Possible for: LCMS_VERSION >= 2000 :*/
+	cmsCloseProfile(in_prof);
+	cmsCloseProfile(out_prof);
+#endif
+
+	if(transform == NULL)
+   {
+#ifdef DEBUG_PROFILE
+fprintf(stderr,"%s:%d:color_apply_icc_profile\n\tcmsCreateTransform failed. "
+"ICC Profile ignored.\n",__FILE__,__LINE__);
+#endif
+	image->color_space = oldspace;
+#ifdef OPJ_HAVE_LIBLCMS1
+	cmsCloseProfile(in_prof);
+	cmsCloseProfile(out_prof);
+#endif
+	return;
+   }
+
+	if(image->numcomps > 2)/* RGB, RGBA */
+   {
+	if( prec <= 8 )
+  {
+	unsigned char *inbuf, *outbuf, *in, *out;
+	max = max_w * max_h;
+	nr_samples = (cmsUInt32Number)max * 3 * (cmsUInt32Number)sizeof(unsigned char);
+	in = inbuf = (unsigned char*)malloc(nr_samples);
+	out = outbuf = (unsigned char*)malloc(nr_samples);
+
+	r = image->comps[0].data;
+	g = image->comps[1].data;
+	b = image->comps[2].data;
+
+	for(i = 0; i < max; ++i)
+ {
+	*in++ = (unsigned char)*r++;
+	*in++ = (unsigned char)*g++;
+	*in++ = (unsigned char)*b++;
+ }
+
+	cmsDoTransform(transform, inbuf, outbuf, (cmsUInt32Number)max);
+
+	r = image->comps[0].data;
+	g = image->comps[1].data;
+	b = image->comps[2].data;
+
+	for(i = 0; i < max; ++i)
+ {
+	*r++ = (int)*out++;
+	*g++ = (int)*out++;
+	*b++ = (int)*out++;
+ }
+	free(inbuf); free(outbuf);
+  }
+	else
+  {
+	unsigned short *inbuf, *outbuf, *in, *out;
+	max = max_w * max_h;
+	nr_samples = (cmsUInt32Number)max * 3 * (cmsUInt32Number)sizeof(unsigned short);
+	in = inbuf = (unsigned short*)malloc(nr_samples);
+	out = outbuf = (unsigned short*)malloc(nr_samples);
+
+	r = image->comps[0].data;
+	g = image->comps[1].data;
+	b = image->comps[2].data;
+
+	for(i = 0; i < max; ++i)
+ {
+	*in++ = (unsigned short)*r++;
+	*in++ = (unsigned short)*g++;
+	*in++ = (unsigned short)*b++;
+ }
+
+	cmsDoTransform(transform, inbuf, outbuf, (cmsUInt32Number)max);
+
+	r = image->comps[0].data;
+	g = image->comps[1].data;
+	b = image->comps[2].data;
+
+	for(i = 0; i < max; ++i)
+ {
+	*r++ = (int)*out++;
+	*g++ = (int)*out++;
+	*b++ = (int)*out++;
+ }
+	free(inbuf); free(outbuf);
+  }
+   }
+	else /* GRAY, GRAYA */
+   {
+	unsigned char *in, *inbuf, *out, *outbuf;
+	max = max_w * max_h;
+	nr_samples = (cmsUInt32Number)max * 3 * sizeof(unsigned char);
+	in = inbuf = (unsigned char*)malloc(nr_samples);
+	out = outbuf = (unsigned char*)malloc(nr_samples);
+
+	image->comps = (opj_image_comp_t*)
+	 realloc(image->comps, (image->numcomps+2)*sizeof(opj_image_comp_t));
+
+	if(image->numcomps == 2)
+	 image->comps[3] = image->comps[1];
+
+	image->comps[1] = image->comps[0];
+	image->comps[2] = image->comps[0];
+
+	image->comps[1].data = (int*)calloc((size_t)max, sizeof(int));
+	image->comps[2].data = (int*)calloc((size_t)max, sizeof(int));
+
+	image->numcomps += 2;
+
+	r = image->comps[0].data;
+
+	for(i = 0; i < max; ++i)
+  {
+	*in++ = (unsigned char)*r++;
+  }
+	cmsDoTransform(transform, inbuf, outbuf, (cmsUInt32Number)max);
+
+	r = image->comps[0].data;
+	g = image->comps[1].data;
+	b = image->comps[2].data;
+
+	for(i = 0; i < max; ++i)
+  {
+	*r++ = (int)*out++; *g++ = (int)*out++; *b++ = (int)*out++;
+  }
+	free(inbuf); free(outbuf);
+
+   }/* if(image->numcomps */
+
+	cmsDeleteTransform(transform);
+
+#ifdef OPJ_HAVE_LIBLCMS1
+	cmsCloseProfile(in_prof);
+	cmsCloseProfile(out_prof);
+#endif
+}/* color_apply_icc_profile() */
+
+void color_cielab_to_rgb(opj_image_t *image)
+{
+	int *row;
+	int enumcs, numcomps;
+	
+	image->color_space = OPJ_CLRSPC_SRGB;
+	
+	numcomps = (int)image->numcomps;
+	
+	if(numcomps != 3)
+	{
+		fprintf(stderr,"%s:%d:\n\tnumcomps %d not handled. Quitting.\n",
+						__FILE__,__LINE__,numcomps);
+		return;
+	}
+	
+	row = (int*)image->icc_profile_buf;
+	enumcs = row[0];
+	
+	if(enumcs == 14) /* CIELab */
+	{
+		int *L, *a, *b, *red, *green, *blue;
+		int *src0, *src1, *src2, *dst0, *dst1, *dst2;
+		double rl, ol, ra, oa, rb, ob, prec0, prec1, prec2;
+		double minL, maxL, mina, maxa, minb, maxb;
+		unsigned int default_type;
+		unsigned int i, max;
+		cmsHPROFILE in, out;
+		cmsHTRANSFORM transform;
+		cmsUInt16Number RGB[3];
+		cmsCIELab Lab;
+		
+		in = cmsCreateLab4Profile(NULL);
+		out = cmsCreate_sRGBProfile();
+		
+		transform = cmsCreateTransform(in, TYPE_Lab_DBL, out, TYPE_RGB_16, INTENT_PERCEPTUAL, 0);
+		
+#ifdef OPJ_HAVE_LIBLCMS2
+		cmsCloseProfile(in);
+		cmsCloseProfile(out);
+#endif
+		if(transform == NULL)
+		{
+#ifdef OPJ_HAVE_LIBLCMS1
+			cmsCloseProfile(in);
+			cmsCloseProfile(out);
+#endif
+			return;
+		}
+		prec0 = (double)image->comps[0].prec;
+		prec1 = (double)image->comps[1].prec;
+		prec2 = (double)image->comps[2].prec;
+		
+		default_type = (unsigned int)row[1];
+		
+		if(default_type == 0x44454600)/* DEF : default */
+		{
+			rl = 100; ra = 170; rb = 200;
+			ol = 0;
+			oa = pow(2, prec1 - 1);
+			ob = pow(2, prec2 - 2) +  pow(2, prec2 - 3);
+		}
+		else
+		{
+			rl = row[2]; ra = row[4]; rb = row[6];
+			ol = row[3]; oa = row[5]; ob = row[7];
+		}
+		
+		L = src0 = image->comps[0].data;
+		a = src1 = image->comps[1].data;
+		b = src2 = image->comps[2].data;
+		
+		max = image->comps[0].w * image->comps[0].h;
+		
+		red = dst0 = (int*)malloc(max * sizeof(int));
+		green = dst1 = (int*)malloc(max * sizeof(int));
+		blue = dst2 = (int*)malloc(max * sizeof(int));
+		
+		minL = -(rl * ol)/(pow(2, prec0)-1);
+		maxL = minL + rl;
+		
+		mina = -(ra * oa)/(pow(2, prec1)-1);
+		maxa = mina + ra;
+		
+		minb = -(rb * ob)/(pow(2, prec2)-1);
+		maxb = minb + rb;
+		
+		for(i = 0; i < max; ++i)
+		{
+			Lab.L = minL + (double)(*L) * (maxL - minL)/(pow(2, prec0)-1); ++L;
+			Lab.a = mina + (double)(*a) * (maxa - mina)/(pow(2, prec1)-1); ++a;
+			Lab.b = minb + (double)(*b) * (maxb - minb)/(pow(2, prec2)-1); ++b;
+		
+			cmsDoTransform(transform, &Lab, RGB, 1);
+		
+			*red++ = RGB[0];
+			*green++ = RGB[1];
+			*blue++ = RGB[2];
+		}
+		cmsDeleteTransform(transform);
+#ifdef OPJ_HAVE_LIBLCMS1
+		cmsCloseProfile(in);
+		cmsCloseProfile(out);
+#endif
+		free(src0); image->comps[0].data = dst0;
+		free(src1); image->comps[1].data = dst1;
+		free(src2); image->comps[2].data = dst2;
+		
+		image->color_space = OPJ_CLRSPC_SRGB;
+		image->comps[0].prec = 16;
+		image->comps[1].prec = 16;
+		image->comps[2].prec = 16;
+		
+		return;
+	}
+	
+	fprintf(stderr,"%s:%d:\n\tenumCS %d not handled. Ignoring.\n", __FILE__,__LINE__, enumcs);
+}/* color_apply_conversion() */
+
+#endif /* OPJ_HAVE_LIBLCMS2 || OPJ_HAVE_LIBLCMS1 */
+
+void color_cmyk_to_rgb(opj_image_t *image)
+{
+	float C, M, Y, K;
+	float sC, sM, sY, sK;
+	unsigned int w, h, max, i;
+
+	w = image->comps[0].w;
+	h = image->comps[0].h;
+
+	if(image->numcomps < 4) return;
+
+	max = w * h;
+	
+	sC = 1.0F / (float)((1 << image->comps[0].prec) - 1);
+	sM = 1.0F / (float)((1 << image->comps[1].prec) - 1);
+	sY = 1.0F / (float)((1 << image->comps[2].prec) - 1);
+	sK = 1.0F / (float)((1 << image->comps[3].prec) - 1);
+
+	for(i = 0; i < max; ++i)
+	{
+		/* CMYK values from 0 to 1 */
+		C = (float)(image->comps[0].data[i]) * sC;
+		M = (float)(image->comps[1].data[i]) * sM;
+		Y = (float)(image->comps[2].data[i]) * sY;
+		K = (float)(image->comps[3].data[i]) * sK;
+		
+		/* Invert all CMYK values */
+		C = 1.0F - C;
+		M = 1.0F - M;
+		Y = 1.0F - Y;
+		K = 1.0F - K;
+
+		/* CMYK -> RGB : RGB results from 0 to 255 */
+		image->comps[0].data[i] = (int)(255.0F * C * K); /* R */
+		image->comps[1].data[i] = (int)(255.0F * M * K); /* G */
+		image->comps[2].data[i] = (int)(255.0F * Y * K); /* B */
+	}
+
+	free(image->comps[3].data); image->comps[3].data = NULL;
+	image->comps[0].prec = 8;
+	image->comps[1].prec = 8;
+	image->comps[2].prec = 8;
+	image->numcomps -= 1;
+	image->color_space = OPJ_CLRSPC_SRGB;
+	
+	for (i = 3; i < image->numcomps; ++i) {
+		memcpy(&(image->comps[i]), &(image->comps[i+1]), sizeof(image->comps[i]));
+	}
+
+}/* color_cmyk_to_rgb() */
+
+/*
+ * This code has been adopted from sjpx_openjpeg.c of ghostscript
+ */
+void color_esycc_to_rgb(opj_image_t *image)
+{
+	int y, cb, cr, sign1, sign2, val;
+	unsigned int w, h, max, i;
+	int flip_value = (1 << (image->comps[0].prec-1));
+	int max_value = (1 << image->comps[0].prec) - 1;
+	
+	if(image->numcomps < 3) return;
+	
+	w = image->comps[0].w;
+	h = image->comps[0].h;
+	
+	sign1 = (int)image->comps[1].sgnd;
+	sign2 = (int)image->comps[2].sgnd;
+	
+	max = w * h;
+	
+	for(i = 0; i < max; ++i)
+	{
+		
+		y = image->comps[0].data[i]; cb = image->comps[1].data[i]; cr = image->comps[2].data[i];
+		
+		if( !sign1) cb -= flip_value;
+		if( !sign2) cr -= flip_value;
+		
+		val = (int)
+		((float)y - (float)0.0000368 * (float)cb
+		 + (float)1.40199 * (float)cr + (float)0.5);
+		
+		if(val > max_value) val = max_value; else if(val < 0) val = 0;
+		image->comps[0].data[i] = val;
+		
+		val = (int)
+		((float)1.0003 * (float)y - (float)0.344125 * (float)cb
+		 - (float)0.7141128 * (float)cr + (float)0.5);
+		
+		if(val > max_value) val = max_value; else if(val < 0) val = 0;
+		image->comps[1].data[i] = val;
+		
+		val = (int)
+		((float)0.999823 * (float)y + (float)1.77204 * (float)cb
+		 - (float)0.000008 *(float)cr + (float)0.5);
+		
+		if(val > max_value) val = max_value; else if(val < 0) val = 0;
+		image->comps[2].data[i] = val;
+	}
+	image->color_space = OPJ_CLRSPC_SRGB;
+
+}/* color_esycc_to_rgb() */
diff --git a/qsstv/utils/color.h b/qsstv/utils/color.h
new file mode 100644
index 0000000..0cd78e8
--- /dev/null
+++ b/qsstv/utils/color.h
@@ -0,0 +1,47 @@
+/*
+ * The copyright in this software is being made available under the 2-clauses 
+ * BSD License, included below. This software may be subject to other third 
+ * party and contributor rights, including patent rights, and no such rights
+ * are granted under this license.
+ *
+ * Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2014, Professor Benoit Macq
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux 
+ * Copyright (c) 2003-2014, Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _OPJ_COLOR_H_
+#define _OPJ_COLOR_H_
+
+extern void color_sycc_to_rgb(opj_image_t *img);
+extern void color_apply_icc_profile(opj_image_t *image);
+extern void color_cielab_to_rgb(opj_image_t *image);
+
+extern void color_cmyk_to_rgb(opj_image_t *image);
+extern void color_esycc_to_rgb(opj_image_t *image);
+#endif /* _OPJ_COLOR_H_ */
diff --git a/qsstv/utils/dirdialog.cpp b/qsstv/utils/dirdialog.cpp
new file mode 100644
index 0000000..e746be7
--- /dev/null
+++ b/qsstv/utils/dirdialog.cpp
@@ -0,0 +1,114 @@
+#include "dirdialog.h"
+#include <QDir>
+#include <QFileDialog>
+
+static QString lastPath;
+
+dirDialog::dirDialog(QWidget * parent,QString title)
+{
+  parentPtr=parent;
+  dialogTitle=title;
+}
+
+dirDialog::~dirDialog()
+{
+}
+
+
+/*!
+    \fn dirDialog::openFileName(const QString &path, const QString &filter, bool single)
+    \brief selection of a file
+
+    \param path  directory to open (preselected) if empty, the last accessed directory will be used
+    \param filter  types to select from (e.g. mydirs*)
+    \param single  allows selection of more than one file if true
+    \return if canceled or no selection then returns an empty string else return string containing absolute filename
+*/
+
+
+QString dirDialog::openFileName(const QString &path, const QString &filter)
+{
+  QString fn;
+  if (path.isEmpty() && lastPath.isEmpty())
+    {
+      lastPath=QDir::homePath();
+    }
+  else if (!path.isEmpty())
+    {
+      lastPath=path;
+    }
+
+  fn=QFileDialog::getOpenFileName(parentPtr,dialogTitle,lastPath,filter);
+  if(!fn.isEmpty())
+    {
+      QFileInfo  fi(fn);
+      lastPath=fi.absolutePath();
+    }
+  return fn;
+}
+
+/*!
+    \fn dirDialog::openDirName(const QString &path, const QString &filter)
+    \brief selection of a directory
+
+    \param path directory to open (preselected)
+    \param filter    types to select from (e.g. mydirs*)
+
+    \return if canceled or no selection then return an empty string else return string containing absolute dirname
+*/
+
+QString dirDialog::openDirName(const QString &path)
+{
+  QString fn;
+  if ((path.isEmpty()) && lastPath.isEmpty())
+    {
+      lastPath=QDir::homePath();
+    }
+  else if (!path.isEmpty())
+    {
+      lastPath=path;
+    }
+  fn=QFileDialog::getExistingDirectory(parentPtr,dialogTitle,lastPath);
+  if(!fn.isEmpty())
+    {
+      lastPath=fn;
+    }
+  return fn;
+}
+
+/*!
+    \fn dirDialog::saveFileName(const QString &path, const QString &filter,QString extension)
+    \brief Save a file to disk
+
+    Saves a file to disk. A dialogbox is opened with \a startWith directory (or /dir/subdir/..../filename) preselected
+    \param path directory to open (can include filename to preselect)
+    \param filter    file types to select from (e.g. *.txt *.doc)
+    \param extension if extension is not empty or NULL, thenn this string will be appended to the filename. A dot will automatically be insterted (i.e specify "txt" not ".txt").
+    \return if canceled or no selection then return an empty string else return string containing absolute filename.
+*/
+
+QString dirDialog::saveFileName(const QString &path, const QString &filter, QString extension)
+{
+  QString fn;
+  if ((path.isEmpty()) && lastPath.isEmpty())
+    {
+      lastPath=QDir::currentPath();
+    }
+  else if (!path.isEmpty())
+    {
+      lastPath=path;
+    }
+  QString exten(extension);
+  fn=QFileDialog::getSaveFileName(parentPtr,dialogTitle,lastPath,filter);
+  if(fn.isEmpty()) return fn;
+  QFileInfo  fi(fn);
+  if(!exten.isEmpty())
+    {
+      if(fi.suffix()=="")
+        {
+          fi.setFile(fi.absoluteFilePath()+"."+exten);
+        }
+    }
+  lastPath=fi.absolutePath();
+  return fi.absoluteFilePath();
+}
diff --git a/qsstv/utils/dirdialog.h b/qsstv/utils/dirdialog.h
new file mode 100644
index 0000000..249ae84
--- /dev/null
+++ b/qsstv/utils/dirdialog.h
@@ -0,0 +1,19 @@
+#ifndef DIRDIALOG_H
+#define DIRDIALOG_H
+#include <QWidget>
+#include <QString>
+
+class dirDialog
+{
+public:
+    dirDialog(QWidget *parent,QString title="");
+    ~dirDialog();
+    QString openFileName(const QString &startWith, const QString &filter="*");
+    QString openDirName(const QString &path);
+    QString saveFileName(const QString &path, const QString &filter,QString extension);
+private:
+    QWidget * parentPtr;
+    QString  dialogTitle;
+};
+
+#endif // DIRDIALOG_H
diff --git a/qsstv/utils/fftcalc.cpp b/qsstv/utils/fftcalc.cpp
new file mode 100644
index 0000000..6ead36c
--- /dev/null
+++ b/qsstv/utils/fftcalc.cpp
@@ -0,0 +1,65 @@
+#include "fftcalc.h"
+
+fftCalc::fftCalc()
+{
+  plan=NULL;
+  out=NULL;
+  dataBuffer=NULL;
+}
+
+fftCalc::~fftCalc()
+{
+  if(plan)fftw_destroy_plan(plan);
+  if(out) fftw_free(out);
+  if(dataBuffer) fftw_free(dataBuffer);
+}
+
+void fftCalc::init(int length,int nblocks,int isamplingrate)
+{
+  windowSize=length;
+  fftLength=windowSize*nblocks;
+  blocks=nblocks;
+  blockIndex=0;
+  createHamming();
+  samplingrate=isamplingrate;
+  //prepare fft
+  if(plan)fftw_destroy_plan(plan);
+  if(out) fftw_free(out);
+  if(dataBuffer) fftw_free(dataBuffer);
+  out =         (double *)fftw_malloc(fftLength * sizeof(double));
+  dataBuffer  = (double *)fftw_malloc(fftLength * sizeof(double));
+  // create the fftw plan
+  plan = fftw_plan_r2r_1d(fftLength, dataBuffer, out, FFTW_R2HC, FFTW_ESTIMATE);
+}
+
+void fftCalc::createHamming()
+{
+  int i;
+  hammingBuffer= new double[fftLength];
+  for(i=0;i<fftLength;i++)
+    {
+      hammingBuffer[i]=0.54-(0.46*cos(2*M_PI*((double)i/((double)(fftLength-1)))));
+    }
+
+}
+
+void fftCalc::realFFT(double *data)
+{
+  int i,j;
+  for(i=0,j=windowSize*blockIndex;i<windowSize;i++,j++)
+    {
+      dataBuffer[j]=data[i]*hammingBuffer[i];
+
+    }
+  doFFT();
+}
+
+void fftCalc::doFFT()
+{
+  blockIndex++;
+  if(blockIndex<blocks) return;
+  blockIndex=0;
+  fftw_execute(plan);
+}
+
+
diff --git a/qsstv/utils/fftcalc.h b/qsstv/utils/fftcalc.h
new file mode 100644
index 0000000..78e2e08
--- /dev/null
+++ b/qsstv/utils/fftcalc.h
@@ -0,0 +1,27 @@
+#ifndef FFTCALC_H
+#define FFTCALC_H
+#include <fftw3.h>
+#include <math.h>
+
+class fftCalc
+{
+public:
+  fftCalc();
+  ~fftCalc();
+  void init(int length,int nblocks,int isamplingrate);
+  void realFFT(double *data);
+  double *out;
+private:
+  void createHamming();
+  void doFFT();
+  double *hammingBuffer;
+  double *dataBuffer;
+  int windowSize;
+  int fftLength;
+  int samplingrate;
+  unsigned int blocks;
+  unsigned int blockIndex;
+  fftw_plan plan;
+};
+
+#endif // FFTCALC_H
diff --git a/qsstv/utils/ftp.cpp b/qsstv/utils/ftp.cpp
index 226b859..c4e0301 100644
--- a/qsstv/utils/ftp.cpp
+++ b/qsstv/utils/ftp.cpp
@@ -18,40 +18,42 @@
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 #include "ftp.h"
-#include "qsstvglobal.h"
-//#include <qmessagebox.h>
-#include <qfiledialog.h>
+#include "appglobal.h"
+#include "dispatch/dispatcher.h"
+
+//#include <qfiledialog.h>
 
 #include <qapplication.h>
 #include "configparams.h"
+
 #include <QDebug>
-#include "dispatcher.h"
+#include <QTemporaryFile>
+#include <string.h>
+#include <errno.h>
+
 #define FTPTIMEOUTTIME 12000
 
 ftpInterface::ftpInterface(QString id)
 {
   ftp=NULL;
+  addToLog(id, LOGFTP);
   name=id;
   sourceFn=NULL;
   init();
-
 }
 
 ftpInterface::~ftpInterface()
 {
-  addToLog("FTP destroy in delete",LOGFTP);
+  addToLog(QString("'%1' FTP destroy in delete").arg(name),LOGFTP);
   destroy();
-  if(ftp) delete ftp;
-
+  if (ftp) delete ftp;
 }
 
 void ftpInterface::init()
 {
-  if(ftp)
-    {
-      destroy();
-      delete ftp;
-    }
+  destroy();
+  if(ftp) delete ftp;
+  addToLog(QString("FTP init '%1'").arg(name), LOGFTP);
   ftp = new QFtp( 0);
   connect( ftp, SIGNAL(commandStarted(int)),SLOT(ftp_commandStarted(int)) );
   connect( ftp, SIGNAL(commandFinished(int,bool)),SLOT(ftp_commandFinished(int,bool)) );
@@ -60,70 +62,67 @@ void ftpInterface::init()
   connect( ftp, SIGNAL(listInfo(const QUrlInfo &)),SLOT(ftp_listInfo(const QUrlInfo &)) );
   connect( ftp, SIGNAL(rawCommandReply(int, const QString &)),SLOT(ftp_rawCommandReply(int, const QString &)) );
   connect( ftp, SIGNAL(dataTransferProgress(qint64,qint64)),SLOT(slotProgress(qint64,qint64)) );
-  //    connect( progress, SIGNAL(canceled()), SLOT(slotAbort()) );
 }
 
 void ftpInterface::destroy()
 {
-  addToLog("FTP show state in destroy",LOGFTP);
-  ftp_stateChanged(ftp->state());
-  if ( ftp->state() != QFtp::Unconnected )
+  mremove_listids.clear();
+  listingResults.clear();
+  notifyId=-1;
+  ftpDone=true;
+  if(ftp)
     {
-
-      addToLog("FTP destroy",LOGFTP);
-      ftp->close();
+      addToLog("FTP show state in destroy",LOGFTP);
+      ftp_stateChanged(ftp->state());
+      if( ftp->state() != QFtp::Unconnected ) 
+        {
+          addToLog(QString("Closing '%1' to %2").arg(name).arg(host),LOGFTP);
+          ftp->close();
+        }
     }
 }
 
+void ftpInterface::setupConnection(QString tHost,int tPort,QString tUser,QString tPasswd,QString tDirectory)
+{
+    addToLog(QString("'%1' host %2").arg(name).arg(tHost), LOGFTP);
+    if(host!=tHost || user!=tUser || passwd!=tPasswd || port!=tPort || directory!=tDirectory)
+      {
+        if (ftp) destroy();
+      }
+    host=tHost;
+    user=tUser;
+    passwd=tPasswd;
+    directory=tDirectory;
+    port=tPort;
+}
+
 eftpError ftpInterface::doConnect()
 {
-  ftpDone=true;
   aborting=false;
-  addToLog(QString("FTP doConnect"),LOGFTP);
-  dumpState();
-  if(isUnconnected())
+  addToLog(QString("'%1' to %2").arg(name).arg(host),LOGFTP);
+  //dumpState();
+  
+  // if !ftpDone then we've had at least one command issued, which means
+  // that first command caused doConnect() to run and call connectToHost()
+  // if !isUnconnected() then the connection has already been established.
+  if(isUnconnected() && ftpDone)
     {
       addToLog(QString("FTP connect to host %1").arg(host),LOGFTP);
-      ftpDone=false;
       connectToHost();
     }
   else
     {
       addToLog(QString("FTP already connected to host %1").arg(host),LOGFTP);
     }
-  tim.setSingleShot(true);
-  tim.start(FTPTIMEOUTTIME);
-  while(!ftpDone)
-    {
-      if(aborting)
-        {
-
-          return FTPCANCELED;
-        }
-      qApp->processEvents();
-      if(!tim.isActive())
-        {
-          slotAbort();
-          addToLog("ftp Timeout",LOGALL);
-          return FTPTIMEOUT;
-        }
-    }
-  tim.stop();
-  if(!ftpCommandSuccess)
-    {
-      addToLog("FTP not connected",LOGFTP);
-      return FTPERROR;
-    }
-  addToLog(QString("FTP connected to %1").arg(host),LOGFTP);
   return FTPOK;
 }
 
 
 eftpError ftpInterface::uploadFile(QString fileName,QString targetFilename,bool reconnect)
 {
-  int id;
+//  int id;
   eftpError result;
-  addToLog("FTP uploadFile",LOGFTP);
+  addToLog("uploadFile",LOGFTP);
   if ( fileName.isNull() )  return FTPNAMEERROR;
   if(reconnect)
     {
@@ -140,28 +139,41 @@ eftpError ftpInterface::uploadFile(QString fileName,QString targetFilename,bool
     }
   QFileInfo fi( fileName );
   QFileInfo fin(targetFilename);
-  addToLog(QString("FTP bytes: %1").arg(sourceFn->size()),LOGFTP);
+  addToLog(QString("'%1' put '%2', %3 bytes").arg(name).arg(targetFilename).arg(sourceFn->size()),LOGFTP);
 
   ftpDone=false;
   if(fin.fileName().isEmpty())
     {
-      id=ftp->put( sourceFn, fi.fileName(),QFtp::Binary);
+      ftp->put( sourceFn, fi.fileName(),QFtp::Binary);
     }
   else
     {
-      id=ftp->put( sourceFn, fin.fileName(),QFtp::Binary);
-    }
-  addToLog(QString("FTP put file id: %1").arg(id),LOGFTP);
-  while(!ftpDone)
-    {
-      if(aborting) return FTPCANCELED;
-      qApp->processEvents();
+      ftp->put( sourceFn, fin.fileName(),QFtp::Binary);
     }
-  if(!ftpCommandSuccess) return FTPERROR;
+//  addToLog(QString("FTP put file id: %1").arg(id),LOGFTP);
+  result = wait(-3);
+  if (result!=FTPOK) return result;
   addToLog("FTP starting progress",LOGFTP);
   return FTPOK;
 }
 
+eftpError ftpInterface::uploadData(const QByteArray & data,QString targetFilename)
+{
+  int id;
+  Q_UNUSED(id)
+  eftpError result;
+
+  QFileInfo fin(targetFilename);
+  if(fin.fileName().isEmpty()) return FTPNAMEERROR;
+
+  result=doConnect();
+  if(result!=FTPOK) return result;
+
+  ftpDone=false;
+  id=ftp->put( data,fin.fileName(),QFtp::Binary);
+  addToLog(QString("'%1' '%2', %3 bytes, id:%4").arg(name).arg(targetFilename).arg(data.size()).arg(id),LOGFTP);
+  return FTPOK;
+}
 
 eftpError ftpInterface::downloadFile(QString sourceFileName,QString destinationFilename)
 {
@@ -175,37 +187,153 @@ eftpError ftpInterface::downloadFile(QString sourceFileName,QString destinationF
       return FTPNAMEERROR;
     }
 
-
   if (sourceFileName.isNull() )  return FTPNAMEERROR;
   result=doConnect();
   if(result!=FTPOK) return result;
   ftpDone=false;
+  addToLog(QString("'%1' get '%2' destination '%3'").arg(name).arg(sourceFileName).arg(destFn->fileName()),LOGFTP);
   ftp->get( sourceFileName, destFn,QFtp::Binary);
-  addToLog(QString("FTP get sourcefile %1 destination %2").arg(sourceFileName).arg(destFn->fileName()),LOGFTP);
-  while(!ftpDone)
+  result = wait(-3);
+  if(result!=FTPOK) return result;
+  addToLog(QString("FTP file: %1 bytes: %2").arg(destinationFilename).arg(QFile(destinationFilename).size()),LOGFTP);
+  return FTPOK;
+}
+
+
+eftpError ftpInterface::wait(int timeout)
+{
+  if (timeout < 0) timeout = FTPTIMEOUTTIME - (0-timeout);
+  if (timeout) {
+     tim.setSingleShot(true);
+     tim.setInterval(timeout);
+     tim.start();
+     }
+     
+  while (!ftpDone)
     {
       if(aborting) return FTPCANCELED;
       qApp->processEvents();
+      if(timeout && !tim.isActive())
+        {
+          slotAbort();
+          addToLog(QString("'%1' Timeout (%2ms) Host:%3 ").arg(name).arg(timeout).arg(host),LOGALL);
+          return FTPTIMEOUT;
+        }
     }
+  if (timeout) tim.stop();
   if(!ftpCommandSuccess) return FTPERROR;
-  addToLog(QString("FTP file: %1 bytes: %2").arg(destinationFilename).arg(QFile(destinationFilename).size()),LOGFTP);
   return FTPOK;
 }
 
+eftpError ftpInterface::remove(QString path)
+{
+  int id;
+  Q_UNUSED(id)
+  eftpError result=doConnect();
+  if(result!=FTPOK) return result;
+
+  ftpDone=false;
+  id = ftp->remove(path);
+  addToLog(QString("'%1' Name='%2'  id:%3").arg(name).arg(path).arg(id),LOGFTP);
+  return FTPOK;
+}
+
+eftpError ftpInterface::mremove(QString path)
+{
+  int id;
+  Q_UNUSED(id)
+  eftpError result;
+  addToLog(QString("FTP mremove"),LOGFTP);
+
+  result=doConnect();
+  if(result!=FTPOK) return result;
+
+  ftpDone=false;
+  id = ftp->list(path);
+  if (id>0) mremove_listids.append(id);
+  addToLog(QString("'%1' Path='%2'  id=%3").arg(name).arg(path).arg(id),LOGFTP);
+  return FTPOK;  
+}
+
+eftpError ftpInterface::getListing(QString path)
+{
+  int id;
+  Q_UNUSED(id)
+  eftpError result;
+  addToLog("FTP getListing",LOGFTP);
+
+  result=doConnect();
+  if(result!=FTPOK) return result;
+  ftpDone=false;
+  id = ftp->list(path);
+  addToLog(QString("'%1' Path='%2'  id:%3").arg(name).arg(path).arg(id),LOGFTP);
+  return FTPOK;  
+}
+
+QList <QUrlInfo> ftpInterface::getListingResults()
+{
+  return listingResults;
+}
+
+void ftpInterface::clearListingResults()
+{
+  listingResults.clear();
+}
+
+
+eftpError ftpInterface::startNotifyCheck(QString fn, int interval, int repeats, bool rm)
+{
+  addToLog(QString("'%1' startNotifyCheck(%2,%3,%4,%5)").arg(name).arg(fn).arg(interval).arg(repeats).arg(rm),LOGNOTIFY);
+  notifyMask    = "Dummy"+fn+"+++*";
+  notifyTicks   = -1;
+  notifyRepeats = repeats;
+  notifyRemove  = rm;
+  
+  notifyList.clear();
+  
+  notifyTimer.setSingleShot(false);
+  notifyTimer.setInterval(interval*1000);
+  connect(&notifyTimer, SIGNAL(timeout()), this, SLOT(notifyTick()));
+  notifyTimer.start();
+  notifyTick();  
+  return FTPOK;
+}
+
+void ftpInterface::notifyTick()
+{
+   // runs once every interval seconds
+   notifyTicks++;
+   addToLog(QString("'%1': ticks=%2  notifyid=%3").arg(name).arg(notifyTicks).arg(notifyId), LOGNOTIFY);
+   if (notifyTicks>notifyRepeats)
+   {
+      notifyTimer.stop();
+   }
+   else if (notifyId<0)
+   {
+      eftpError result=doConnect();
+      if (result==FTPOK)
+      {
+         ftpDone=false;
+         notifyId = ftp->list(notifyMask);
+      }
+   }
+}
 
 void ftpInterface::connectToHost()
 {
+  addToLog(QString("'%1' connectToHost %2").arg(name).arg(host), LOGFTP);
   destroy();
+  ftpDone=false;
   ftp->connectToHost(host,port);
   ftp->login( user, passwd );
   if(!directory.isEmpty()) changePath(directory);
-  //    qDebug() << QString("connecting to host %1,%2,%3,%4").arg(host).arg(port).arg(user).arg(passwd);
 }
 
 // This slot is connected to the QComboBox::activated() signal of the
 // remotePath.
 void ftpInterface::changePath( const QString &newPath )
 {
+  directory=newPath;
   ftp->cd( newPath );
 }
 
@@ -218,19 +346,22 @@ void ftpInterface::changePath( const QString &newPath )
 
 void ftpInterface::ftp_commandStarted(int id)
 {
-  addToLog(QString("FTP commandStarted id:%1, %2").arg(id).arg(ftp->currentCommand()),LOGFTP);
+  Q_UNUSED(id);
+  addToLog(QString("'%1' id:%2, %3").arg(name).arg(id).arg(ftp->currentCommand()),LOGFTP);
   if ( ftp->currentCommand() == QFtp::List )
     {
     }
+  if (tim.isActive()) tim.start();
 }
 
 void ftpInterface::ftp_commandFinished(int id,bool err)
 {
+  Q_UNUSED(id);
   QIODevice *p;
 
   slotProgress(0,0);
 
-  addToLog(QString("FTP commandFinished id:%1, error:%2").arg(id).arg(err),LOGFTP);
+  addToLog(QString("'%1' id:%2, error:%3").arg(name).arg(id).arg(err),LOGFTP);
   if(err)
     {
       addToLog(QString("FTP error:%1").arg(ftp->errorString()),LOGFTP);
@@ -241,7 +372,9 @@ void ftpInterface::ftp_commandFinished(int id,bool err)
       ftpCommandSuccess=true;
     }
 
-
+  mremove_listids.removeOne(id);
+  if (id==notifyId) notifyId=-1;
+  
   p=ftp->currentDevice();
   if(p)
     {
@@ -263,17 +396,18 @@ void ftpInterface::ftp_done( bool error )
       // failed).
       if(!isLoggedIn())
         {
-          addToLog("FTP done:  error and not logged in-> disconnecting",LOGFTP);
+          addToLog(QString("'%1': error and not logged in-> disconnecting").arg(host),LOGFTP);
           destroy();
           ftpDone=true;
           return;
         }
-      addToLog("FTP done:  error",LOGFTP);
+      addToLog(QString("'%1': error").arg(host),LOGFTP);
     }
   else
     {
-      addToLog("FTP done:  no error",LOGFTP);
+      addToLog(QString("'%1': OK").arg(host),LOGFTP);
     }
+  mremove_listids.clear();
   ftpDone=true;
 }
 
@@ -287,6 +421,11 @@ bool ftpInterface::isUnconnected()
   return ftp->state() == QFtp::Unconnected;
 }
 
+bool ftpInterface::isBusy()
+{
+  return !ftpDone;
+}
+
 void ftpInterface::ftp_stateChanged( int )
 {
   dumpState();
@@ -298,36 +437,61 @@ void ftpInterface::dumpState()
     {
     case QFtp::Unconnected:
       addToLog(QString("FTPss Unconnected name:=%1 :host=%2").arg(name).arg(host),LOGFTP);
-    break;
+      break;
     case QFtp::HostLookup:
       addToLog(QString("FTPss Host lookup name:=%1 :host=%2").arg(name).arg(host),LOGFTP);
-    break;
+      break;
     case QFtp::Connecting:
       addToLog(QString("FTPss Connecting name:=%1 :host=%2").arg(name).arg(host),LOGFTP);
-    break;
+      break;
     case QFtp::Connected:
       addToLog(QString("FTPss Connected name:=%1 :host=%2").arg(name).arg(host),LOGFTP);
-    break;
+      break;
     case QFtp::LoggedIn:
       addToLog(QString("FTPss Logged In name:=%1 :host=%2").arg(name).arg(host),LOGFTP);
-    break;
+      break;
     case QFtp::Closing:
       addToLog(QString("FTPss Closing name:=%1 :host=%2").arg(name).arg(host),LOGFTP);
-    break;
+      break;
     default:
       addToLog(QString("FTPss uknown %1 name:=%2 host=%3").arg(ftp->state()).arg(name).arg(host),LOGFTP);
-    break;
+      break;
     }
 }
 
 
-void ftpInterface::ftp_listInfo( const QUrlInfo &)
+void ftpInterface::ftp_listInfo( const QUrlInfo & ent)
 {
-
+  if (ent.isFile()) {
+     addToLog(QString("currentId=%1, name=%2").
+             arg(ftp->currentId()).arg(ent.name()),
+             LOGFTP);
+             
+     if (ftp->currentId()==notifyId) {
+        QString name = ent.name().mid(notifyMask.length());
+
+        if (!notifyList.contains(name)) {
+            addToLog(QString("New Notification:'%1'").arg(name), LOGALL);
+            notifyList.append(name);
+            emit notification(name);
+            }
+        
+        if (notifyRemove) remove(ent.name());
+     }
+     else if (mremove_listids.contains(ftp->currentId())) {
+        remove(ent.name());
+     }
+     else {
+        listingResults.append(ent);
+        addToLog(QString("List Entry: %1").arg(ent.name()), LOGFTP);
+     }
+  }
 }
 
 void ftpInterface::ftp_rawCommandReply( int code, const QString &text )
 {
+  Q_UNUSED(code);
+  Q_UNUSED(text);
   addToLog(QString("FTP Raw Command Reply: code=%1 , %2").arg(code).arg(text),LOGFTP);
 }
 
@@ -344,7 +508,7 @@ void ftpInterface::slotProgress(qint64 bytes ,qint64 total)
   displayProgressFTPEvent *stmb;
   stmb=new displayProgressFTPEvent(bytes,total);
   QApplication::postEvent( dispatcherPtr, stmb );  // Qt will delete it when done
-
+  if (tim.isActive()) tim.start();
 }
 
 eftpError ftpInterface::uploadToRXServer(QString fn)
@@ -368,7 +532,6 @@ eftpError ftpInterface::uploadToRXServer(QString fn)
       for(i=0;i<ftpNumImages-1;i++)
         //        for(i=0;i<1;i++)
         {
-          //          qDebug() << "ftp renaming" << i;
           ftpDone=false;
           ftp->rename(QString("image%1").arg(ftpNumImages-1-i),QString("image%1").arg(ftpNumImages-i));
           while(!ftpDone)
@@ -388,3 +551,83 @@ eftpError ftpInterface::uploadToRXServer(QString fn)
 }
 
 
+QString ftpInterface::execFTPTest()
+{
+  QString ret;
+  QString fn;
+  QString rfn;
+  eftpError ftpResult;
+
+  addToLog(QString("%1 execFTPTest").arg(name), LOGFTP);
+
+  QTemporaryFile tst;
+  if (!tst.open())
+    {
+      ret=QString("Error writing temp file: %1, %2").arg(tst.fileName()).arg(strerror(errno));
+    }
+  else
+    {
+      fn=tst.fileName();
+      tst.write("connection test\n");
+      tst.close();
+      
+      rfn = QString("test_%1.txt").arg( myCallsign);
+#if 1
+      ftpResult=uploadFile(fn,rfn,true);
+#else
+      mremove("test_"+myCallsign+".*");
+      uploadData(QByteArray("Dummy\r\n"), rfn);
+      ftpResult = wait(-1);
+#endif
+      
+      switch(ftpResult)
+        {
+        case FTPCANCELED:
+          ret="Connection Canceled";
+          break;
+        case FTPOK:
+          ret="Connection OK";
+          break;
+        case FTPERROR:
+          ret=getLastError();
+          break;
+        case FTPNAMEERROR:
+          ret="Error in filename";
+          break;
+        case FTPTIMEOUT:
+          ret="FTP timed out";
+          break;
+        default:
+          ret="Unknown error";
+          break;
+        }
+    if (ftpResult==FTPOK) {
+        remove(rfn);
+        ftpResult=wait(-1);
+        switch(ftpResult)
+          {
+          case FTPCANCELED:
+            ret="mremove: Connection Canceled";
+            break;
+          case FTPOK:
+            ret="Connection OK";
+            break;
+          case FTPERROR:
+            ret=getLastError();
+            break;
+          case FTPNAMEERROR:
+            ret="mremove: Error in filename";
+            break;
+          case FTPTIMEOUT:
+            ret="mremove: FTP timed out";
+            break;
+          default:
+            ret="mremove: Unknown error";
+            break;
+          }
+
+       }
+    }
+  return ret;
+}
+
diff --git a/qsstv/utils/ftp.h b/qsstv/utils/ftp.h
index b4a96d3..dce2af5 100644
--- a/qsstv/utils/ftp.h
+++ b/qsstv/utils/ftp.h
@@ -30,7 +30,6 @@
 
 #include <QObject>
 #include <QFile>
-
 #include <QTimer>
 
 enum eftpError {FTPOK,FTPERROR,FTPNAMEERROR,FTPCANCELED,FTPTIMEOUT};
@@ -40,21 +39,31 @@ class ftpInterface: public QObject
 public:
   ftpInterface(QString id);
   ~ftpInterface();
-  void setupConnection(QString tHost,int tPort,QString tUser,QString tPasswd,QString tDirectory)
-  {
-    host=tHost;
-    user=tUser;
-    passwd=tPasswd;
-    directory=tDirectory;
-    port=tPort;
-
-  }
+  void setupConnection(QString tHost,int tPort,QString tUser,QString tPasswd,QString tDirectory);
+  void changePath( const QString &newPath );
   eftpError uploadFile(QString fileName, QString fixFilename, bool reconnect);
+  eftpError uploadData(const QByteArray & data, QString fixFilename);
   eftpError downloadFile(QString sourceFileName,QString destinationFilename);
+  eftpError wait(int timeout = 0);
+  eftpError remove(QString path);
+  eftpError mremove(QString path);
+  eftpError getListing(QString path);
+  eftpError startNotifyCheck(QString fn, int interval, int repeats, bool rm);
+  QList <QUrlInfo> getListingResults();
+  void clearListingResults();
+  
   bool isUnconnected();
   bool isLoggedIn();
+  bool isBusy();
+  void dumpState();
   eftpError uploadToRXServer(QString fn);
   QString getLastError() {return ftp->errorString();}
+  QString execFTPTest();
+  void init();
+
+signals:
+  void notification(QString info);
+  
 private slots:
   void ftp_commandStarted(int);
   void ftp_commandFinished(int,bool);
@@ -64,13 +73,13 @@ private slots:
   void ftp_rawCommandReply(int, const QString &);
   void slotAbort();
   void slotProgress(qint64 total, qint64 bytes);
-
+  void notifyTick();
+    
 private:
   void connectToHost();
-  void changePath( const QString &newPath );
   eftpError doConnect();
   void destroy();
-  void init();
+
   QFtp *ftp;
   QFile *sourceFn;
   bool ftpDone;
@@ -82,10 +91,20 @@ private:
   int port;
   bool ftpCommandSuccess;
   QTimer tim;
-  void dumpState();
+
   QString name;
+
+  QList <int> mremove_listids;
+  QList <QUrlInfo> listingResults;
+  QList <QString>  notifyList;
+  QTimer notifyTimer;
+  QString notifyMask;
+  int notifyTicks;
+  int notifyRepeats;
+  bool notifyRemove;
+  int notifyId;
 };
 
-extern ftpInterface *ftpIntf;
+//extern ftpInterface *ftpIntf;
 
 #endif
diff --git a/qsstv/utils/hexconvertor.cpp b/qsstv/utils/hexconvertor.cpp
new file mode 100644
index 0000000..bca4346
--- /dev/null
+++ b/qsstv/utils/hexconvertor.cpp
@@ -0,0 +1,28 @@
+#include "hexconvertor.h"
+
+bool hexFromString(QString s,QByteArray &ba,bool toHex)
+{
+  int i,j;
+  unsigned char res;
+  bool ok;
+  QString tmp;
+  if(toHex)
+    {
+      if((s.length()&1)!=0) return false;
+      ba.resize(s.length()/2);
+      for(i=0,j=0;i<s.length();i+=2,j++)
+        {
+          tmp="0x";
+          tmp+=s.mid(i,2);
+          res=tmp.toInt(&ok,16);
+          if(!ok) return false;
+          ba[j]=res;
+        }
+    }
+  else
+    {
+      ba=s.toLatin1();
+    }
+  return true;
+}
+
diff --git a/qsstv/utils/hexconvertor.h b/qsstv/utils/hexconvertor.h
new file mode 100644
index 0000000..d17d662
--- /dev/null
+++ b/qsstv/utils/hexconvertor.h
@@ -0,0 +1,10 @@
+#ifndef HEXCONVERTOR_H
+#define HEXCONVERTOR_H
+
+#include <QString>
+#include <QByteArray>
+
+
+
+bool hexFromString(QString s, QByteArray &ba, bool toHex);
+#endif // HEXCONVERTOR_H
diff --git a/qsstv/utils/hybridcrypt.cpp b/qsstv/utils/hybridcrypt.cpp
index b393aa9..d5323a8 100644
--- a/qsstv/utils/hybridcrypt.cpp
+++ b/qsstv/utils/hybridcrypt.cpp
@@ -23,7 +23,6 @@ hybridCrypt::hybridCrypt()
   vhcFtpLogin=hcFtpLogin;
   vhcFtpPassword=hcFtpPassword;
   vhcFtpRemoteDirectory=hcFtpRemoteDirectory;
-  vhcFtpRemoteDirectory="";
   vhcFtpPort=21; // at this moment no port can by specified
   hcFtpPort=vhcFtpPort;
   if((enableSpecialServer) && (!hybridFtpRemoteHost.isEmpty()))
@@ -31,7 +30,7 @@ hybridCrypt::hybridCrypt()
       hcFtpRemoteHost=hybridFtpRemoteHost;
       hcFtpLogin=hybridFtpLogin;
       hcFtpPassword=hybridFtpPassword;
-      hcFtpRemoteDirectory=hybridFtpRemoteDirectory; //always relatif to hybridFtpHybridFilesDirectory
+      hcFtpRemoteDirectory=hybridFtpRemoteDirectory; //always relatif to /HybridFiles
     }
   else
     {
@@ -60,17 +59,11 @@ bool hybridCrypt::enCrypt(QByteArray *ba)
 
   for(i=0;i<hstr.length();i++)
     {
-
       string.append(charToHex(hstr.at(i)));
     }
-
-
-
-  //int strLen=string.length();
   int sc=0;
   short int bufI,  num1, num2, num3, num4, res1, res2, res3, res4;
   unsigned char r1,r2;
-  QString encStr;
   ba->clear();
   while(string.length()%4!=0)
     {
@@ -114,23 +107,12 @@ bool hybridCrypt::enCrypt(QByteArray *ba)
               r2=r1;
               r1=0xFD;
             }
-          encStr.append(r1);
-          encStr.append(r2);
+          ba->append(r1);
+          ba->append(r2);
         }
     }
   while(sc<string.length());
-
-  ba->append(encStr);
   ba->append("\r\n");
-  //  QFile tf("mgc2.raw");
-  //  if(!tf.open(QIODevice::WriteOnly))
-  //    {
-  //    return false;
-  //    }
-  //  tf.write(*ba);
-  //  tf.close();
-
-
   return true;
 }
 
@@ -234,22 +216,28 @@ void hybridCrypt::reverseString(QString & s)
   s=t;
 }
 
-bool hybridCrypt::getParam(QString result)
+bool hybridCrypt::getParam(QString resultStr)
 {
   int a,b,c,d,e;
-  a=result.indexOf(QChar(63));
-  b=result.indexOf(QChar(34),a+1);
-  c=result.indexOf(QChar(60),b+1);
-  d=result.indexOf(QChar(62),c+1);
-  e=result.indexOf(QChar(58),d+1);
-  hcFtpRemoteHost=result.mid(a+1,b-a-1);
-  hcFtpLogin=result.mid(b+1,c-b-1);
-  hcFtpPassword=result.mid(c+1,d-c-1);
-  hcFtpRemoteDirectory=result.mid(d+1,e-d-1);
-  //  qDebug() <<  "host" << hcFtpRemoteHost;
-  //  qDebug() << "login" << hcFtpLogin;
-  //  qDebug() <<  "pwd" <<hcFtpPassword;
-  //  qDebug() <<  "dir" << hcFtpRemoteDirectory;
+  QString tempDir;
+  a=resultStr.indexOf(QChar(63));
+  b=resultStr.indexOf(QChar(34),a+1);
+  c=resultStr.indexOf(QChar(60),b+1);
+  d=resultStr.indexOf(QChar(62),c+1);
+  e=resultStr.indexOf(QChar(58),d+1);
+  hcFtpRemoteHost=resultStr.mid(a+1,b-a-1);
+  hcFtpLogin=resultStr.mid(b+1,c-b-1);
+  hcFtpPassword=resultStr.mid(c+1,d-c-1);
+  tempDir=resultStr.mid(d+1,e-d-1);
+  if( !tempDir.isEmpty())
+    {
+      hcFtpRemoteDirectory=resultStr.mid(d+1,e-d-1)+"/"+vhcFtpRemoteDirectory;
+    }
+  else
+    {
+      hcFtpRemoteDirectory=vhcFtpRemoteDirectory;
+    }
+  addToLog(QString("host: %1, login: %2, pwd: %3, dir: %4").arg(hcFtpRemoteHost).arg(hcFtpLogin).arg(hcFtpPassword).arg(hcFtpRemoteDirectory),LOGALL);
   return true;
 }
 
diff --git a/qsstv/utils/jp2io.cpp b/qsstv/utils/jp2io.cpp
new file mode 100644
index 0000000..8bc17e2
--- /dev/null
+++ b/qsstv/utils/jp2io.cpp
@@ -0,0 +1,612 @@
+#include "jp2io.h"
+#include "color.h"
+#include "appglobal.h"
+#include "loggingparams.h"
+
+#include <errno.h>
+#include <string.h>
+
+#include <QFile>
+#include <QDir>
+#include <QDebug>
+#include <QTemporaryFile>
+
+#define JP2_RFC3745_MAGIC "\x00\x00\x00\x0c\x6a\x50\x20\x20\x0d\x0a\x87\x0a"
+#define JP2_MAGIC "\x0d\x0a\x87\x0a"
+#define J2K_CODESTREAM_MAGIC "\xff\x4f\xff\x51"
+
+
+static size_t opj_strnlen_s(const char *src, size_t max_len)
+{
+  size_t len;
+
+  if (src == NULL) {
+    return 0U;
+  }
+  for (len = 0U; (*src != '\0') && (len < max_len); src++, len++);
+  return len;
+}
+
+static int opj_strcpy_s(char* dst, size_t dst_size, const char* src)
+{
+  size_t src_len = 0U;
+  if ((dst == NULL) || (dst_size == 0U)) {
+    return EINVAL;
+  }
+  if (src == NULL) {
+    dst[0] = '\0';
+    return EINVAL;
+  }
+  src_len = opj_strnlen_s(src, dst_size);
+  if (src_len >= dst_size) {
+    return ERANGE;
+  }
+  memcpy(dst, src, src_len);
+  dst[src_len] = '\0';
+  return 0;
+}
+
+
+/**
+sample error callback expecting a FILE* client object
+*/
+static void error_callback(const char *msg, void *client_data) {
+  (void)client_data;
+  Q_UNUSED( msg )
+  addToLog(QString("[ERROR] %1").arg(msg),LOGIMAG);
+}
+/**
+sample warning callback expecting a FILE* client object
+*/
+static void warning_callback(const char *msg, void *client_data) {
+  (void)client_data;
+  Q_UNUSED( msg )
+ addToLog(QString("[WARNING] %1").arg(msg),LOGIMAG);
+}
+/**
+sample debug callback expecting no client object
+*/
+static void info_callback(const char *msg, void *client_data) {
+  (void)client_data;
+  Q_UNUSED( msg )
+  addToLog(QString("[INFO] %1").arg(msg),LOGIMAG);
+}
+
+/*!
+ * Divide an integer by a power of 2 and round upwards.
+ */
+// -------------------- int_ceildivpow2() ------------------------------------
+static inline int int_ceildivpow2(int a, int b) {
+  return (a + (1 << b) - 1) >> b;
+}
+// ---------------------------------------------------------------------------
+
+jp2IO::jp2IO()
+{
+
+}
+
+void  jp2IO::init()
+{
+  jp2Image = NULL;
+  l_stream = NULL;				/* Stream */
+  l_codec = NULL;				/* Handle to a decompressor */
+  cstr_index = NULL;
+}
+
+bool jp2IO::check(QString fileName)
+{
+  quint64 size;
+  char data[12];
+  QFile fi(fileName);
+  set_default_parameters(&parameters); // set decoding parameters to default values
+  if(!fi.open(QIODevice::ReadOnly)) return false;
+  size=fi.read(data,12);
+  fi.close();
+  if(size!=12)
+  {
+    return false;
+  }
+  if (memcmp(data, JP2_RFC3745_MAGIC, 12) == 0 || memcmp(data, JP2_MAGIC, 4) == 0)
+  {
+    magicFormat = JP2_CFMT;
+    magicStr = ".jp2";
+  }
+  else if (memcmp(data, J2K_CODESTREAM_MAGIC, 4) == 0)
+  {
+    magicFormat  = J2K_CFMT;
+    magicStr = ".j2k or .jpc or .j2c";
+  }
+  else return false;
+  parameters.decod_format=magicFormat;
+  return true;
+}
+
+void jp2IO::set_default_parameters(opj_decompress_parameters* parameters)
+{
+  if (parameters)
+  {
+    memset(parameters, 0, sizeof(opj_decompress_parameters));
+
+    /* default decoding parameters (command line specific) */
+    parameters->decod_format = -1;
+    parameters->cod_format = -1;
+
+    /* default decoding parameters (core) */
+    opj_set_default_decoder_parameters(&(parameters->core));
+  }
+}
+
+void jp2IO::destroy_parameters(opj_decompress_parameters* parameters)
+{
+  if (parameters) {
+    if (parameters->precision) {
+      free(parameters->precision);
+      parameters->precision = NULL;
+    }
+  }
+}
+
+QImage jp2IO::decode(QString fileName)
+{
+  QImage qimage;
+  int width;  // image width and height
+  int wr, hr;         // taken from OpenJPEG
+  init();
+
+  l_stream = opj_stream_create_default_file_stream(fileName.toLatin1(),1);
+  if (!l_stream)
+  {
+    qDebug() << "ERROR -> failed to create the stream from the file " << parameters.infile;
+    destroy_parameters(&parameters);
+    return qimage;
+  }
+
+  /* decode the JPEG2000 stream */
+  /* ---------------------- */
+
+  switch(parameters.decod_format) {
+  case J2K_CFMT:	/* JPEG-2000 codestream */
+  {
+    /* Get a decoder handle */
+    l_codec = opj_create_decompress(OPJ_CODEC_J2K);
+    break;
+  }
+  case JP2_CFMT:	/* JPEG 2000 compressed image data */
+  {
+    /* Get a decoder handle */
+    l_codec = opj_create_decompress(OPJ_CODEC_JP2);
+    break;
+  }
+  case JPT_CFMT:	/* JPEG 2000, JPIP */
+  {
+    /* Get a decoder handle */
+    l_codec = opj_create_decompress(OPJ_CODEC_JPT);
+    break;
+  }
+  default:
+    //      fprintf(stderr, "skipping file..\n");
+    destroy_parameters(&parameters);
+    opj_stream_destroy(l_stream);
+  }
+
+  /* catch events using our callbacks and give a local context */
+  opj_set_info_handler(l_codec, info_callback,00);
+  opj_set_warning_handler(l_codec, warning_callback,00);
+  opj_set_error_handler(l_codec, error_callback,00);
+
+  //  t = opj_clock();
+
+  /* Setup the decoder decoding parameters using user parameters */
+  if ( !opj_setup_decoder(l_codec, &(parameters.core)) ){
+    qDebug() << "ERROR -> opj_decompress: failed to setup the decoder";
+    destroy_parameters(&parameters);
+    opj_stream_destroy(l_stream);
+    opj_destroy_codec(l_codec);
+    return qimage;
+  }
+
+
+  /* Read the main header of the codestream and if necessary the JP2 boxes*/
+  if(! opj_read_header(l_stream, l_codec, &jp2Image)){
+    qDebug() << "ERROR -> opj_decompress: failed to read the header";
+    destroy_parameters(&parameters);
+    opj_stream_destroy(l_stream);
+    opj_destroy_codec(l_codec);
+    opj_image_destroy(jp2Image);
+    return qimage;
+  }
+
+  if (!parameters.nb_tile_to_decode)
+  {
+    /* Optional if you want decode the entire image */
+    if (!opj_set_decode_area(l_codec, jp2Image, (OPJ_INT32)parameters.DA_x0,
+                             (OPJ_INT32)parameters.DA_y0, (OPJ_INT32)parameters.DA_x1, (OPJ_INT32)parameters.DA_y1)){
+      qDebug() <<	"ERROR -> opj_decompress: failed to set the decoded area";
+      destroy_parameters(&parameters);
+      opj_stream_destroy(l_stream);
+      opj_destroy_codec(l_codec);
+      opj_image_destroy(jp2Image);
+      return qimage;
+    }
+
+    /* Get the decoded image */
+    if (!(opj_decode(l_codec, l_stream, jp2Image) && opj_end_decompress(l_codec,	l_stream)))
+    {
+      qDebug() <<"ERROR -> opj_decompress: failed to decode image!";
+      destroy_parameters(&parameters);
+      opj_destroy_codec(l_codec);
+      opj_stream_destroy(l_stream);
+      opj_image_destroy(jp2Image);
+      return qimage;
+    }
+  }
+//  else {
+
+//    /* It is just here to illustrate how to use the resolution after set parameters */
+//    /*if (!opj_set_decoded_resolution_factor(l_codec, 5)) {
+//      fprintf(stderr, "ERROR -> opj_decompress: failed to set the resolution factor tile!\n");
+//      opj_destroy_codec(l_codec);
+//      opj_stream_destroy(l_stream);
+//      opj_image_destroy(jp2Image);
+//      return EXIT_FAILURE;
+//    }*/
+
+//    if (!opj_get_decoded_tile(l_codec, l_stream, jp2Image, parameters.tile_index)) {
+//      fprintf(stderr, "ERROR -> opj_decompress: failed to decode tile!\n");
+//      destroy_parameters(&parameters);
+//      opj_destroy_codec(l_codec);
+//      opj_stream_destroy(l_stream);
+//      opj_image_destroy(jp2Image);
+//      return qimage;
+//    }
+//    fprintf(stdout, "tile %d is decoded!\n\n", parameters.tile_index);
+//  }
+
+  //  tCumulative += opj_clock() - t;
+  //  numDecompressedImages++;
+
+  /* Close the byte stream */
+  opj_stream_destroy(l_stream);
+
+  if( jp2Image->color_space != OPJ_CLRSPC_SYCC
+      && jp2Image->numcomps == 3 && jp2Image->comps[0].dx == jp2Image->comps[0].dy
+      && jp2Image->comps[1].dx != 1 )
+    jp2Image->color_space = OPJ_CLRSPC_SYCC;
+  else if (jp2Image->numcomps <= 2)
+    jp2Image->color_space = OPJ_CLRSPC_GRAY;
+
+  if(jp2Image->color_space == OPJ_CLRSPC_SYCC){
+    color_sycc_to_rgb(jp2Image);
+  }
+
+  else if(jp2Image->color_space == OPJ_CLRSPC_EYCC){
+    color_esycc_to_rgb(jp2Image);
+  }
+
+  if(jp2Image->icc_profile_buf)
+  {
+    free(jp2Image->icc_profile_buf);
+    jp2Image->icc_profile_buf = NULL; jp2Image->icc_profile_len = 0;
+  }
+
+  //  /* Force output precision */
+  //  /* ---------------------- */
+  //  if (parameters.precision != NULL)
+  //  {
+  //    OPJ_UINT32 compno;
+  //    for (compno = 0; compno < jp2Image->numcomps; ++compno)
+  //    {
+  //      OPJ_UINT32 precno = compno;
+  //      OPJ_UINT32 prec;
+
+  //      if (precno >= parameters.nb_precision) {
+  //        precno = parameters.nb_precision - 1U;
+  //      }
+
+  //      prec = parameters.precision[precno].prec;
+  //      if (prec == 0) {
+  //        prec = jp2Image->comps[compno].prec;
+  //      }
+
+  //      switch (parameters.precision[precno].mode) {
+  //        case OPJ_PREC_MODE_CLIP:
+  //          clip_component(&(jp2Image->comps[compno]), prec);
+  //          break;
+  //        case OPJ_PREC_MODE_SCALE:
+  //          scale_component(&(jp2Image->comps[compno]), prec);
+  //          break;
+  //        default:
+  //          break;
+  //      }
+
+  //    }
+  //  }
+
+  //  /* Upsample components */
+  //  /* ------------------- */
+  //  if (parameters.upsample)
+  //  {
+  //    jp2Image = upsample_image_components(jp2Image);
+  //    if (jp2Image == NULL) {
+  //      fprintf(stderr, "ERROR -> opj_decompress: failed to upsample image components!\n");
+  //      destroy_parameters(&parameters);
+  //      opj_destroy_codec(l_codec);
+  //      return EXIT_FAILURE;
+  //    }
+  //  }
+
+  /* Force RGB output */
+  /* ---------------- */
+  if (parameters.force_rgb)
+  {
+    switch (jp2Image->color_space) {
+    case OPJ_CLRSPC_SRGB:
+      break;
+    case OPJ_CLRSPC_GRAY:
+      jp2Image = convert_gray_to_rgb(jp2Image);
+      break;
+    default:
+      fprintf(stderr, "ERROR -> opj_decompress: don't know how to convert image to RGB colorspace!\n");
+      opj_image_destroy(jp2Image);
+      jp2Image = NULL;
+      break;
+    }
+    if (jp2Image == NULL) {
+      fprintf(stderr, "ERROR -> opj_decompress: failed to convert to RGB image!\n");
+      destroy_parameters(&parameters);
+      opj_destroy_codec(l_codec);
+      return qimage;
+    }
+  }
+
+
+
+  // decode image width and height
+  width = jp2Image->comps[0].w;
+  wr = int_ceildivpow2(jp2Image->comps[0].w, jp2Image->comps[0].factor);
+//  height = jp2Image->comps[0].h;
+  hr = int_ceildivpow2(jp2Image->comps[0].h, jp2Image->comps[0].factor);
+
+  // alloc memory for a new image
+  qimage=QImage(wr, hr, QImage::Format_RGB32);
+
+  // get a pointer to the first pixel data in result image
+  QRgb *bits = (QRgb *)qimage.bits();
+  for(int i = 0; i < wr * hr; i++) {
+    unsigned char R, G, B;
+
+    // calculate coords
+    int x = (i) % (wr);
+    //     int y = height - (i) / (wr) - 1;
+    int y = (i) / (wr);
+#define idx( _x, _y ) ( _x + _y * width )
+
+    R = jp2Image->comps[0].data[ idx( x, y ) ];
+    G = jp2Image->comps[1].data[ idx( x, y ) ];
+    B = jp2Image->comps[2].data[ idx( x, y ) ];
+
+    // fill the bit with read pallete
+    bits[i] = qRgb(R, G, B);
+  }
+  return qimage;
+}
+
+opj_image_t *jp2IO::convert_gray_to_rgb(opj_image_t* original)
+{
+  OPJ_UINT32 compno;
+  opj_image_t* l_new_image = NULL;
+  opj_image_cmptparm_t* l_new_components = NULL;
+
+  l_new_components = (opj_image_cmptparm_t*)malloc((original->numcomps + 2U) * sizeof(opj_image_cmptparm_t));
+  if (l_new_components == NULL) {
+    fprintf(stderr, "ERROR -> opj_decompress: failed to allocate memory for RGB image!\n");
+    opj_image_destroy(original);
+    return NULL;
+  }
+
+  l_new_components[0].bpp  = l_new_components[1].bpp  = l_new_components[2].bpp  = original->comps[0].bpp;
+  l_new_components[0].dx   = l_new_components[1].dx   = l_new_components[2].dx   = original->comps[0].dx;
+  l_new_components[0].dy   = l_new_components[1].dy   = l_new_components[2].dy   = original->comps[0].dy;
+  l_new_components[0].h    = l_new_components[1].h    = l_new_components[2].h    = original->comps[0].h;
+  l_new_components[0].w    = l_new_components[1].w    = l_new_components[2].w    = original->comps[0].w;
+  l_new_components[0].prec = l_new_components[1].prec = l_new_components[2].prec = original->comps[0].prec;
+  l_new_components[0].sgnd = l_new_components[1].sgnd = l_new_components[2].sgnd = original->comps[0].sgnd;
+  l_new_components[0].x0   = l_new_components[1].x0   = l_new_components[2].x0   = original->comps[0].x0;
+  l_new_components[0].y0   = l_new_components[1].y0   = l_new_components[2].y0   = original->comps[0].y0;
+
+  for(compno = 1U; compno < original->numcomps; ++compno) {
+    l_new_components[compno+2U].bpp  = original->comps[compno].bpp;
+    l_new_components[compno+2U].dx   = original->comps[compno].dx;
+    l_new_components[compno+2U].dy   = original->comps[compno].dy;
+    l_new_components[compno+2U].h    = original->comps[compno].h;
+    l_new_components[compno+2U].w    = original->comps[compno].w;
+    l_new_components[compno+2U].prec = original->comps[compno].prec;
+    l_new_components[compno+2U].sgnd = original->comps[compno].sgnd;
+    l_new_components[compno+2U].x0   = original->comps[compno].x0;
+    l_new_components[compno+2U].y0   = original->comps[compno].y0;
+  }
+
+  l_new_image = opj_image_create(original->numcomps + 2U, l_new_components, OPJ_CLRSPC_SRGB);
+  free(l_new_components);
+  if (l_new_image == NULL) {
+    fprintf(stderr, "ERROR -> opj_decompress: failed to allocate memory for RGB image!\n");
+    opj_image_destroy(original);
+    return NULL;
+  }
+
+  l_new_image->x0 = original->x0;
+  l_new_image->x1 = original->x1;
+  l_new_image->y0 = original->y0;
+  l_new_image->y1 = original->y1;
+
+  l_new_image->comps[0].factor        = l_new_image->comps[1].factor        = l_new_image->comps[2].factor        = original->comps[0].factor;
+  l_new_image->comps[0].alpha         = l_new_image->comps[1].alpha         = l_new_image->comps[2].alpha         = original->comps[0].alpha;
+  l_new_image->comps[0].resno_decoded = l_new_image->comps[1].resno_decoded = l_new_image->comps[2].resno_decoded = original->comps[0].resno_decoded;
+
+  memcpy(l_new_image->comps[0].data, original->comps[0].data, original->comps[0].w * original->comps[0].h * sizeof(OPJ_INT32));
+  memcpy(l_new_image->comps[1].data, original->comps[0].data, original->comps[0].w * original->comps[0].h * sizeof(OPJ_INT32));
+  memcpy(l_new_image->comps[2].data, original->comps[0].data, original->comps[0].w * original->comps[0].h * sizeof(OPJ_INT32));
+
+  for(compno = 1U; compno < original->numcomps; ++compno) {
+    l_new_image->comps[compno+2U].factor        = original->comps[compno].factor;
+    l_new_image->comps[compno+2U].alpha         = original->comps[compno].alpha;
+    l_new_image->comps[compno+2U].resno_decoded = original->comps[compno].resno_decoded;
+    memcpy(l_new_image->comps[compno+2U].data, original->comps[compno].data, original->comps[compno].w * original->comps[compno].h * sizeof(OPJ_INT32));
+  }
+  opj_image_destroy(original);
+  return l_new_image;
+}
+
+QByteArray jp2IO::encode(QImage qimage, QImage &newImage,int &fileSize, int compressionRatio)
+{
+  QByteArray byteArray;
+  QString fn=QString("%1/%2").arg(QDir::tempPath()).arg("qsstv.tmp");
+//  char *of=fn.toLatin1().data();
+  bool success;
+  init();
+  fileSize=0;
+  opj_set_default_encoder_parameters(&cparameters);
+  cparameters.cp_disto_alloc = 1;
+  createImage(qimage);
+  cparameters.cod_format=JP2_CFMT;
+  if(opj_strcpy_s(cparameters.outfile, sizeof(cparameters.outfile), fn.toLatin1().data()) != 0)
+
+  {
+    return byteArray;
+  }
+  raw_cp.rawBitDepth = 0;
+  raw_cp.rawComp = 0;
+  raw_cp.rawComps = 0;
+  raw_cp.rawHeight = 0;
+  raw_cp.rawSigned = 0;
+  raw_cp.rawWidth = 0;
+  cparameters.tcp_mct = (char) 255; // This will be set later according to the input image or the provided option
+  cparameters.tcp_mct = (jp2Image->numcomps >= 3) ? 1 : 0;
+
+   cparameters.tcp_rates[0] = compressionRatio;	/* MOD antonin : losslessbug */
+    cparameters.tcp_numlayers++;
+    cparameters.cp_disto_alloc = 1;
+  l_codec = opj_create_compress(OPJ_CODEC_JP2);
+  /* catch events using our callbacks and give a local context */
+  opj_set_info_handler(l_codec, info_callback,00);
+  opj_set_warning_handler(l_codec, warning_callback,00);
+  opj_set_error_handler(l_codec, error_callback,00);
+  /* open a byte stream for writing and allocate memory for all tiles */
+
+
+  if (! opj_setup_encoder(l_codec, &cparameters, jp2Image))
+  {
+    addToLog("failed to encode image: opj_setup_encoder",LOGIMAG);
+    opj_destroy_codec(l_codec);
+    opj_image_destroy(jp2Image);
+    return byteArray;
+
+  }
+
+  l_stream = opj_stream_create_default_file_stream(cparameters.outfile,OPJ_FALSE);
+  if (! l_stream)
+  {
+    return byteArray;
+  }
+  /* encode the image */
+  success = opj_start_compress(l_codec,jp2Image,l_stream);
+  if (!success)
+  {
+    addToLog("failed to encode image: opj_start_compress",LOGIMAG);
+  }
+  success = success && opj_encode(l_codec, l_stream);
+  if (!success)
+  {
+    addToLog("failed to encode image: opj_encode",LOGIMAG);
+  }
+  success = success && opj_end_compress(l_codec, l_stream);
+  if (!success)
+  {
+    addToLog("failed to encode image: opj_end_compress",LOGIMAG);
+  }
+
+  if (!success)
+  {
+    opj_stream_destroy(l_stream);
+    opj_destroy_codec(l_codec);
+    opj_image_destroy(jp2Image);
+    addToLog("failed to encode image",LOGIMAG);
+    remove(parameters.outfile);
+    return byteArray;
+  }
+
+  opj_stream_destroy(l_stream);
+  opj_destroy_codec(l_codec);
+  opj_image_destroy(jp2Image);
+
+  /* free user parameters structure */
+  if(cparameters.cp_comment)   free(cparameters.cp_comment);
+  if(cparameters.cp_matrice)   free(cparameters.cp_matrice);
+  if(raw_cp.rawComps) free(raw_cp.rawComps);
+  QFile fi(fn);
+  if(fi.open(QIODevice::ReadOnly))
+  {
+    byteArray=fi.readAll();
+    fileSize=byteArray.count();
+  }
+  fi.close();
+  check(fn);
+  newImage=decode(fn);
+  fi.remove();
+  return byteArray;
+}
+
+bool jp2IO::createImage(QImage qimage)
+{
+  int i;
+  int numcmpts=3;
+  opj_image_cmptparm_t cmptparm[4];	/* maximum of 4 components */
+  memset(&cmptparm[0], 0, sizeof(cmptparm));
+  for(i = 0; i < 4; i++)
+  {
+    cmptparm[i].prec = 8;
+    cmptparm[i].bpp  = 8;
+    cmptparm[i].sgnd = 0;
+    cmptparm[i].dx   = (OPJ_UINT32)cparameters.subsampling_dx;
+    cmptparm[i].dy   = (OPJ_UINT32)cparameters.subsampling_dy;
+    cmptparm[i].w    = qimage.width();
+    cmptparm[i].h    = qimage.height();
+  }
+
+  jp2Image = opj_image_create(numcmpts, &cmptparm[0],OPJ_CLRSPC_SRGB);
+  if(!jp2Image) return false;
+  if (numcmpts == 4)
+  {
+    jp2Image->comps[3].alpha = 1;
+  }
+
+  /* set image offset and reference grid */
+  jp2Image->x0 = (OPJ_UINT32)cparameters.image_offset_x0;
+  jp2Image->y0 = (OPJ_UINT32)cparameters.image_offset_y0;
+  jp2Image->x1 =	jp2Image->x0 + (qimage.width()  - 1U) * (OPJ_UINT32)cparameters.subsampling_dx + 1U;
+  jp2Image->y1 = jp2Image->y0 + (qimage.height() - 1U) * (OPJ_UINT32)cparameters.subsampling_dy + 1U;
+
+
+  int width  = jp2Image->comps[0].w;
+  int height = jp2Image->comps[0].h;
+
+  QRgb *bits;
+  QRgb color;
+  int index = 0;
+  int x,y;
+  bits= (QRgb *)qimage.bits();
+  for(y = 0; y < height; y++)
+  {
+    for(x = 0; x < width; x++)
+    {
+      color=bits[x+y* width];
+      jp2Image->comps[0].data[index] = (OPJ_INT32)qRed(color);	/* R */
+      jp2Image->comps[1].data[index] = (OPJ_INT32)qGreen(color);	/* G */
+      jp2Image->comps[2].data[index] = (OPJ_INT32)qBlue(color);	/* B */
+      index++;
+    }
+  }
+  return true;
+}
+
diff --git a/qsstv/utils/jp2io.h b/qsstv/utils/jp2io.h
new file mode 100644
index 0000000..613c02e
--- /dev/null
+++ b/qsstv/utils/jp2io.h
@@ -0,0 +1,111 @@
+#ifndef JP2READER_H
+#define JP2READER_H
+#include "openjpeg.h"
+
+#include <QString>
+#include <QImage>
+
+#define J2K_CFMT 0
+#define JP2_CFMT 1
+#define JPT_CFMT 2
+
+typedef enum opj_prec_mode
+{
+  OPJ_PREC_MODE_CLIP,
+  OPJ_PREC_MODE_SCALE
+} opj_precision_mode;
+
+typedef struct opj_prec
+{
+  OPJ_UINT32         prec;
+  opj_precision_mode mode;
+}opj_precision;
+
+// used in encode
+
+/**@name RAW component encoding parameters */
+/*@{*/
+typedef struct raw_comp_cparameters {
+    /** subsampling in X direction */
+    int dx;
+    /** subsampling in Y direction */
+    int dy;
+    /*@}*/
+} raw_comp_cparameters_t;
+
+
+/**@name RAW image encoding parameters */
+/*@{*/
+typedef struct raw_cparameters {
+  /** width of the raw image */
+  int rawWidth;
+  /** height of the raw image */
+  int rawHeight;
+    /** number of components of the raw image */
+  int rawComp;
+    /** bit depth of the raw image */
+    int rawBitDepth;
+    /** signed/unsigned raw image */
+    OPJ_BOOL rawSigned;
+    /** raw components parameters */
+    raw_comp_cparameters_t *rawComps;
+  /*@}*/
+} raw_cparameters_t;
+
+
+
+
+
+
+typedef struct opj_decompress_params
+{
+  opj_dparameters_t core;  // core library parameters
+  char infile[OPJ_PATH_LEN]; // input file name
+  char outfile[OPJ_PATH_LEN]; // output file name
+  int decod_format; // input file format 0: J2K, 1: JP2, 2: JPT
+  int cod_format; // output file format 0: PGX, 1: PxM, 2: BMP
+  char indexfilename[OPJ_PATH_LEN]; // index file name
+  OPJ_UINT32 DA_x0; // Decoding area left boundary
+  OPJ_UINT32 DA_x1; // Decoding area right boundary
+  OPJ_UINT32 DA_y0; // Decoding area up boundary
+  OPJ_UINT32 DA_y1; // Decoding area bottom boundary
+  OPJ_BOOL m_verbose; // Verbose mode
+  OPJ_UINT32 tile_index; // tile number of the decoded tile
+  OPJ_UINT32 nb_tile_to_decode; // Nb of tile to decode
+  opj_precision* precision;
+  OPJ_UINT32     nb_precision;
+  int force_rgb; // force output colorspace to RGB
+  int upsample;// upsample components according to their dx/dy values
+  int split_pnm;// split output components to different files
+}opj_decompress_parameters;
+
+
+
+
+class jp2IO
+{
+public:
+  jp2IO();
+  bool check(QString fileName);
+  QImage decode(QString fileName);
+  QByteArray encode(QImage qimage, QImage &newImage, int &fileSize, int compressionRatio=0 );
+
+private:
+  int magicFormat;
+  QString magicStr;
+  opj_decompress_parameters parameters;			/* decompression parameters */
+  opj_cparameters_t cparameters;
+  opj_image_t* jp2Image;
+  opj_stream_t *l_stream ;				/* Stream */
+  opj_codec_t* l_codec;				/* Handle to a decompressor */
+  opj_codestream_index_t* cstr_index;
+  void set_default_parameters(opj_decompress_parameters* parameters);
+  void destroy_parameters(opj_decompress_parameters* parameters);
+  opj_image_t *convert_gray_to_rgb(opj_image_t* original);
+  void init();
+  // used in encode (compress)
+  raw_cparameters_t raw_cp;
+  bool createImage(QImage qimage);
+};
+
+#endif // JP2READER_H
diff --git a/qsstv/utils/logging.cpp b/qsstv/utils/logging.cpp
index 831aedd..38ce983 100644
--- a/qsstv/utils/logging.cpp
+++ b/qsstv/utils/logging.cpp
@@ -27,7 +27,7 @@
 #include <QStringList>
 #include <QDir>
 #include "ui_loggingform.h"
-#include "qsstvdefs.h"
+
 
 
 
@@ -48,7 +48,7 @@
 
 logFile::logFile()
 {
-#ifndef QT_NO_DEBUG
+#ifdef ENABLELOGGING
   lf=new QFile;
   auxFile=new QFile;
 #endif
@@ -62,7 +62,7 @@ logFile::logFile()
   creates logfile with name=logname, and opens it for writing
 */
 
-#ifndef QT_NO_DEBUG
+#ifdef ENABLELOGGING
 bool logFile::open(QString logname)
 {
 
@@ -87,8 +87,8 @@ logFile::~logFile()
 
 void logFile::close()
 {
-#ifndef QT_NO_DEBUG
- qDebug() << "closing logfile";
+#ifdef ENABLELOGGING
+ errorOut() << "closing logfile";
  add("End of logfile",LOGALL);
  add("....,",LOGALL);
  delete ts;
@@ -106,20 +106,20 @@ void logFile::reset()
 
 bool logFile::reopen()
 {
-#ifndef QT_NO_DEBUG
+#ifdef ENABLELOGGING
   setEnabled(false);
   QFileInfo finf(*lf);
   QFileInfo finfaux(*auxFile);
-  qDebug() << "opening logfile--: " << finf.absoluteFilePath();
+  errorOut() << "opening logfile--: " << finf.absoluteFilePath();
   if(!lf->open(QIODevice::WriteOnly))
     {
-      qDebug() << "logfile creation failed";
+     errorOut() << "logfile creation failed";
       return false;
     }
-  qDebug() << "opening logfile: " << finfaux.absoluteFilePath();
+  errorOut() << "opening logfile: " << finfaux.absoluteFilePath();
   if(!auxFile->open(QIODevice::WriteOnly))
     {
-      qDebug() << "auxillary file creation failed";
+      errorOut() << "auxillary file creation failed";
       lf->close();
       return false;
     }
@@ -141,7 +141,7 @@ bool logFile::reopen()
   The output is flushed after every access.Identical messages are only logged once. The count indicates the number of duplicate messages.
 */
 
-#ifndef QT_NO_DEBUG
+#ifdef ENABLELOGGING
 void logFile::add(QString t,short unsigned int posMask)
 {
   if(!(posMask==LOGALL)) // always show messages with DBALL
@@ -199,7 +199,7 @@ void logFile::add(const char *fileName,const char *functionName, int line, QStri
   add(s,posMask);
 }
 
-#ifndef QT_NO_DEBUG
+#ifdef ENABLELOGGING
 void logFile::addToAux(QString t)
 {
   if (!enabled) return;
@@ -262,18 +262,20 @@ void logFile::maskSelect(QWidget *wPtr)
       }
 }
 
-void logFile::readSettings(QSettings &qSettings)
+void logFile::readSettings()
 {
+  QSettings qSettings;
   qSettings.beginGroup ("logging");
-  mask=qSettings.value("mask",1).toUInt();
+  mask=qSettings.value("mask",1).toULongLong();
   deduplicate=qSettings.value("deduplicate",true).toBool();
   qSettings.endGroup();
 }
 
-void logFile::writeSettings(QSettings &qSettings)
+void logFile::writeSettings()
 {
+  QSettings qSettings;
   qSettings.beginGroup ("logging");
-  qSettings.setValue ( "mask", (uint)mask.to_ulong());
+  qSettings.setValue ( "mask", (qulonglong)mask.to_ulong());
   qSettings.setValue ( "deduplicate", deduplicate);
   qSettings.endGroup();
 }
diff --git a/qsstv/utils/logging.h b/qsstv/utils/logging.h
index e5ab8d7..1f82a40 100644
--- a/qsstv/utils/logging.h
+++ b/qsstv/utils/logging.h
@@ -11,9 +11,16 @@
 #include "loggingparams.h"
 
 #ifndef QT_NO_DEBUG
-#define addToLog(x,y) logfile->add(__FILE__,__func__,__LINE__,x,y)
+#define ENABLELOGGING
+#endif
+
+#define errorOut() qDebug()
+#ifdef ENABLELOGGING
+#define addToLog(x,y) logFilePtr->add(__FILE__,__func__,__LINE__,x,y)
+
 #else
-#define addToLog(x,y) logfile->dummyAdd(x,y) // to avoid parameter not used warnings
+//#define addToLog(x,y) logFilePtr->dummyAdd(x,y) // to avoid parameter not used warnings
+#define addToLog(x,y) {} // to avoid parameter not used warnings
 #endif
 
 class QTextStream;
@@ -32,8 +39,8 @@ class logFile
     bool setEnabled(bool e);
     void setLogMask(std::bitset<NUMDEBUGLEVELS> logMask);
     void maskSelect(QWidget *wPtr=0);
-    void readSettings(QSettings &qSettings);
-    void writeSettings(QSettings &qSettings);
+    void readSettings();
+    void writeSettings();
     void close();
     void reset();
     bool reopen();
diff --git a/qsstv/utils/loggingform.ui b/qsstv/utils/loggingform.ui
index bcf5904..8e47b56 100644
--- a/qsstv/utils/loggingform.ui
+++ b/qsstv/utils/loggingform.ui
@@ -19,6 +19,9 @@
   <layout class="QVBoxLayout" name="verticalLayout">
    <item>
     <widget class="QTableWidget" name="maskTableWidget">
+     <property name="alternatingRowColors">
+      <bool>true</bool>
+     </property>
      <property name="rowCount">
       <number>10</number>
      </property>
diff --git a/qsstv/utils/loggingparams.cpp b/qsstv/utils/loggingparams.cpp
index 67c7914..d9176d4 100644
--- a/qsstv/utils/loggingparams.cpp
+++ b/qsstv/utils/loggingparams.cpp
@@ -20,37 +20,49 @@
 ***************************************************************************/
 #include "loggingparams.h"
 
+
+
 QString levelStr[NUMDEBUGLEVELS]=
 {
-  "GALLERY ",
-  "PARAMS  ",
-  "FFT     ",
-  "WAVIO   ",
-  "SYNTHES ",
-  "DISPATC ",
-  "SOUNDIO ",
-  "RXFUNC  ",
-  "TXFUNC  ",
-  "SYNCPRC1",
-  "SYNCPRC2",
-  "SLANTAD ",
-  "MODES   ",
-  "FTP     ",
-  "IMAGE   ",
-  "SCOPE   ",
-  "CAM     ",
-  "RX MAIN ",
-  "TX MAIN ",
-  "EDITOR  ",
-  "RIGCTRL ",
-  "DRMDEMOD",
-  "DRMRXSRC",
-  "DRMMOT  ",
-  "DRMTX   ",
-  "DRMTXMOT",
-  "DRMTXCOD",
-  "DRMTXAAA",
-  "XMLRPC  ",
-  "PERFORM "
+  "GALLERY  ",
+  "PARAMS   ",
+  "FFT      ",
+  "WAVIO    ",
+  "SYNTHES  ",
+  "DISPATC  ",
+  "SOUNDIO  ",
+  "RXFUNC   ",
+  "TXFUNC   ",
+  "SYNCSTATE",
+  "SYNCPROCESSSTATE",
+  "SYNCEXTR ",
+  "SYNCEVAL",
+  "SYNCACC  ",
+  "SYNCREJ  ",
+  "SYNCMATCH",
+  "SYNCLOST",
+  "SLANTAD  ",
+  "MODES    ",
+  "FTP      ",
+  "IMAGE    ",
+  "SCOPE    ",
+  "CAM      ",
+  "RX MAIN  ",
+  "TX MAIN  ",
+  "EDITOR   ",
+  "RIGCTRL  ",
+  "DRMDEMOD ",
+  "DRMRXSRC ",
+  "DRMMOT   ",
+  "DRMTX    ",
+  "DRMTXMOT ",
+  "DRMTXCOD ",
+  "DRMTXAAA ",
+  "XMLRPC   ",
+  "FSKID    ",
+  "VISCODE  ",
+  "RETRACE  ",
+  "CALIBRATE",
+  "NOTIFY   ",
+  "PERFORM  "
 };
-
diff --git a/qsstv/utils/loggingparams.h b/qsstv/utils/loggingparams.h
index 93541ca..9e61da2 100644
--- a/qsstv/utils/loggingparams.h
+++ b/qsstv/utils/loggingparams.h
@@ -2,38 +2,12 @@
 #define LOGGINGPARAMS_H
 #include <QString>
 
-//debuglevels
-#define LOGALL       99
-#define LOGGALLERY   0
-#define LOGPARAM     1
-#define LOGFFT       2
-#define LOGWAVIO     3
-#define LOGSYNTHES   4
-#define LOGDISPAT    5
-#define LOGSOUND     6
-#define LOGRXFUNC    7
-#define LOGTXFUNC    8
-#define LOGSYNC1     9
-#define LOGSYNC2     10
-#define LOGSLANT     11
-#define LOGMODES     12
-#define LOGFTP       13
-#define LOGIMAG      14
-#define LOGSCOPE     15
-#define LOGCAM       16
-#define LOGRXMAIN    17
-#define LOGTXMAIN    18
-#define LOGEDIT      19
-#define LOGRIGCTRL   20
-#define LOGDRMDEMOD  21
-#define LOGDRMSRC    22
-#define LOGDRMMOT    23
-#define LOGDRMTX     24
-#define LOGDRMTXMOT  25
-#define LOGDRMTXCOD  26
-#define LOGDRMTXAAA  27
-#define LOGXML       28
-#define LOGPERFORM   29
+enum debugLevels {LOGGALLERY,LOGPARAM,LOGFFT,LOGWAVIO,LOGSYNTHES,LOGDISPATCH,LOGSOUND,
+                  LOGRXFUNC,LOGTXFUNC,LOGSYNCSTATE,LOGSYNCPROCESSSTATE,LOGSYNCEXTRACT,LOGSYNCEVAL,LOGSYNCACCEPTED,LOGSYNCREJECTED,LOGSYNCMATCH,LOGSYNCLOST,LOGSLANT,
+                  LOGMODES,LOGFTP,LOGIMAG,LOGSCOPE,LOGCAM,LOGRXMAIN,LOGTXMAIN,LOGEDIT,LOGRIGCTRL,
+                  LOGDRMDEMOD,LOGDRMSRC,LOGDRMMOT,LOGDRMTX,LOGDRMTXMOT,LOGDRMTXCOD,LOGDRMTXAAA,LOGXML,
+                  LOGFSKID,LOGVISCODE,LOGRETRACE,LOGCALIB,LOGNOTIFY,LOGPERFORM,LOGALL=99};
+
 #define NUMDEBUGLEVELS (LOGPERFORM+1)
 
 extern QString levelStr[NUMDEBUGLEVELS];
diff --git a/qsstv/utils/qftp.cpp b/qsstv/utils/qftp.cpp
index f3fd58c..0eeb29f 100644
--- a/qsstv/utils/qftp.cpp
+++ b/qsstv/utils/qftp.cpp
@@ -739,7 +739,8 @@ void QFtpDTP::socketError(QAbstractSocket::SocketError e)
 
 void QFtpDTP::socketConnectionClosed()
 {
-    if (!is_ba && data.dev) {
+    if (!is_ba && data.dev)
+      {
         clearData();
     }
 
@@ -1434,12 +1435,12 @@ QFtp::QFtp(QObject *parent)
 
     This enum defines the connection state:
 
-    \value Unconnected There is no connection to the host.
-    \value HostLookup A host name lookup is in progress.
-    \value Connecting An attempt to connect to the host is in progress.
-    \value Connected Connection to the host has been achieved.
-    \value LoggedIn Connection and user login have been achieved.
-    \value Closing The connection is closing down, but it is not yet
+    \var Unconnected There is no connection to the host.
+    \var HostLookup A host name lookup is in progress.
+    \var Connecting An attempt to connect to the host is in progress.
+    \var Connected Connection to the host has been achieved.
+    \var LoggedIn Connection and user login have been achieved.
+    \var Closing The connection is closing down, but it is not yet
     closed. (The state will be \c Unconnected when the connection is
     closed.)
 
@@ -1456,10 +1457,10 @@ QFtp::QFtp(QObject *parent)
     This enum defines whether the client (Passive mode) or the server
     (Active mode) should set up the data connection.
 
-    \value Passive The client connects to the server to transmit its
+    \var Passive The client connects to the server to transmit its
     data.
 
-    \value Active The server connects to the client to transmit its
+    \var Active The server connects to the client to transmit its
     data.
 */
 /*!
@@ -1468,9 +1469,9 @@ QFtp::QFtp(QObject *parent)
     This enum identifies the data transfer type used with get and
     put commands.
 
-    \value Binary The data will be transferred in Binary mode.
+    \var Binary The data will be transferred in Binary mode.
 
-    \value Ascii The data will be transferred in Ascii mode and new line
+    \var Ascii The data will be transferred in Ascii mode and new line
     characters will be converted to the local format.
 */
 /*!
@@ -1478,12 +1479,12 @@ QFtp::QFtp(QObject *parent)
 
     This enum identifies the error that occurred.
 
-    \value NoError No error occurred.
-    \value HostNotFound The host name lookup failed.
-    \value ConnectionRefused The server refused the connection.
-    \value NotConnected Tried to send a command, but there is no connection to
+    \var NoError No error occurred.
+    \var HostNotFound The host name lookup failed.
+    \var ConnectionRefused The server refused the connection.
+    \var NotConnected Tried to send a command, but there is no connection to
     a server.
-    \value UnknownError An error other than those specified above
+    \var UnknownError An error other than those specified above
     occurred.
 
     \sa error()
@@ -1499,21 +1500,21 @@ QFtp::QFtp(QObject *parent)
     can simply check in the slot connected to the start() signal if
     the currentCommand() is \c List.
 
-    \value None No command is being executed.
-    \value SetTransferMode set the \link TransferMode transfer\endlink mode.
-    \value SetProxy switch proxying on or off.
-    \value ConnectToHost connectToHost() is being executed.
-    \value Login login() is being executed.
-    \value Close close() is being executed.
-    \value List list() is being executed.
-    \value Cd cd() is being executed.
-    \value Get get() is being executed.
-    \value Put put() is being executed.
-    \value Remove remove() is being executed.
-    \value Mkdir mkdir() is being executed.
-    \value Rmdir rmdir() is being executed.
-    \value Rename rename() is being executed.
-    \value RawCommand rawCommand() is being executed.
+    \var None No command is being executed.
+    \var SetTransferMode set the \link TransferMode transfer\endlink mode.
+    \var SetProxy switch proxying on or off.
+    \var ConnectToHost connectToHost() is being executed.
+    \var Login login() is being executed.
+    \var Close close() is being executed.
+    \var List list() is being executed.
+    \var Cd cd() is being executed.
+    \var Get get() is being executed.
+    \var Put put() is being executed.
+    \var Remove remove() is being executed.
+    \var Mkdir mkdir() is being executed.
+    \var Rmdir rmdir() is being executed.
+    \var Rename rename() is being executed.
+    \var RawCommand rawCommand() is being executed.
 
     \sa currentCommand()
 */
diff --git a/qsstv/utils/qjp2io.cpp b/qsstv/utils/qjp2io.cpp
deleted file mode 100644
index 7d3a72d..0000000
--- a/qsstv/utils/qjp2io.cpp
+++ /dev/null
@@ -1,400 +0,0 @@
-/*****************************************************************************
- JPEG 2000 support for Qt based on JasPer lib
- Copyright (c) 2003 by Dmitry V. Fedorov <www.dimin.net>
-
- This wrapper is in it's initial state, it's quite slow now because
- of something, so soon will fix this performance probs...
-
- IMPLEMENTATION
-
- Programmer: Dima V. Fedorov <mailto:dima at dimin.net> <http://www.dimin.net/>
-
- History:
-   13/06/2003 17:02 - First creation
-
-
- Ver : 1
-*****************************************************************************/
-#include "qsstvdefs.h"
-#include <QImage>
-#include <QImageReader>
-#include <QImageWriter>
-#include <QFile>
-#include <QColor>
-
-#include <QDebug>
-
-#include <jasper/jasper.h>
-
-
-#include "qjp2io.h"
-
-
-QImage readJP2Image(QString fileName)
-{
-
-  // pass on file name if known
-  QFile f(fileName);
-  long y;
-  jas_image_t *jp2_image;
-  jas_matrix_t *pixels[4];
-  jas_stream_t *jp2_stream;
-  int format;
-
-  register unsigned long i, x;
-  int components[4];
-  unsigned long number_components;
-  unsigned int channel_scale[4], maximum_component_depth=8;
-
-  int_fast32_t height = 0;
-  int_fast32_t width = 0;
-  uchar *px;
-  uchar pixel[4];
-  
-  // Initialize JPEG 2000 API.
-  jas_init();  // always returns 0
-
-  QByteArray ba = fileName.toLocal8Bit();
-  const char *fn = ba.data();
-//  qDebug() << "fn:" << fn;
-
-  if ( !(jp2_stream = jas_stream_fopen(fn, "rb")) ) return QImage();
-
-  if ((format = jas_image_getfmt(jp2_stream)) < 0)
-    {
-      return QImage(); // Unknown format
-    }
-
-
-  jp2_image = jas_image_decode(jp2_stream, format, 0);
-
-  if (jp2_image == (jas_image_t *) NULL) {
-      (void) jas_stream_close(jp2_stream);
-      return QImage(); //UnableToDecodeImageFile
-    }
-
-
-  switch (jas_clrspc_fam(jas_image_clrspc(jp2_image)))
-    {
-    case JAS_CLRSPC_FAM_RGB:
-      {
-        components[0]=jas_image_getcmptbytype(jp2_image,
-                                              JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R));
-        components[1]=jas_image_getcmptbytype(jp2_image,
-                                              JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G));
-        components[2]=jas_image_getcmptbytype(jp2_image,
-                                              JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B));
-        if ((components[0] < 0) || (components[1] < 0) || (components[2] < 0))
-          {
-            (void) jas_stream_close(jp2_stream);
-            jas_image_destroy(jp2_image);
-            return QImage(); //MissingImageChannel
-          }
-        number_components=3;
-        components[3]=jas_image_getcmptbytype(jp2_image,
-                                              JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_OPACITY));
-        if (components[3] > 0)
-          {
-            //image->matte=True; // dima - what a hell is this???
-            number_components++;
-          }
-        break;
-      }
-    case JAS_CLRSPC_FAM_GRAY:
-      {
-        components[0]=jas_image_getcmptbytype(jp2_image,
-                                              JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y));
-        if (components[0] < 0)
-          {
-            (void) jas_stream_close(jp2_stream);
-            jas_image_destroy(jp2_image);
-            return QImage(); //MissingImageChannel
-          }
-        number_components=1;
-        break;
-      }
-    case JAS_CLRSPC_FAM_YCBCR:
-    default:
-      {
-        (void) jas_stream_close(jp2_stream);
-        jas_image_destroy(jp2_image);
-        return QImage(); //ColorspaceModelIsNotSupported
-      }
-    }
-
-  //-------------------------------------------------------------------
-  // Now create the QImage
-  //-------------------------------------------------------------------
-
-  height = jas_image_height(jp2_image);
-  width  = jas_image_width(jp2_image);
-  
-  // test for components geometry
-  for (i=0; i < (ulong) number_components; i++)
-    {
-      if ((jas_image_cmptwidth(jp2_image,components[i]) != width) ||
-          (jas_image_cmptheight(jp2_image,components[i]) != height) ||
-          (jas_image_cmpttlx(jp2_image,components[i]) != 0) ||
-          (jas_image_cmpttly(jp2_image,components[i]) != 0) ||
-          (jas_image_cmpthstep(jp2_image,components[i]) != 1) ||
-          (jas_image_cmptvstep(jp2_image,components[i]) != 1) ||
-          (jas_image_cmptsgnd(jp2_image,components[i]) != false))
-        {
-          (void) jas_stream_close(jp2_stream);
-          jas_image_destroy(jp2_image);
-          return QImage(); // IrregularChannelGeometryNotSupported
-        }
-    }
-
-  // now get the max component depth
-  for (i=0; i < (ulong) number_components; i++)
-    {
-      maximum_component_depth = max((unsigned int) jas_image_cmptprec(jp2_image,components[i]),
-                                    maximum_component_depth);
-      pixels[i] = jas_matrix_create(1, (unsigned int) width);
-      if (pixels[i] == (jas_matrix_t *) NULL)
-        {
-          jas_image_destroy(jp2_image);
-          return QImage(); //MemoryAllocationFailed
-        }
-    }
-
-  // we should set it here, since QT works with only 8bit channels, done for now
-  /*
-  if (maximum_component_depth <= 8)
-    image->depth=Min(QuantumDepth,8);
-  else
-    image->depth=Min(QuantumDepth,16);
-  */
-
-  if (number_components == 1)
-    {
-      return QImage();
-    }
-  QImage image(width, height, QImage::Format_RGB32);
-  if(image.isNull()) return QImage();
-
-  for (i=0; i < (ulong) number_components; i++)
-    {
-      channel_scale[i]=1;
-      if (jas_image_cmptprec(jp2_image,components[i]) < 16)
-        channel_scale[i]=
-            (1 << (16-jas_image_cmptprec(jp2_image,components[i])))+1;
-    }
-
-  //-------------------------------------------------------------------
-  // Now copy image data
-  //-------------------------------------------------------------------
-  
-  for (y=0; y < (long) height; y++)
-    {
-      for (i=0; i < number_components; i++)
-        jas_image_readcmpt(jp2_image, components[i], 0, y, width, 1, pixels[i]);
-
-      px = image.scanLine(y);
-
-      switch (number_components)
-        {
-
-        case 1: // GRAY SCALE IMAGE
-          {
-            for (x=0; x < (ulong) width; x++)
-              {
-                px[x] = (unsigned char) jas_matrix_getv(pixels[0],x)*channel_scale[0];
-              }
-
-            break;
-          }
-
-        case 3: // RGB
-          {
-
-            for (x=0; x < (ulong) width; x++)
-              {
-                QRgb *row = (QRgb*) px;
-
-                pixel[0] = (jas_matrix_getv(pixels[0],x)*channel_scale[0]);
-                pixel[1] = (jas_matrix_getv(pixels[1],x)*channel_scale[1]);
-                pixel[2] = (jas_matrix_getv(pixels[2],x)*channel_scale[2]);
-
-                row[x] = qRgb(pixel[0], pixel[1], pixel[2] );
-              }
-            break;
-          }
-        case 4: // RGBA
-          {
-            for (x=0; x < (ulong) width; x++)
-              {
-                QRgb *row = (QRgb*) px;
-
-                pixel[0] = (jas_matrix_getv(pixels[0],x)*channel_scale[0]);
-                pixel[1] = (jas_matrix_getv(pixels[1],x)*channel_scale[1]);
-                pixel[2] = (jas_matrix_getv(pixels[2],x)*channel_scale[2]);
-                pixel[3] = (jas_matrix_getv(pixels[3],x)*channel_scale[3]);
-
-                row[x] = qRgba(pixel[0], pixel[1], pixel[2], pixel[3]);
-              }
-            break;
-          }
-        }
-
-    }
-  
-  // clean up all mess in memory
-  (void) jas_stream_close(jp2_stream);
-  jas_image_destroy(jp2_image);
-  for (i=0; i < (ulong) number_components; i++)
-    jas_matrix_destroy(pixels[i]);
-
-  jas_init();
-
-  return image;
-}
-
-//! QImageIO write handler for TIFF files.
-//
-bool writeJP2Image(QImage img, QString fileName,double ratio)
-{
-  QFile f(fileName);
-  char options[MaxTextExtent];
-  double rate;
-  int format;
-  ulong y;
-  jas_image_cmptparm_t component_info;
-  jas_image_t *jp2_image;
-  jas_matrix_t *pixels[4];
-  jas_stream_t *jp2_stream;
-  register unsigned long i, x;
-  int status;
-  unsigned long number_components;
-
-  uchar *px;
-
-
-  // Intialize JasPer JPEG 2000 API
-  jas_init();
-  QByteArray ba = fileName.toLocal8Bit();
-  const char *fn = ba.data();
-//  qDebug() << "fn:" << fn;
-
-  if ( !(jp2_stream = jas_stream_fopen(fn, "wb")) ) return false;
-
-  if (img.depth() == 8)
-    number_components = 1;
-  else
-    number_components = 4;
-
-  jp2_image=jas_image_create0();
-  if (jp2_image == (jas_image_t *) NULL) return false; //UnableToCreateImage
-
-
-  for (i=0; i < (ulong) number_components; i++)
-    {
-      (void) memset((void *) &component_info,0,sizeof(jas_image_cmptparm_t));
-      component_info.tlx=0;
-      component_info.tly=0;
-      component_info.hstep=1;
-      component_info.vstep=1;
-      component_info.width=(unsigned int) img.width();
-      component_info.height=(unsigned int) img.height();
-      component_info.prec=(unsigned int) 8;//img.depth() <= 8 ? 8 : 16;
-      component_info.sgnd=false;
-      if (jas_image_addcmpt(jp2_image,i,&component_info))
-        {
-          jas_image_destroy(jp2_image);
-          return false; //UnableToCreateImageComponent
-        }
-    }
-
-  if (number_components == 1)
-    {
-      //  sRGB Grayscale
-      jas_image_setclrspc(jp2_image, JAS_CLRSPC_SGRAY);
-      jas_image_setcmpttype(jp2_image, 0, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y));
-    }
-  else
-    {
-      //  sRGB
-      jas_image_setclrspc(jp2_image, JAS_CLRSPC_SRGB);
-      jas_image_setcmpttype(jp2_image, 0, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R));
-      jas_image_setcmpttype(jp2_image, 1, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G));
-      jas_image_setcmpttype(jp2_image, 2, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B));
-      if (number_components == 4 )
-        jas_image_setcmpttype(jp2_image, 3, JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_OPACITY));
-    }
-
-
-  //  Convert to JPEG 2000 pixels.
-  for (i=0; i < (ulong) number_components; i++)
-    {
-      pixels[i] = jas_matrix_create(1, (unsigned int) img.width());
-      if (pixels[i] == (jas_matrix_t *) NULL)
-        {
-          for (x=0; x < i; x++) jas_matrix_destroy(pixels[x]);
-          jas_image_destroy(jp2_image);
-          return false; //MemoryAllocationFailed
-        }
-    }
-  
-  
-  // now copy the data itself
-  for (y=0; y < (ulong) img.height(); y++)
-    {
-      px = img.scanLine(y);
-
-      for (x=0; x < (ulong) img.width(); x++)
-        {
-          if (number_components == 1)
-            jas_matrix_setv(pixels[0], x, px[x] );
-          else
-            {
-              QRgb *row = (QRgb*) px;
-
-              jas_matrix_setv(pixels[0], x, qRed(row[x]) );
-              jas_matrix_setv(pixels[1], x, qGreen(row[x]) );
-              jas_matrix_setv(pixels[2], x, qBlue(row[x]) );
-              if (number_components > 3)
-                jas_matrix_setv(pixels[3], x, qAlpha(*(row+x)) );
-            }
-        }
-
-
-      for (i=0; i < (ulong) number_components; i++)
-        jas_image_writecmpt(jp2_image, i, 0, y, img.width(), 1, pixels[i]);
-
-    }  // end of byte data copy
-
-  rate=1;
-  format = jas_image_fmtfromname(fileName.toLatin1().data());
-  double qrate=ratio;
-
-
-  if (img.width()*img.height() > 2500)
-    {
-      double alpha, header_size, number_pixels, target_size;
-
-      alpha=115-100;
-      rate=100.0/(alpha*alpha);
-      header_size=550.0;
-      header_size+=(number_components-1)*142;
-      number_pixels=(double) img.width()*img.height()*(img.depth()/8)*number_components;
-      target_size=(number_pixels*rate)+header_size;
-      rate=target_size/number_pixels;
-    }
-  if(rate>qrate)
-    {
-      rate=qrate;
-    }
-  
-  sprintf(options, "rate=%g", rate);
-  status = jas_image_encode(jp2_image, jp2_stream, format, options);
-  
-  // clean up our mess
-  (void) jas_stream_close(jp2_stream);
-  for (i=0; i < (ulong) number_components; i++) jas_matrix_destroy(pixels[i]);
-  jas_image_destroy(jp2_image);
-
-  if (status == -1) return false; //UnableToEncodeImageFile
-  return true;
-}
-
diff --git a/qsstv/utils/qjp2io.h b/qsstv/utils/qjp2io.h
deleted file mode 100644
index a022b97..0000000
--- a/qsstv/utils/qjp2io.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*****************************************************************************
- JPEG 2000 support for Qt based on JasPer lib
- Copyright (c) 2003 by Dmitry V. Fedorov <www.dimin.net>
-
- DEFINES
-
- Programmer: Dima V. Fedorov <mailto:dima at dimin.net> <http://www.dimin.net/>
-
- History:
-   13/06/2003 17:02 - First creation
-   17/12/2013 // changed by ON4QZ
-
-
- Ver : 1
-*****************************************************************************/
-#ifndef QJP2_H
-#define QJP2_H
-
-#include <QString>
-
-
-/* we better use jasper defined types
-#ifndef int8
-typedef	char int8;
-#endif
-
-#ifndef uint8
-typedef	unsigned char uint8;
-#endif
-
-#ifndef int16
-typedef	short int16;
-#endif
-
-#ifndef uint16
-typedef	unsigned short uint16;
-#endif
-
-#ifndef int32
-typedef	long int32;
-#endif
-
-#ifndef uint32
-typedef	unsigned long uint32;	// sizeof (uint32) must == 4
-#endif
-*/
-
-#ifndef max
-#define max(a,b)      (((a) > (b)) ? (a) : (b))
-#endif
-
-#ifndef min
-#define min(a,b)      (((a) < (b)) ? (a) : (b))
-#endif
-
-#define MaxTextExtent 2053 
-
-QImage readJP2Image(QString fileName);
-bool writeJP2Image(QImage im, QString fileName, double ratio);
-
-#endif
diff --git a/qsstv/utils/qurlinfo.cpp b/qsstv/utils/qurlinfo.cpp
index 3429542..68d9e57 100644
--- a/qsstv/utils/qurlinfo.cpp
+++ b/qsstv/utils/qurlinfo.cpp
@@ -84,7 +84,7 @@ public:
 
     \ingroup io
     \ingroup network
-    \inmodule QtNetwork
+
 
     The information about a URL that can be retrieved includes name(),
     permissions(), owner(), group(), size(), lastModified(),
@@ -108,15 +108,15 @@ public:
     This enum is used by the permissions() function to report the
     permissions of a file.
 
-    \value ReadOwner The file is readable by the owner of the file.
-    \value WriteOwner The file is writable by the owner of the file.
-    \value ExeOwner The file is executable by the owner of the file.
-    \value ReadGroup The file is readable by the group.
-    \value WriteGroup The file is writable by the group.
-    \value ExeGroup The file is executable by the group.
-    \value ReadOther The file is readable by anyone.
-    \value WriteOther The file is writable by anyone.
-    \value ExeOther The file is executable by anyone.
+    \var ReadOwner The file is readable by the owner of the file.
+    \var WriteOwner The file is writable by the owner of the file.
+    \var ExeOwner The file is executable by the owner of the file.
+    \var ReadGroup The file is readable by the group.
+    \var WriteGroup The file is writable by the group.
+    \var ExeGroup The file is executable by the group.
+    \var ReadOther The file is readable by anyone.
+    \var WriteOther The file is writable by anyone.
+    \var ExeOther The file is executable by anyone.
 */
 
 /*!
diff --git a/qsstv/utils/reedsolomoncoder.cpp b/qsstv/utils/reedsolomoncoder.cpp
index 932a09b..81b1e2f 100644
--- a/qsstv/utils/reedsolomoncoder.cpp
+++ b/qsstv/utils/reedsolomoncoder.cpp
@@ -54,10 +54,9 @@ bool reedSolomonCoder::decode(QByteArray &ba,QString fn,QString &newFileName,QBy
 
   int i,j;
   int startOfSegment,row;
-//  QByteArray *t;
+  //  QByteArray *t;
 
   init();
-//  qDebug() << "size of ba" << ba.size();
   origFileName=fn;
   fpin.setFileName(fn);
 
@@ -77,14 +76,14 @@ bool reedSolomonCoder::decode(QByteArray &ba,QString fn,QString &newFileName,QBy
       bep_size++ ;
       tr_buf=tr_buf.leftJustified(bep_size*RSBSIZE,'\0');
     }
-//  qDebug() << "got" << got << "bep_size" << bep_size;
+
   int rest=tr_buf.count()%64;
-   if(rest!=0)
-     {
-       tr_buf=tr_buf.leftJustified(bep_size*RSBSIZE+(64-rest),'\0');
-//       qDebug() << "size of tr_buf extended" << tr_buf.count();
+  if(rest!=0)
+    {
+      tr_buf=tr_buf.leftJustified(bep_size*RSBSIZE+(64-rest),'\0');
 
-   }
+
+    }
   ec_buf.resize(bep_size*RSBSIZE);
   bk_buf.resize(bep_size*RSBSIZE);
 
@@ -105,17 +104,15 @@ bool reedSolomonCoder::decode(QByteArray &ba,QString fn,QString &newFileName,QBy
       totalSegments=erasuresArray.at(0);
       segmentLength=erasuresArray.at(1);
       numMissing=erasuresArray.count()-2;
-//      qDebug() << "numMissing" << numMissing;
       if(zeroPositions) delete zeroPositions;
       if(newZeroPositions) delete newZeroPositions;
       zeroPositions=new int[segmentLength*(totalSegments+1)];
       newZeroPositions=new int[256*bep_size];
-//      qDebug() << "newZeroPositions len" << (segmentLength*(totalSegments+1));
       for(i=0;i<(segmentLength*totalSegments);i++) zeroPositions[i]=-1;
     }
   else
     {
-      qDebug() << "no erasure info";
+      errorOut() << "no erasure info";
       return false;
     }
   /* now label the erasures positions */
@@ -142,20 +139,20 @@ bool reedSolomonCoder::decode(QByteArray &ba,QString fn,QString &newFileName,QBy
   distribute((byte *)tr_buf.data(),(byte *)ec_buf.data(),bep_size,rs_bsize,DECODE);
   if(!decode_and_write())
     {
-//      fpout.close();
+      //      fpout.close();
       return false;
     }
   //  fpin.close();
-//  fpout.close();
-//  tr_buf=ec_buf;
+  //  fpout.close();
+  //  tr_buf=ec_buf;
   if(uncorrectableFailures>0) return false;
-//  if(fpout.open(QIODevice::ReadOnly)<=0) return false;
-//  tr_buf=fpout.readAll();
+  //  if(fpout.open(QIODevice::ReadOnly)<=0) return false;
+  //  tr_buf=fpout.readAll();
   if (bep_size != (((unsigned char) tr_buf[1]) + ((unsigned char) tr_buf[2])*256 ))
     {
-      qDebug()<< "problems with bep_size coded in file";
-      qDebug() << "bep_size: " << bep_size <<" coded size: " << (((unsigned char) tr_buf[1]) + ((unsigned char) tr_buf[2])*256 ) ;
-      qDebug() << "bep_sizeaa: " << bep_size <<" coded size: " << (((unsigned char) ba[1]) + ((unsigned char)ba[2])*256 ) ;
+      errorOut()<< "problems with bep_size coded in file";
+      errorOut() << "bep_size: " << bep_size <<" coded size: " << (((unsigned char) tr_buf[1]) + ((unsigned char) tr_buf[2])*256 ) ;
+      errorOut() << "bep_sizeaa: " << bep_size <<" coded size: " << (((unsigned char) ba[1]) + ((unsigned char)ba[2])*256 ) ;
       return false;
     }
   coded_file_size = bep_size*rs_dsize - (int)tr_buf[0];
@@ -164,26 +161,19 @@ bool reedSolomonCoder::decode(QByteArray &ba,QString fn,QString &newFileName,QBy
 
 
   QFileInfo fileInfo(origFileName);
-  QString baseName=rxImagesPath+"/"+fileInfo.completeBaseName();
+  QString baseName=rxDRMImagesPath+"/"+fileInfo.completeBaseName();
   baseName.append(".");
   baseName.append(coded_file_ext);
 
-//  qDebug() <<" new filename: " << baseName;
-//  qDebug() << "tr_buf count before truncation: " << tr_buf.count();
   tr_buf=tr_buf.right(tr_buf.count()-7);
   tr_buf=tr_buf.left(coded_file_size);
-//  qDebug() << "coded_file_size: " << coded_file_size << "tr_buf count: " << tr_buf.count();
 
   newFileName=baseName;
-//  t=&tr_buf;
   baFile=tr_buf;
-//  fpout.close();
   if(uncorrectableFailures>0)
     {
-//      qDebug() <<"uncorrectable failures:" << uncorrectableFailures;
       return false;
     }
-
   return true;
 }
 
@@ -234,33 +224,23 @@ bool reedSolomonCoder::decode_and_write()
               eras_pos[nr_erasures++]= newZeroPositions[i*rs_bsize+j] ;
               if(nr_erasures>(rs_bsize-rs_dsize))
                 {
-//                  uncorrectableFailures++;
-//                  qDebug() << "ersasures too high" << nr_erasures;
                   return false;
                 }
-             }
+            }
         }
-//      qDebug()<< "block: " << i << "nr_erasures" << nr_erasures;
       if(nr_erasures>(rs_bsize-rs_dsize)) nr_erasures=rs_bsize-rs_dsize-1;
       int failure=rsd32(((byte *)ec_buf.data()+(i*rs_bsize)),eras_pos, nr_erasures);
       if (failure>0)
         {
-
           sumOfFailures+=failure;
         }
       else if (failure==-1)
         {
-
           uncorrectableFailures++;
           return false;
         }
-//      qDebug() <<"block: " << i << "nr_erasures:" << nr_erasures << "failure corrected:" << failure << "uncorrectable failure" << uncorrectableFailures;
-//      qDebug() << "ec_buf len" << ec_buf.count();
-        tr_buf.append(ec_buf.data()+i*rs_bsize,rs_dsize);
-//      fpout.write(ec_buf.data()+i*rs_bsize,rs_dsize);
-//      if(i==0) qDebug() << "rs write" <<((unsigned char) ec_buf[1]) << ((unsigned char)ec_buf[2]);
+      tr_buf.append(ec_buf.data()+i*rs_bsize,rs_dsize);
     }
-//  qDebug() << "trsize" << tr_buf.count() << "bepsize" << bep_size << "rs_bsize" << rs_bsize << "rs_dsize" << rs_dsize;
   return true;
 }
 
@@ -269,6 +249,7 @@ bool reedSolomonCoder::encode(QByteArray &ba,QString extension,eRSType rsType)
   int i,j;
   unsigned char dataByte;
   QByteArray temp;
+  QString suffix=extension.leftJustified(3,0);
   tr_buf=ba;
   fileType=rsType;
   rs_bsize=RSBSIZE;
@@ -285,7 +266,7 @@ bool reedSolomonCoder::encode(QByteArray &ba,QString extension,eRSType rsType)
   chunks = (got+7) / rs_dsize ;
   if (((got+7) % rs_dsize ) > 0) chunks++ ;
   bep_size=chunks;
-//  ec_buf.resize(bep_size*RSBSIZE);
+  //  ec_buf.resize(bep_size*RSBSIZE);
   ec_buf.clear();
   bk_buf.resize(bep_size*RSBSIZE);
 
@@ -295,9 +276,9 @@ bool reedSolomonCoder::encode(QByteArray &ba,QString extension,eRSType rsType)
   ec_buf.append(dataByte);
   dataByte = (unsigned char) (chunks/256) ;
   ec_buf.append(dataByte);
-  ec_buf.append(extension.toLatin1().at(0));newZeroPositions=NULL;
-  ec_buf.append(extension.toLatin1().at(1));
-  ec_buf.append(extension.toLatin1().at(2));
+  ec_buf.append(suffix.toLatin1().at(0));
+  ec_buf.append(suffix.toLatin1().at(1));
+  ec_buf.append(suffix.toLatin1().at(2));
   dataByte=0;
   ec_buf.append(dataByte);
   ec_buf.append(tr_buf.left(rs_dsize-7));
diff --git a/qsstv/utils/reedsolomoncoder.h b/qsstv/utils/reedsolomoncoder.h
index dcfe7a9..58c7d44 100644
--- a/qsstv/utils/reedsolomoncoder.h
+++ b/qsstv/utils/reedsolomoncoder.h
@@ -1,7 +1,7 @@
 #ifndef REEDSOLOMONCODER_H
 #define REEDSOLOMONCODER_H
-#include "qsstvglobal.h"
-#include "qsstvdefs.h"
+#include "appglobal.h"
+#include "appdefs.h"
 #include <QFile>
 #include <QByteArray>
 
diff --git a/qsstv/utils/supportfunctions.cpp b/qsstv/utils/supportfunctions.cpp
index a7f3b90..c973b71 100644
--- a/qsstv/utils/supportfunctions.cpp
+++ b/qsstv/utils/supportfunctions.cpp
@@ -20,10 +20,12 @@
 ***************************************************************************/
 
 #include "supportfunctions.h"
+#include "appglobal.h"
 #include <QDateTime>
 #include <QDebug>
 #include <stdarg.h>
-#include "qsstvglobal.h"
+#include "appglobal.h"
+#include "dirdialog.h"
 
 
 QString lastPath("");
@@ -221,8 +223,6 @@ void setValue(int val, QSlider *input)
 }
 
 
-
-
 bool browseGetFile(QLineEdit *le,QString deflt, const QString &filter)
 {
     dirDialog d((QWidget *)le,"Browse");
@@ -256,117 +256,6 @@ bool browseDir(QLineEdit *le,QString deflt)
 
 
 
-
-
-dirDialog::dirDialog(QWidget * parent,QString title)
-{
-    parentPtr=parent;
-    dialogTitle=title;
-}
-
-dirDialog::~dirDialog()
-{
-}
-
-
-/*!
-    \fn dirDialog::openFileName(const QString &path, const QString &filter, bool single)
-    \brief selection of a file
-
-    \param path  directory to open (preselected) if empty, the last accessed directory will be used
-    \param filter  types to select from (e.g. mydirs*)
-    \param single  allows selection of more than one file if true
-    \return if canceled or no selection then returns an empty string else return string containing absolute filename
-*/
-
-
-QString dirDialog::openFileName(const QString &path, const QString &filter)
-{
-    QString fn;
-  if (path.isEmpty() && lastPath.isEmpty())
-    {
-      lastPath=QDir::homePath();
-    }
-  else if (!path.isEmpty())
-    {
-      lastPath=path;
-    }
-
-  fn=QFileDialog::getOpenFileName(parentPtr,dialogTitle,lastPath,filter);
-  if(!fn.isEmpty())
-  {
-      QFileInfo  fi(fn);
-        lastPath=fi.absolutePath();
-  }
-  return fn;
-}
-
-/*!
-    \fn dirDialog::openDirName(const QString &path, const QString &filter)
-    \brief selection of a directory
-
-    \param path directory to open (preselected)
-    \param filter    types to select from (e.g. mydirs*)
-
-    \return if canceled or no selection then return an empty string else return string containing absolute dirname
-*/
-
-QString dirDialog::openDirName(const QString &path)
-{
-  QString fn;
-  if ((path.isEmpty()) && lastPath.isEmpty())
-    {
-      lastPath=QDir::homePath();
-    }
-  else if (!path.isEmpty())
-    {
-      lastPath=path;
-    }
-  fn=QFileDialog::getExistingDirectory(parentPtr,dialogTitle,lastPath);
-  if(!fn.isEmpty())
-  {
-      lastPath=fn;
-  }
-  return fn;
-}
-
-/*!
-    \fn dirDialog::saveFileName(const QString &path, const QString &filter,QString extension)
-    \brief Save a file to disk
-
-    Saves a file to disk. A dialogbox is opened with \a startWith directory (or /dir/subdir/..../filename) preselected
-    \param path directory to open (can include filename to preselect)
-    \param filter    file types to select from (e.g. *.txt *.doc)
-    \param extension if extension is not empty or NULL, thenn this string will be appended to the filename. A dot will automatically be insterted (i.e specify "txt" not ".txt").
-    \return if canceled or no selection then return an empty string else return string containing absolute filename.
-*/
-
-QString dirDialog::saveFileName(const QString &path, const QString &filter, QString extension)
-{
-  QString fn;
-  if ((path.isEmpty()) && lastPath.isEmpty())
-    {
-      lastPath=QDir::currentPath();
-    }
-  else if (!path.isEmpty())
-    {
-      lastPath=path;
-    }
-  QString exten(extension);
-  fn=QFileDialog::getSaveFileName(parentPtr,dialogTitle,lastPath,filter);
-  if(fn.isEmpty()) return fn;
-  QFileInfo  fi(fn);
-  if(!exten.isEmpty())
-    {
-      if(fi.suffix()=="")
-        {
-          fi.setFile(fi.absoluteFilePath()+"."+exten);
-        }
-    }
-    lastPath=fi.absolutePath();
-  return fi.absoluteFilePath();
-}
-
 void deleteFiles(QString dirPath,QString extension)
 {
   int i;
@@ -418,14 +307,14 @@ bool trash(QString filename,bool forceDelete)
 
   if((!trDir.exists()) || (!infoDir.exists()) || (!filesDir.exists()))
     {
-      qDebug() << "Trash folder or one of its components does not exist";
+      errorOut() << "Trash folder or one of its components does not exist";
       if(forceDelete) orgFile.remove();
       return false;
     }
 
   if(!infoFile.open(QIODevice::WriteOnly))
   {
-    qDebug() << QString("Trash folder: can't open %1 for writing").arg(infoFile.fileName());
+   errorOut() << QString("Trash folder: can't open %1 for writing").arg(infoFile.fileName());
     if(forceDelete) orgFile.remove();
     return false;
   }
@@ -436,175 +325,13 @@ bool trash(QString filename,bool forceDelete)
   target=QString("%1").arg(modifiedFile.fileName());
   if(!trashFile.rename(filename,target))
   {
-    qDebug() << QString("Trash folder: can't rename %1 to %2").arg(filename).arg(target);
+    errorOut() << QString("Trash folder: can't rename %1 to %2").arg(filename).arg(target);
     if(forceDelete) orgFile.remove();
     return false;
   }
   return true;
 }
 
-void arrayComplexDump(QString label,CVectorEx<_COMPLEX> data,unsigned int len,bool toAux)
-{
-  CVectorEx<_COMPLEX> vct=data;
-  _COMPLEX c;
-  unsigned int i,j;
-//  unsigned int len;
-//  len=vct.Size()/8;
-  QString dumpStr,tmp;
-
-  for( i=0;i<len;i+=16)
-    {
-      dumpStr=label+" ";
-      for(j=0;(j<16)&&((i+j)<len);j++)
-        {
-          c=vct[i+j];
-          tmp=QString::number(c.real())+","+QString::number(c.imag());
-//          while(tmp.length()<2) tmp.prepend("0");
-          dumpStr+=tmp+" ";
-        }
-      dumpStr.chop(1);
-      if(toAux)
-        {
-          logfile->addToAux(dumpStr);
-        }
-      else
-        {
-          addToLog(dumpStr,LOGALL);
-        }
-    }
-}
-
-
-void arrayBinDump(QString label,CVector<_BINARY> data,unsigned int len,bool toAux)
-{
-  CVector<_BINARY> vct=data;
-  unsigned int i,j;
-//  unsigned int len;
-//  len=vct.Size()/8;
-  QString dumpStr,tmp;
-
-  for( i=0;i<len;i+=16)
-    {
-      dumpStr=label+" ";
-      for(j=0;(j<16)&&((i+j)<len);j++)
-        {
-          tmp=QString::number(vct.Separate(8),16).right(2);
-          while(tmp.length()<2) tmp.prepend("0");
-          dumpStr+=tmp+" ";
-        }
-      dumpStr.chop(1);
-      if(toAux)
-        {
-          logfile->addToAux(dumpStr);
-        }
-      else
-        {
-          addToLog(dumpStr,LOGALL);
-        }
-    }
-}
-
-
-void arrayDump(QString label,short int *data, unsigned int len,bool toAux)
-{
-  unsigned int i,j;
-  QString dumpStr,tmp;
-  for( i=0;i<len;i+=16)
-    {
-      dumpStr=label+" ";
-      for(j=0;(j<16)&&((i+j)<len);j++)
-        {
-          tmp=QString::number(data[i+j],16).right(4);
-          while(tmp.length()<4) tmp.prepend("0");
-          dumpStr+=tmp+" ";
-        }
-      dumpStr.chop(1);
-      if(toAux)
-        {
-          logfile->addToAux(dumpStr);
-        }
-      else
-        {
-          addToLog(dumpStr,LOGALL);
-        }
-    }
-}
-
-void arrayDump(QString label,int *data, unsigned int len,bool toAux)
-{
-  unsigned int i,j;
-  QString dumpStr,tmp;
-  for( i=0;i<len;i+=16)
-    {
-      dumpStr=label+" ";
-      for(j=0;(j<16)&&((i+j)<len);j++)
-        {
-          tmp=QString::number(data[i+j],16).right(4);
-          while(tmp.length()<4) tmp.prepend("0");
-          dumpStr+=tmp+" ";
-        }
-      dumpStr.chop(1);
-      if(toAux)
-        {
-          logfile->addToAux(dumpStr);
-        }
-      else
-        {
-          addToLog(dumpStr,LOGALL);
-        }
-    }
-}
-
-void arrayDump(QString label, float *data, unsigned int len, bool toAux)
-{
-  unsigned int i,j;
-  QString dumpStr,tmp;
-  for( i=0;i<len;i+=16)
-    {
-      dumpStr=label+" ";
-      for(j=0;(j<16)&&((i+j)<len);j++)
-        {
-          tmp=QString::number(data[i+j]).right(8);
-          while(tmp.length()<8) tmp.prepend(" ");
-          dumpStr+=tmp+" ";
-        }
-      dumpStr.chop(1);
-      if(toAux)
-        {
-          logfile->addToAux(dumpStr);
-        }
-      else
-        {
-          addToLog(dumpStr,LOGALL);
-        }
-    }
-}
-
-
-void arrayDump(QString label, quint32* data, unsigned int len, bool toAux)
-{
-  unsigned int i,j;
-  QString dumpStr,tmp;
-  for( i=0;i<len;i+=16)
-    {
-      dumpStr=label+" ";
-      for(j=0;(j<16)&&((i+j)<len);j++)
-        {
-          tmp=QString::number(data[i+j],16).right(8);
-          while(tmp.length()<8) tmp.prepend("0");
-          dumpStr+=tmp+" ";
-        }
-      dumpStr.chop(1);
-      if(toAux)
-        {
-          logfile->addToAux(dumpStr);
-        }
-      else
-        {
-          addToLog(dumpStr,LOGALL);
-        }
-    }
-}
 
 timingAnalyser::timingAnalyser()
 {
diff --git a/qsstv/utils/supportfunctions.h b/qsstv/utils/supportfunctions.h
index 7819080..cc36948 100644
--- a/qsstv/utils/supportfunctions.h
+++ b/qsstv/utils/supportfunctions.h
@@ -12,7 +12,7 @@
 #include <QSlider>
 #include <QPlainTextEdit>
 #include <QTime>
-#include "vector.h"
+
 
 /** \file */
 
@@ -66,26 +66,10 @@ bool browseDir(QLineEdit *le, QString deflt);
 void deleteFiles(QString dirPath,QString extension);
 
 bool trash(QString filename,bool forceDelete);
-void arrayDump(QString label, short int *data, unsigned int len, bool toAux);
-void arrayDump(QString label, int *data, unsigned int len, bool toAux);
-void arrayDump(QString label,float *data, unsigned int len,bool toAux);
-void arrayDump(QString label, quint32 *data, unsigned int len, bool toAux);
-void arrayBinDump(QString label, CVector<_BINARY> data, unsigned int len, bool toAux);
-void arrayComplexDump(QString label,CVectorEx<_COMPLEX> data,unsigned int len,bool toAux);
 
 
-class dirDialog
-{
-public:
-    dirDialog(QWidget *parent,QString title="");
-    ~dirDialog();
-    QString openFileName(const QString &startWith, const QString &filter="*");
-    QString openDirName(const QString &path);
-    QString saveFileName(const QString &path, const QString &filter,QString extension);
-private:
-    QWidget * parentPtr;
-    QString  dialogTitle;
-};
+
+
 
 class timingAnalyser
 {
diff --git a/qsstv/utils/vector.h b/qsstv/utils/vector.h
index f67f915..b06827d 100644
--- a/qsstv/utils/vector.h
+++ b/qsstv/utils/vector.h
@@ -30,7 +30,7 @@
 #define VECTOR_H__3B0BA660_CA6LIUBEFIB2B_23E7A0D31912__INCLUDED_
 
 //#include "drmtx/common/GlobalDefinitions.h"
-#include "qsstvdefs.h"
+#include "appdefs.h"
 using namespace std; /* Because of the library: "complex" */
 #include <string>
 #include <stdio.h>
diff --git a/qsstv/videocapt/cameradialog.cpp b/qsstv/videocapt/cameradialog.cpp
new file mode 100644
index 0000000..cdd88b5
--- /dev/null
+++ b/qsstv/videocapt/cameradialog.cpp
@@ -0,0 +1,278 @@
+/**************************************************************************
+*   Copyright (C) 2000-2012 by Johan Maes                                 *
+*   on4qz at telenet.be                                                      *
+*   http://users.telenet.be/on4qz                                         *
+*                                                                         *
+*   This program is free software; you can redistribute it and/or modify  *
+*   it under the terms of the GNU General Public License as published by  *
+*   the Free Software Foundation; either version 2 of the License, or     *
+*   (at your option) any later version.                                   *
+*                                                                         *
+*   This program is distributed in the hope that it will be useful,       *
+*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+*   GNU General Public License for more details.                          *
+*                                                                         *
+*   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.,                                       *
+*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+***************************************************************************/
+
+#include "cameradialog.h"
+#include "ui_cameradialog.h"
+
+#include "appglobal.h"
+#include <libv4l2.h>
+#include "imagesettings.h"
+#include "videocapture.h"
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <cerrno>
+#include <cstring>
+
+
+#include <QMessageBox>
+#include <QPalette>
+//#include <QtWidgets>
+//#include <QDebug>
+
+cameraDialog::cameraDialog(QWidget *parent) :
+  QDialog(parent),
+  ui(new Ui::cameraDialog)
+{
+  ui->setupUi(this);
+  listCameraDevices();
+  connect(ui->settingsButton,SIGNAL(clicked()),SLOT(slotSettings()));
+  ui->devicesComboBox->setCurrentIndex(0);
+  imageSettings settingsDialog(cameraList.at(0).deviceName);
+  cameraActive=false;
+  videoCapturePtr=new videoCapture;
+  connect(ui->devicesComboBox,SIGNAL(currentIndexChanged(int)),SLOT(slotDeviceChanged(int)));
+  connect(ui->formatsComboBox,SIGNAL(currentIndexChanged(int)),SLOT(slotFormatChanged(int)));
+  connect(ui->sizeComboBox,SIGNAL(currentIndexChanged(int)),SLOT(slotSizeChanged(int)));
+}
+
+cameraDialog::~cameraDialog()
+{
+  delete ui;
+}
+
+int cameraDialog::exec()
+{
+  if(!restartCapturing(true))
+    {
+      QMessageBox::warning(this,"Capturing","Unable to start capturing");
+      return QDialog::Rejected;
+    }
+  int result;
+  addToLog("cameracontrol exec",LOGCAM);
+  result=QDialog::exec();
+  killTimer(timerID);
+  videoCapturePtr->stopStreaming();
+  videoCapturePtr->close();
+  if(result==QDialog::Accepted) return true;
+  return false;
+}
+
+
+void cameraDialog::timerEvent(QTimerEvent *)
+ {
+     if(videoCapturePtr->getFrame())
+      {
+        ui->viewFinder->openImage(*videoCapturePtr->getImage());
+      }
+ }
+
+QImage *cameraDialog::getImage()
+{
+  return videoCapturePtr->getImage();
+}
+
+
+
+
+void cameraDialog::slotSettings()
+{
+  imageSettings settingsDialog(cameraList.at(ui->devicesComboBox->currentIndex()).deviceName);
+  settingsDialog.exec();
+}
+
+void cameraDialog::listCameraDevices()
+{
+  int i;
+  cameraList.clear();
+  QDir devDir("/dev");
+  QStringList devList;
+  devDir.setFilter(QDir::System| QDir::NoSymLinks);
+  devDir.setSorting(QDir::Name);
+  devDir.setNameFilters(QStringList("video*"));
+  devList=devDir.entryList();
+  getCameraInfo(devList);
+  for(i=0;i<cameraList.count();i++)
+    {
+      ui->devicesComboBox->addItem(cameraList.at(i).deviceDescription);
+    }
+  setupFormatComboBox(cameraList.at(0));
+}
+
+
+void cameraDialog::setupFormatComboBox(scameraDevice cd)
+{
+  int i;
+  ui->formatsComboBox->blockSignals(true);
+  ui->formatsComboBox->clear();
+  for(i=0;i<cd.formats.count();i++)
+    {
+      ui->formatsComboBox->addItem(cd.formats.at(i).description);
+    }
+  ui->formatsComboBox->setCurrentIndex(cd.formatIdx);
+  ui->formatsComboBox->blockSignals(false);
+  setupSizeComboBox(cd.formats.at(cd.formatIdx));
+}
+
+void cameraDialog::setupSizeComboBox(sformats frmat)
+{
+  int i;
+  ui->sizeComboBox->blockSignals(true);
+  ui->sizeComboBox->clear();
+  for(i=0;i<frmat.cameraSizes.count();i++)
+    {
+      ui->sizeComboBox->addItem(frmat.cameraSizes.at(i).description);
+    }
+  ui->sizeComboBox->setCurrentIndex(frmat.sizeIdx);
+  ui->sizeComboBox->blockSignals(false);
+}
+
+
+void cameraDialog::getCameraInfo(QStringList devList)
+{
+  int fd;
+  int i;
+  bool ok=true;
+  QString camDev;
+
+  QList <sformats> formats;
+
+  for(i=0;i<devList.count();i++)
+    {
+      ok=true;
+      struct v4l2_capability cap;
+      memset(&cap, 0, sizeof(cap));
+      camDev=QString("/dev/")+devList.at(i);
+      fd = v4l2_open(camDev.toLatin1().data(), O_RDWR, 0);
+      if(fd < 0)
+        {
+          QString msg=QString("Unable to open file %1\n%2").arg(camDev).arg(strerror(errno));
+          QMessageBox::warning(this,"v4l2ucp: Unable to open file", msg, "OK");
+          continue;
+        }
+
+      if(v4l2_ioctl(fd, VIDIOC_QUERYCAP, &cap) == -1)
+        {
+          QString msg=QString("%1 is not a V4L2 device").arg(camDev);
+          QMessageBox::warning(this, "Camera selection error", msg, "OK");
+          ok=false;
+        }
+      formats=getFormatList(fd);
+      if(ok)
+        {
+          cameraList.append(scameraDevice(camDev,(const char *)cap.card,(const char *)cap.driver,(const char *)cap.bus_info,formats));
+        }
+      v4l2_close(fd);
+    }
+}
+
+QString cameraDialog::pixelFormatStr(int pixelFormat)
+{
+  QString t;
+  t=pixelFormat&0xFF;
+  t+=(pixelFormat>>8)&0xFF;
+  t+=(pixelFormat>>16)&0xFF;
+  t+=(pixelFormat>>24)&0xFF;
+  return t;
+}
+
+QList<sformats> cameraDialog::getFormatList(int fd)
+{
+  int ret;
+  QList<sformats> formatsList;
+  v4l2_frmsizeenum frm;
+  struct v4l2_fmtdesc fmt;
+  QList<scameraSizes> scsList;
+
+  int i = 0;
+  do
+    {
+      scsList.clear();
+      memset(&fmt, 0, sizeof fmt);
+      fmt.index = i;
+      fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+      if ((ret = v4l2_ioctl(fd, VIDIOC_ENUM_FMT, &fmt)) < 0)
+        break;
+      else
+        {
+          frm.index=0;
+          frm.pixel_format=fmt.pixelformat;
+          while(v4l2_ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &frm) >=0)
+            {
+              if(frm.type==V4L2_FRMSIZE_TYPE_DISCRETE)
+                {
+                   scsList.append(scameraSizes(frm.discrete.width,frm.discrete.height,QString("%1x%2").arg(frm.discrete.width).arg(frm.discrete.height)));
+                }
+              frm.index++;
+            }
+          formatsList.append(sformats(fmt.pixelformat,pixelFormatStr(fmt.pixelformat),scsList));
+        }
+      i++;
+    }
+  while (ret != EINVAL);
+  return formatsList;
+}
+
+
+void cameraDialog::slotDeviceChanged(int idx)
+{
+  setupFormatComboBox(cameraList.at(idx));
+  slotFormatChanged(cameraList.at(idx).formatIdx);
+}
+
+void cameraDialog::slotFormatChanged(int idx)
+{
+  setupSizeComboBox(cameraList.at(ui->devicesComboBox->currentIndex()).formats.at(idx));
+  slotSizeChanged(cameraList.at(ui->devicesComboBox->currentIndex()).formats.at(idx).sizeIdx);
+  cameraList[(ui->devicesComboBox->currentIndex())].formatIdx=idx;
+
+}
+
+void cameraDialog::slotSizeChanged(int idx)
+{
+  cameraList[ui->devicesComboBox->currentIndex()].formats[ui->formatsComboBox->currentIndex()].sizeIdx=idx;
+  restartCapturing();
+}
+
+bool cameraDialog::restartCapturing(bool first)
+{
+  if(!first)
+    {
+      killTimer(timerID);
+      videoCapturePtr->stopStreaming();
+      videoCapturePtr->close();
+    }
+  if(!videoCapturePtr->open(cameraList.at(ui->devicesComboBox->currentIndex()).deviceName))
+    {
+      return false;
+    }
+  if(!videoCapturePtr->init(cameraList.at(ui->devicesComboBox->currentIndex()).formats.at(ui->formatsComboBox->currentIndex()).format,
+                        cameraList.at(ui->devicesComboBox->currentIndex()).formats.at(ui->formatsComboBox->currentIndex()).cameraSizes.at(ui->sizeComboBox->currentIndex()).width,
+                        cameraList.at(ui->devicesComboBox->currentIndex()).formats.at(ui->formatsComboBox->currentIndex()).cameraSizes.at(ui->sizeComboBox->currentIndex()).height))
+    {
+      return false;
+    }
+  cameraActive=true;
+  videoCapturePtr->startSnapshots();
+  timerID=startTimer(50);
+  return true;
+}
+
+
diff --git a/qsstv/videocapt/cameradialog.h b/qsstv/videocapt/cameradialog.h
new file mode 100644
index 0000000..a3fe024
--- /dev/null
+++ b/qsstv/videocapt/cameradialog.h
@@ -0,0 +1,99 @@
+#ifndef CAMERADIALOG_H
+#define CAMERADIALOG_H
+
+#include <QDialog>
+
+namespace Ui {
+class cameraDialog;
+}
+
+class videoCapture;
+
+
+
+struct scameraSizes
+{
+  scameraSizes(int w,int h,QString desc)
+  {
+    description=desc;
+    width=w;
+    height=h;
+  }
+  QString description;
+  int width;
+  int height;
+};
+
+struct sformats
+{
+  sformats(int frmt,QString desc,QList<scameraSizes> cs)
+  {
+    format=frmt;
+    description=desc;
+    cameraSizes=cs;
+    sizeIdx=0;
+  }
+  int format;
+  QString description;
+  int sizeIdx;
+  QList<scameraSizes> cameraSizes;
+};
+
+struct scameraDevice
+{
+  scameraDevice(QString devName,QString devDescription,QString driv,QString bus,QList<sformats> frmts)
+  {
+    deviceName=devName;
+    deviceDescription=devDescription;
+    driver=driv;
+    busInfo=bus;
+    formats=frmts;
+    formatIdx=0;
+  }
+  QString deviceName;
+  QString deviceDescription;
+  QString driver;
+  QString busInfo;
+  QList<sformats> formats;
+  int formatIdx;
+};
+
+
+
+
+class cameraDialog : public QDialog
+{
+  Q_OBJECT
+
+public:
+  explicit cameraDialog(QWidget *parent = 0);
+  ~cameraDialog();
+  int exec();
+  QImage *getImage();
+private slots:
+  void slotSettings();
+  void slotDeviceChanged(int idx);
+  void slotFormatChanged(int idx);
+  void slotSizeChanged(int idx);
+
+private:
+
+  Ui::cameraDialog *ui;
+  void listCameraDevices();
+  QList<scameraDevice> cameraList;
+
+  void getCameraInfo(QStringList devList);
+  videoCapture *videoCapturePtr;
+  bool cameraActive;
+  void timerEvent(QTimerEvent *event);
+  QString pixelFormatStr(int pixelFormat);
+  QList<sformats> getFormatList(int fd);
+  void setupFormatComboBox(scameraDevice cd);
+  void setupSizeComboBox(sformats frmat);
+  int timerID;
+  bool restartCapturing(bool first=false);
+
+};
+
+#endif // CAMERADIALOG_H
+
diff --git a/qsstv/videocapt/cameradialog.ui b/qsstv/videocapt/cameradialog.ui
new file mode 100644
index 0000000..acf12f0
--- /dev/null
+++ b/qsstv/videocapt/cameradialog.ui
@@ -0,0 +1,229 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>cameraDialog</class>
+ <widget class="QDialog" name="cameraDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>585</width>
+    <height>361</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout_2">
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <widget class="QStackedWidget" name="stackedWidget">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+         <horstretch>1</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="palette">
+        <palette>
+         <active>
+          <colorrole role="Base">
+           <brush brushstyle="SolidPattern">
+            <color alpha="255">
+             <red>255</red>
+             <green>255</green>
+             <blue>255</blue>
+            </color>
+           </brush>
+          </colorrole>
+          <colorrole role="Window">
+           <brush brushstyle="SolidPattern">
+            <color alpha="255">
+             <red>145</red>
+             <green>145</green>
+             <blue>145</blue>
+            </color>
+           </brush>
+          </colorrole>
+         </active>
+         <inactive>
+          <colorrole role="Base">
+           <brush brushstyle="SolidPattern">
+            <color alpha="255">
+             <red>255</red>
+             <green>255</green>
+             <blue>255</blue>
+            </color>
+           </brush>
+          </colorrole>
+          <colorrole role="Window">
+           <brush brushstyle="SolidPattern">
+            <color alpha="255">
+             <red>145</red>
+             <green>145</green>
+             <blue>145</blue>
+            </color>
+           </brush>
+          </colorrole>
+         </inactive>
+         <disabled>
+          <colorrole role="Base">
+           <brush brushstyle="SolidPattern">
+            <color alpha="255">
+             <red>145</red>
+             <green>145</green>
+             <blue>145</blue>
+            </color>
+           </brush>
+          </colorrole>
+          <colorrole role="Window">
+           <brush brushstyle="SolidPattern">
+            <color alpha="255">
+             <red>145</red>
+             <green>145</green>
+             <blue>145</blue>
+            </color>
+           </brush>
+          </colorrole>
+         </disabled>
+        </palette>
+       </property>
+       <property name="currentIndex">
+        <number>0</number>
+       </property>
+       <widget class="QWidget" name="viewfinderPage">
+        <layout class="QGridLayout" name="gridLayout_5">
+         <item row="0" column="0">
+          <widget class="imageViewer" name="viewFinder">
+           <property name="text">
+            <string>TextLabel</string>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </widget>
+       <widget class="QWidget" name="previewPage">
+        <layout class="QGridLayout" name="gridLayout_4">
+         <item row="0" column="0">
+          <widget class="QLabel" name="lastImagePreviewLabel">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="frameShape">
+            <enum>QFrame::Box</enum>
+           </property>
+           <property name="text">
+            <string/>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </widget>
+      </widget>
+     </item>
+     <item>
+      <layout class="QVBoxLayout" name="verticalLayout">
+       <item>
+        <widget class="QPushButton" name="settingsButton">
+         <property name="enabled">
+          <bool>true</bool>
+         </property>
+         <property name="text">
+          <string>Settings</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QLabel" name="label">
+         <property name="text">
+          <string>Devices</string>
+         </property>
+         <property name="alignment">
+          <set>Qt::AlignCenter</set>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QComboBox" name="devicesComboBox"/>
+       </item>
+       <item>
+        <widget class="QComboBox" name="formatsComboBox"/>
+       </item>
+       <item>
+        <widget class="QComboBox" name="sizeComboBox"/>
+       </item>
+       <item>
+        <spacer name="verticalSpacer">
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>20</width>
+           <height>40</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+      </layout>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>imageViewer</class>
+   <extends>QLabel</extends>
+   <header>imageviewer.h</header>
+  </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>cameraDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>cameraDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/qsstv/videocapt/imagesettings.cpp b/qsstv/videocapt/imagesettings.cpp
new file mode 100644
index 0000000..e54989e
--- /dev/null
+++ b/qsstv/videocapt/imagesettings.cpp
@@ -0,0 +1,256 @@
+/**************************************************************************
+*   Copyright (C) 2000-2012 by Johan Maes                                 *
+*   on4qz at telenet.be                                                      *
+*   http://users.telenet.be/on4qz                                         *
+*                                                                         *
+*   This program is free software; you can redistribute it and/or modify  *
+*   it under the terms of the GNU General Public License as published by  *
+*   the Free Software Foundation; either version 2 of the License, or     *
+*   (at your option) any later version.                                   *
+*                                                                         *
+*   This program is distributed in the hope that it will be useful,       *
+*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+*   GNU General Public License for more details.                          *
+*                                                                         *
+*   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.,                                       *
+*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+*                                                                         *
+*                                                                         *
+*                                                                         *
+* Part of this software has been copied from examples of the Qt Toolkit.  *
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**   * Redistributions of source code must retain the above copyright
+**     notice, this list of conditions and the following disclaimer.
+**   * Redistributions in binary form must reproduce the above copyright
+**     notice, this list of conditions and the following disclaimer in
+**     the documentation and/or other materials provided with the
+**     distribution.
+**   * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+**     of its contributors may be used to endorse or promote products derived
+**     from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "imagesettings.h"
+#include "ui_imagesettings.h"
+#include "v4l2control.h"
+
+#include <QComboBox>
+#include <QDebug>
+#include <libv4l2.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <cerrno>
+#include <QMessageBox>
+#include <QLabel>
+#include <QScrollArea>
+
+
+imageSettings::imageSettings(QString cameraDevice, QWidget *parent) :   QDialog(parent)
+{
+  camDev=cameraDevice.toLatin1();
+  ui= new Ui::imageSettingsUi;
+  ui->setupUi(this);
+  gridLayout=NULL;
+  loadCapabilities();
+  ui->buttonBox->button(QDialogButtonBox::Ok)->setDefault(false);
+  ui->buttonBox->button(QDialogButtonBox::Cancel)->setDefault(false);
+}
+
+imageSettings::~imageSettings()
+{
+  delete ui;
+}
+
+
+
+bool imageSettings::loadCapabilities()
+{
+  int fd;
+  struct v4l2_capability cap;
+  struct v4l2_queryctrl ctrl;
+  row=0;
+  fd = v4l2_open(camDev, O_RDWR, 0);
+  if(fd < 0)
+    {
+      QString msg=
+      msg.sprintf("Unable to open file %s\n%s", camDev.constData(), strerror(errno));
+      QMessageBox::warning(NULL, "v4l2ucp: Unable to open file", msg, "OK");
+      return false;
+    }
+
+  if(v4l2_ioctl(fd, VIDIOC_QUERYCAP, &cap) == -1) {
+      QString msg;
+      msg.sprintf("%s is not a V4L2 device", camDev.constData());
+      QMessageBox::warning(NULL, "v4l2ucp: Not a V4L2 device", msg, "OK");
+      return false;
+    }
+  ui->driverLabel->setText((const char *)cap.driver);
+  ui->cardLabel->setText((const char *)cap.card);
+  ui->busLabel->setText((const char *)cap.bus_info);
+  ui->deviceLabel->setText(camDev.constData());
+
+#ifdef V4L2_CTRL_FLAG_NEXT_CTRL
+  /* Try the extended control API first */
+  ctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL;
+  if(v4l2_ioctl (fd, VIDIOC_QUERYCTRL, &ctrl)==0)
+    {
+      do
+        {
+          addControl(ctrl, fd);
+          ctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
+        }
+      while(v4l2_ioctl (fd, VIDIOC_QUERYCTRL, &ctrl)==0);
+    }
+  else
+#endif
+    {
+      /* Fall back on the standard API */
+      /* Check all the standard controls */
+      for(int i=V4L2_CID_BASE; i<V4L2_CID_LASTP1; i++) {
+          ctrl.id = i;
+          if(v4l2_ioctl(fd, VIDIOC_QUERYCTRL, &ctrl) == 0) {
+              addControl(ctrl, fd);
+            }
+        }
+
+      /* Check any custom controls */
+      for(int i=V4L2_CID_PRIVATE_BASE; ; i++) {
+          ctrl.id = i;
+          if(v4l2_ioctl(fd, VIDIOC_QUERYCTRL, &ctrl) == 0) {
+              addControl(ctrl, fd);
+            } else {
+              break;
+            }
+        }
+    }
+  return true;
+}
+
+void imageSettings::addControl(struct v4l2_queryctrl &ctrl, int fd)
+{
+  QWidget *w = NULL;
+
+  if(ctrl.flags & V4L2_CTRL_FLAG_DISABLED) return;
+  if((ctrl.type!=V4L2_CTRL_TYPE_CTRL_CLASS) && (gridLayout==NULL))
+     {
+      addNewTab("Controls");
+    }
+
+  switch(ctrl.type)
+    {
+    case V4L2_CTRL_TYPE_INTEGER:
+      w = new V4L2IntegerControl(fd, ctrl, grid);
+      break;
+    case V4L2_CTRL_TYPE_BOOLEAN:
+      w = new V4L2BooleanControl(fd, ctrl, grid);
+      break;
+    case V4L2_CTRL_TYPE_MENU:
+      w = new V4L2MenuControl(fd, ctrl, grid);
+      break;
+    case V4L2_CTRL_TYPE_BUTTON:
+      w = new V4L2ButtonControl(fd, ctrl, grid);
+      break;
+
+    case V4L2_CTRL_TYPE_CTRL_CLASS:
+      {
+        addNewTab(QString((const char *)ctrl.name));
+        return;
+      }
+    case V4L2_CTRL_TYPE_INTEGER64:
+    default:
+      break;
+    }
+
+  if(!w) {
+      new QLabel("Unknown control", grid);
+      new QLabel(grid);
+      new QLabel(grid);
+      return;
+    }
+  QLabel *l = new QLabel((const char *)ctrl.name, grid);
+  gridLayout->addWidget(l,row,0);
+  gridLayout->addWidget(w,row,1);
+  if(ctrl.flags & V4L2_CTRL_FLAG_GRABBED)
+    {
+      w->setEnabled(false);
+    }
+  else
+    {
+      w->setEnabled(true);
+    }
+
+  QPushButton *pb;
+  pb = new QPushButton("Update", grid);
+  gridLayout->addWidget(pb,row,2);
+  QObject::connect( pb, SIGNAL(clicked()), w, SLOT(updateStatus()) );
+
+  if(ctrl.type == V4L2_CTRL_TYPE_BUTTON)
+    {
+      l = new QLabel(grid);
+      gridLayout->addWidget(l,row,3);
+    }
+  else
+    {
+      pb = new QPushButton("Reset", grid);
+      gridLayout->addWidget(pb,row,3);
+      QObject::connect(pb, SIGNAL(clicked()), w, SLOT(resetToDefault()) );
+
+    }
+  row++;
+}
+
+void imageSettings::addNewTab(QString tabName)
+{
+  QVBoxLayout *vLayout;
+  QWidget *tab=new QWidget();
+  vLayout = new QVBoxLayout(tab);
+  QScrollArea *scrollArea = new QScrollArea(tab);
+  scrollArea->setWidgetResizable(true);
+  grid = new QWidget();
+  grid->setGeometry(QRect(0, 0, 592, 100));
+  scrollArea->setWidget(grid);
+  vLayout->addWidget(scrollArea);
+  ui->tabWidget->addTab(tab, tabName);
+  gridLayout = new QGridLayout();
+  grid->setLayout(gridLayout);
+  gridLayout->setSpacing(0);
+  gridLayout->setMargin(1);
+  gridLayout->setContentsMargins(0, 0, 0, 0);
+}
+
+void imageSettings::showEvent(QShowEvent * event)
+{
+  ui->buttonBox->button(QDialogButtonBox::Ok)->setDefault(false);
+  ui->buttonBox->button(QDialogButtonBox::Cancel)->setDefault(false);
+  QDialog::showEvent(event);
+}
diff --git a/qsstv/videocapt/imagesettings.h b/qsstv/videocapt/imagesettings.h
new file mode 100644
index 0000000..28cd3c0
--- /dev/null
+++ b/qsstv/videocapt/imagesettings.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**   * Redistributions of source code must retain the above copyright
+**     notice, this list of conditions and the following disclaimer.
+**   * Redistributions in binary form must reproduce the above copyright
+**     notice, this list of conditions and the following disclaimer in
+**     the documentation and/or other materials provided with the
+**     distribution.
+**   * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+**     of its contributors may be used to endorse or promote products derived
+**     from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef IMAGESETTINGS_H
+#define IMAGESETTINGS_H
+
+#include <linux/types.h>          /* for videodev2.h */
+#include <linux/videodev2.h>
+
+#include <QDialog>
+#include <QGridLayout>
+
+
+class QCameraImageCapture;
+
+namespace Ui
+{
+class imageSettingsUi;
+}
+
+
+class imageSettings : public QDialog
+{
+    Q_OBJECT
+
+public:
+    imageSettings(QString cameraDevice, QWidget *parent = 0);
+    ~imageSettings();
+
+
+private:
+    QByteArray camDev;
+    Ui::imageSettingsUi *ui;
+    QCameraImageCapture *imagecapture;
+    bool loadCapabilities();
+    void addControl(struct v4l2_queryctrl &ctrl, int fd);
+    void addNewTab(QString tabName);
+    QWidget *grid;
+    QGridLayout *gridLayout;
+    int row;
+    void showEvent(QShowEvent * event);
+
+};
+
+#endif // IMAGESETTINGS_H
diff --git a/qsstv/videocapt/imagesettings.ui b/qsstv/videocapt/imagesettings.ui
new file mode 100644
index 0000000..65767b2
--- /dev/null
+++ b/qsstv/videocapt/imagesettings.ui
@@ -0,0 +1,168 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>imageSettingsUi</class>
+ <widget class="QDialog" name="imageSettingsUi">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>600</width>
+    <height>320</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout_2">
+   <item>
+    <widget class="QTabWidget" name="tabWidget">
+     <property name="currentIndex">
+      <number>0</number>
+     </property>
+     <widget class="QWidget" name="generalTab">
+      <attribute name="title">
+       <string>General</string>
+      </attribute>
+      <layout class="QVBoxLayout" name="verticalLayout">
+       <item>
+        <layout class="QHBoxLayout" name="horizontalLayout">
+         <item>
+          <layout class="QGridLayout" name="gridLayout">
+           <item row="1" column="0">
+            <widget class="QLabel" name="label_3">
+             <property name="text">
+              <string>Card:</string>
+             </property>
+            </widget>
+           </item>
+           <item row="0" column="0">
+            <widget class="QLabel" name="label">
+             <property name="text">
+              <string>Driver:</string>
+             </property>
+            </widget>
+           </item>
+           <item row="1" column="1">
+            <widget class="QLabel" name="cardLabel">
+             <property name="text">
+              <string/>
+             </property>
+            </widget>
+           </item>
+           <item row="2" column="0">
+            <widget class="QLabel" name="label_6">
+             <property name="text">
+              <string>Bus:</string>
+             </property>
+            </widget>
+           </item>
+           <item row="0" column="1">
+            <widget class="QLabel" name="driverLabel">
+             <property name="text">
+              <string/>
+             </property>
+            </widget>
+           </item>
+           <item row="2" column="1">
+            <widget class="QLabel" name="busLabel">
+             <property name="text">
+              <string/>
+             </property>
+            </widget>
+           </item>
+           <item row="3" column="0">
+            <widget class="QLabel" name="label_2">
+             <property name="text">
+              <string>Device:</string>
+             </property>
+            </widget>
+           </item>
+           <item row="3" column="1">
+            <widget class="QLabel" name="deviceLabel">
+             <property name="text">
+              <string/>
+             </property>
+            </widget>
+           </item>
+          </layout>
+         </item>
+         <item>
+          <spacer name="horizontalSpacer">
+           <property name="orientation">
+            <enum>Qt::Horizontal</enum>
+           </property>
+           <property name="sizeHint" stdset="0">
+            <size>
+             <width>40</width>
+             <height>20</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <spacer name="verticalSpacer">
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>20</width>
+           <height>382</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+      </layout>
+     </widget>
+    </widget>
+   </item>
+   <item>
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>imageSettingsUi</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>322</x>
+     <y>272</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>44</x>
+     <y>230</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>imageSettingsUi</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>405</x>
+     <y>262</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>364</x>
+     <y>227</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/qsstv/videocapt/v4l2control.cpp b/qsstv/videocapt/v4l2control.cpp
new file mode 100644
index 0000000..11945c9
--- /dev/null
+++ b/qsstv/videocapt/v4l2control.cpp
@@ -0,0 +1,298 @@
+/**************************************************************************
+*   Copyright (C) 2000-2012 by Johan Maes                                 *
+*   on4qz at telenet.be                                                      *
+*   http://users.telenet.be/on4qz                                         *
+*                                                                         *
+*   This program is free software; you can redistribute it and/or modify  *
+*   it under the terms of the GNU General Public License as published by  *
+*   the Free Software Foundation; either version 2 of the License, or     *
+*   (at your option) any later version.                                   *
+*                                                                         *
+*   This program is distributed in the hope that it will be useful,       *
+*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+*   GNU General Public License for more details.                          *
+*                                                                         *
+*   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.,                                       *
+*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+*                                                                         *
+*                                                                         *
+*   This software has been partially copied from the program:             *
+*    qv4l2: a control panel controlling v4l2 devices.                     *
+*                                                                         *
+*  Copyright (C) 2006 Hans Verkuil <hverkuil at xs4all.nl>                   *                                                                       *
+***************************************************************************/
+
+
+#include "v4l2control.h"
+
+#include <sys/ioctl.h>
+#include <cerrno>
+#include <cstring>
+//#include <libv4l2.h>
+#include <linux/types.h>          /* for videodev2.h */
+#include <linux/videodev2.h>
+
+#include <QPushButton>
+#include <QLabel>
+#include <QValidator>
+#include <QMessageBox>
+#include <QLineEdit>
+//#include <QDebug>
+
+V4L2Control::V4L2Control(int fd, const struct v4l2_queryctrl &ctrl, QWidget *parent) :
+  QWidget(parent), cid(ctrl.id), default_value(ctrl.default_value)
+{
+  this->fd = fd;
+  strncpy(name, (const char *)ctrl.name, sizeof(name));
+  name[sizeof(name)-1] = '\0';
+  layout.setSpacing(1);
+  layout.setContentsMargins(0,0,0,0);
+  this->setLayout(&layout);
+}
+
+
+
+void V4L2Control::updateHardware()
+{
+  struct v4l2_control c;
+  c.id = cid;
+  c.value = getValue();
+  if(v4l2_ioctl(fd, VIDIOC_S_CTRL, &c) == -1)
+    {
+      QString msg;
+      msg.sprintf("Unable to set %s\n%s", name, strerror(errno));
+      QMessageBox::warning(this, "Unable to set control", msg, "OK");
+    }
+  updateStatus();
+}
+
+void V4L2Control::updateStatus()
+{
+  struct v4l2_control c;
+  c.id = cid;
+  if(v4l2_ioctl(fd, VIDIOC_G_CTRL, &c) == -1)
+    {
+      QString msg;
+      msg.sprintf("Unable to get %s\n%s", name,strerror(errno));
+      QMessageBox::warning(this, "Unable to get control", msg, "OK");
+    }
+  else
+    {
+      if(c.value != getValue())
+        setValue(c.value);
+    }
+  struct v4l2_queryctrl ctrl;
+  ctrl.id = cid;
+  if(v4l2_ioctl(fd, VIDIOC_QUERYCTRL, &ctrl) == -1)
+    {
+      QString msg;
+      msg.sprintf("Unable to get the status of %s\n%s", name,strerror(errno));
+      QMessageBox::warning(this, "Unable to get control status", msg, "OK");
+    }
+  else
+    {
+      setEnabled((ctrl.flags &( V4L2_CTRL_FLAG_DISABLED | V4L2_CTRL_FLAG_GRABBED)) == 0);
+    }
+}
+
+void V4L2Control::resetToDefault()
+{
+  if(isEnabled())
+    {
+      setValue(default_value);
+      updateHardware();
+    }
+}
+
+/*
+ * V4L2IntegerControl
+ */
+V4L2IntegerControl::V4L2IntegerControl
+(int fd, const struct v4l2_queryctrl &ctrl, QWidget *parent) :
+  V4L2Control(fd, ctrl, parent),
+  minimum(ctrl.minimum), maximum(ctrl.maximum), step(ctrl.step)
+{
+  int pageStep = (maximum-minimum)/10;
+  if(step > pageStep)
+    pageStep = step;
+  sl = new QSlider(Qt::Horizontal, this);
+  sl->setMinimum(minimum);
+  sl->setMaximum(maximum);
+  sl->setFocusPolicy(Qt::StrongFocus);
+  sl->setPageStep(pageStep);
+  sl->setValue(default_value);
+  sl->setVisible(true);
+  this->layout.addWidget(sl);
+
+  QString defStr;
+  defStr.setNum(default_value);
+  le = new QLineEdit(this);
+  le->setText(defStr);
+  le->setValidator(new QIntValidator(minimum, maximum, this));
+  this->layout.addWidget(le);
+
+  QObject::connect( sl, SIGNAL(valueChanged(int)),this, SLOT(SetValueFromSlider()) );
+  QObject::connect( sl, SIGNAL(sliderReleased()), this, SLOT(SetValueFromSlider()) );
+  QObject::connect( le, SIGNAL(returnPressed()),  this, SLOT(SetValueFromText()) );
+  updateStatus();
+}
+
+void V4L2IntegerControl::setValue(int val)
+{
+  if(val < minimum) val = minimum;
+  if(val > maximum) val = maximum;
+  if(step > 1)
+    {
+      int mod = (val-minimum)%step;
+      if(mod > step/2)
+        {
+          val += step-mod;
+        }
+      else
+        {
+          val -= mod;
+        }
+    }
+  QString str;
+  str.setNum(val);
+  le->setText(str);
+
+  /* FIXME: find clean solution to prevent infinite loop */
+  sl->blockSignals(true);
+  sl->setValue(val);
+  sl->blockSignals(false);
+}
+
+int V4L2IntegerControl::getValue()
+{
+  return sl->value();
+}
+
+void V4L2IntegerControl::SetValueFromSlider()
+{
+  setValue(sl->value());
+  updateHardware();
+}
+
+void V4L2IntegerControl::SetValueFromText()
+{
+  if(le->hasAcceptableInput())
+    {
+      setValue(le->text().toInt());
+      updateHardware();
+    }
+  else
+    {
+      SetValueFromSlider();
+    }
+}
+
+/*
+ * V4L2BooleanControl
+ */
+V4L2BooleanControl::V4L2BooleanControl
+(int fd, const struct v4l2_queryctrl &ctrl, QWidget *parent) :
+  V4L2Control(fd, ctrl, parent),
+  cb(new QCheckBox(this))
+{
+  this->layout.addWidget(cb);
+  QObject::connect( cb, SIGNAL(clicked()), this, SLOT(updateHardware()) );
+  updateStatus();
+}
+
+void V4L2BooleanControl::setValue(int val)
+{
+  cb->setChecked(val != 0);
+}
+
+int V4L2BooleanControl::getValue()
+{
+  return cb->isChecked();
+}
+
+/*
+ * V4L2MenuControl
+ */
+V4L2MenuControl::V4L2MenuControl(int fd, const struct v4l2_queryctrl &ctrl, QWidget *parent) :  V4L2Control(fd, ctrl, parent)
+{
+  int i,j;
+  int defIdx=0;
+  cb = new QComboBox(this);
+  this->layout.addWidget(cb);
+
+  for(i=ctrl.minimum,j=0; i<=ctrl.maximum; i++,j++)
+    {
+      struct v4l2_querymenu qm;
+      qm.id = ctrl.id;
+      qm.index = i;
+      if(v4l2_ioctl(fd, VIDIOC_QUERYMENU, &qm) == 0)
+        {
+          cb->insertItem(i, (const char *)qm.name);
+          indexValueArray[j]=i;
+          if(i==default_value)
+            {
+              defIdx=j;
+            }
+        }
+      else
+        {
+          cb->insertItem(i,"Unsupported");
+        }
+
+    }
+//  cb->setCurrentIndex(defIdx);
+  setValue(defIdx);
+  QObject::connect( cb, SIGNAL(activated(int)),
+                    this, SLOT(menuActivated(int)) );
+  updateStatus();
+  updateHardware();
+}
+
+void V4L2MenuControl::setValue(int val)
+{
+  cb->setCurrentIndex(val);
+}
+
+int V4L2MenuControl::getValue()
+{
+  return indexValueArray[cb->currentIndex()];
+}
+
+void V4L2MenuControl::menuActivated(int val)
+{
+  setValue(val);
+  updateHardware();
+}
+
+/*
+ * V4L2ButtonControl
+ */
+V4L2ButtonControl::V4L2ButtonControl
+(int fd, const struct v4l2_queryctrl &ctrl, QWidget *parent) :
+  V4L2Control(fd, ctrl, parent)
+{
+  QPushButton *pb = new QPushButton((const char *)ctrl.name, this);
+  this->layout.addWidget(pb);
+  QObject::connect( pb, SIGNAL(clicked()), this, SLOT(updateHardware()) );
+}
+
+void V4L2ButtonControl::updateStatus()
+{
+  struct v4l2_queryctrl ctrl;
+  ctrl.id = cid;
+  if(v4l2_ioctl(fd, VIDIOC_QUERYCTRL, &ctrl) == -1) {
+      QString msg;
+      msg.sprintf("Unable to get the status of %s\n%s", name,
+                  strerror(errno));
+      QMessageBox::warning(this, "Unable to get control status", msg, "OK");
+    } else {
+      setEnabled((ctrl.flags &( V4L2_CTRL_FLAG_DISABLED | V4L2_CTRL_FLAG_GRABBED)) == 0);
+    }
+}
+
+void V4L2ButtonControl::resetToDefault()
+{
+}
diff --git a/qsstv/videocapt/v4l2control.h b/qsstv/videocapt/v4l2control.h
new file mode 100644
index 0000000..0121f7b
--- /dev/null
+++ b/qsstv/videocapt/v4l2control.h
@@ -0,0 +1,108 @@
+#ifndef V4L2CONTROL_H
+#define V4L2CONTROL_H
+
+#include <QObject>
+#include <QCheckBox>
+#include <QPushButton>
+#include <QComboBox>
+#include <QHBoxLayout>
+#include <libv4l2.h>
+#include <QEvent>
+
+class V4L2Control : public QWidget
+{
+    Q_OBJECT
+public slots:
+    void updateHardware();
+    virtual void updateStatus();
+    virtual void resetToDefault();
+    virtual void setValue(int val) = 0;
+
+public:
+    virtual int getValue() = 0;
+
+protected:
+    V4L2Control(int fd, const struct v4l2_queryctrl &ctrl, QWidget *parent);
+    int fd;
+    int cid;
+    int default_value;
+    char name[32];
+    QHBoxLayout layout;
+};
+
+class V4L2IntegerControl : public V4L2Control
+{
+    Q_OBJECT
+public:
+    V4L2IntegerControl(int fd, const struct v4l2_queryctrl &ctrl, QWidget *parent);
+
+public slots:
+    void setValue(int val);
+
+public:
+    int getValue();
+
+private slots:
+    void SetValueFromSlider(void);
+    void SetValueFromText(void);
+
+private:
+    int minimum;
+    int maximum;
+    int step;
+    QSlider *sl;
+    QLineEdit *le;
+};
+
+class V4L2BooleanControl : public V4L2Control
+{
+    Q_OBJECT
+public:
+    V4L2BooleanControl(int fd, const struct v4l2_queryctrl &ctrl, QWidget *parent);
+
+public slots:
+    void setValue(int val);
+
+public:
+    int getValue();
+
+private:
+    QCheckBox *cb;
+};
+
+class V4L2MenuControl : public V4L2Control
+{
+    Q_OBJECT
+public:
+    V4L2MenuControl(int fd, const struct v4l2_queryctrl &ctrl, QWidget *parent);
+
+public slots:
+    void setValue(int val);
+
+public:
+    int getValue();
+
+private:
+    QComboBox *cb;
+    short int indexValueArray[256];
+
+private slots:
+    void menuActivated(int val);
+};
+
+class V4L2ButtonControl : public V4L2Control
+{
+    Q_OBJECT
+public slots:
+    void updateStatus();
+    void resetToDefault();
+
+public:
+    V4L2ButtonControl(int fd, const struct v4l2_queryctrl &ctrl, QWidget *parent);
+
+public slots:
+    void setValue(int) {};
+    int getValue() { return 0; };
+};
+
+#endif // V4L2CONTROL_H
diff --git a/qsstv/videocapt/videocapture.cpp b/qsstv/videocapt/videocapture.cpp
index c15f800..79881dd 100644
--- a/qsstv/videocapt/videocapture.cpp
+++ b/qsstv/videocapt/videocapture.cpp
@@ -1,19 +1,38 @@
-/*
- *      videoCapture.cpp -- Kapture
- *
- *      Copyright (C) 2006-2009
- *          Detlev Casanova (detlev.casanova at gmail.com)
- *
- *      This program is free software; you can redistribute it and/or modify
- *      it under the terms of the GNU General Public License as published by
- *      the Free Software Foundation; either version 2 of the License, or
- *      (at your option) any later version.
- *
- */
-#define DEBUG
+/**************************************************************************
+*   Copyright (C) 2000-2012 by Johan Maes                                 *
+*   on4qz at telenet.be                                                      *
+*   http://users.telenet.be/on4qz                                         *
+*                                                                         *
+*   This program is free software; you can redistribute it and/or modify  *
+*   it under the terms of the GNU General Public License as published by  *
+*   the Free Software Foundation; either version 2 of the License, or     *
+*   (at your option) any later version.                                   *
+*                                                                         *
+*   This program is distributed in the hope that it will be useful,       *
+*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+*   GNU General Public License for more details.                          *
+*                                                                         *
+*   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.,                                       *
+*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+*                                                                         *
+*                                                                         *
+*   This software contains parts of the following softwares               *
+*      videoCapture.cpp -- Kapture                                        *
+*                                                                         *
+*      Copyright (C) 2006-2009                                            *
+*          Detlev Casanova (detlev.casanova at gmail.com)                    *
+*                                                                         *
+*  qv4l2: a control panel controlling v4l2 devices.                       *
+*                                                                         *
+*  Copyright (C) 2006 Hans Verkuil <hverkuil at xs4all.nl>                   *                                                                       *
+***************************************************************************/
+
 #include "videocapture.h"
 #include "configparams.h"
-#include "qsstvglobal.h"
+#include "appglobal.h"
 #include <stdio.h>
 #include <string.h>
 #include <fcntl.h>
@@ -22,6 +41,8 @@
 #include <sys/ioctl.h>
 #include <sys/mman.h>
 #include <sys/select.h>
+#include <libv4l2.h>
+#include <libv4lconvert.h>
 
 #include <QtGui>
 #include <QApplication>
@@ -32,14 +53,12 @@
 #include <QSize>
 
 
-#define CLIP(x) ( (x)>=0xFF ? 0xFF : ( (x) <= 0x00 ? 0x00 : (x) ) )
-
 
 videoCapture::videoCapture()
 {
-	dev = 0;
-	opened = false;
-	allocated = false;
+  dev = 0;
+  opened = false;
+  allocated = false;
   localImage=NULL;
   numBuffers=2;
 
@@ -48,154 +67,138 @@ videoCapture::videoCapture()
 videoCapture::~videoCapture()
 {
   if(localImage!=NULL) delete localImage;
-	close();
+  close();
 }
 
 void videoCapture::close()
 {
   if(!opened) return;
-	::close(dev);
-	opened = false;
-	allocated = false;
+
+  v4l2_close(dev);
+  opened = false;
+  allocated = false;
 }
 
-bool videoCapture::open()
+bool videoCapture::open(QString videoDev)
 {
-	struct v4l2_capability cap;
-	int ret;
-
-
+  videoDevice=videoDev;
   if (opened) return true;
   addToLog("opening Videocapture device",LOGCAM);
 
-  dev = ::open(videoDevice.toLatin1().data(), O_RDWR);
-	if (dev < 0) 
+  dev = v4l2_open(videoDevice.toLatin1().data(), O_RDWR);
+  if (dev < 0)
     {
-     addToLog(QString("Error opening %1, %2").arg(videoDevice).arg(errno),LOGCAM);
+      addToLog(QString("Error opening %1, %2").arg(videoDevice).arg(errno),LOGCAM);
       return false;
     }
+  //  dumpCaps(cap);
+  opened = true;
+  return opened;
+}
 
-  memset(&cap, 0, sizeof cap);
-  ret = ioctl(dev, VIDIOC_QUERYCAP, &cap);
-  if (ret < 0)
+
+bool videoCapture::init(int pixelFormat,int width,int height)
+{
+
+  getFormat(srcFmt);
+  srcFmt.fmt.pix.pixelformat=pixelFormat;
+  srcFmt.fmt.pix.width=width;
+  srcFmt.fmt.pix.height=height;
+  //  srcFmt.fmt.pix.width=320;
+  //  srcFmt.fmt.pix.height=240;
+  setFormat(srcFmt);
+  dstFmt=srcFmt;
+  qFmt=checkConversionNeeded();
+  if(qFmt==QImage::Format_Invalid)
     {
-      addToLog(QString("Error querying capabilities for %1, %2").arg(videoDevice).arg(errno),LOGCAM);
-      return false;
+      needsConversion=true;
+      convertData = v4lconvert_create(dev);
+      dstFmt.fmt.pix.pixelformat=V4L2_PIX_FMT_RGB24;
+      qFmt=QImage::Format_RGB888;
     }
-  dumpCaps(cap);
-
-	if ((cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == 0) 
+  else
     {
-      addToLog(QString("Error checking caps for %1").arg(videoDevice),LOGCAM);
-      return false;
+      needsConversion=false;
     }
 
-  formatList=getFormatList(descripList);
-  getFormat();
-  setFormat(currentWidth(), currentHeight(), currentPixelFormat());
-  sizeList=getSizesList();
+  if(needsConversion)
+    {
+      v4lconvert_try_format(convertData, &dstFmt, &srcFmt);
+      getFormat(srcFmt); //restore srcFmt
+    }
 
-  //Allocate buffers
+  if(localImage) delete localImage;
+  localImage=new QImage( dstFmt.fmt.pix.width,dstFmt.fmt.pix.height,qFmt);
   if (!allocated)
     {
-      memset(&rb, 0, sizeof rb);
-      rb.count = numBuffers;
-      rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-      rb.memory = V4L2_MEMORY_MMAP;
-
-        ret = ioctl(dev, VIDIOC_REQBUFS, &rb);
-        if (ret < 0)
-          {
-            addToLog(QString("Unable to allocate buffersfor %1, %2").arg(videoDevice).arg(errno),LOGCAM);
-            return false;
-          }
-        allocated = true;
-     }
-
-
-
-
-	opened = true;
+      if(allocateBuffers(numBuffers)>=0)
+        {
+          allocated=true;
+        }
+      else
+        {
+          return false;
+        }
+    }
+  else
+    {
+      allocateBuffers(0); // deallocate buffers
+      if(allocateBuffers(numBuffers)>=0)
+        {
+          allocated=true;
+        }
+      else
+        {
+          return false;
+        }
+    }
   return true;
 }
 
-QList<int> videoCapture::getFormatList(QList<QString> &description) const
+int videoCapture::allocateBuffers(int numBufs)
 {
-	QList<int> formatList;
-	int ret;
-	struct v4l2_fmtdesc fmtList;
-  addToLog("getFomatList()",LOGCAM);
-	memset(&fmtList, 0, sizeof fmtList);
-	fmtList.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-	int i = 0;
-
-	do
-	{
-		fmtList.index = i;
-		if ((ret = ioctl(dev, VIDIOC_ENUM_FMT, &fmtList)) < 0)
-			break;
-		else
-		{
-			formatList.append((int)fmtList.pixelformat);
-			description.append((char*)fmtList.description);
-		}
-		i++;
-	}
-	while (ret != EINVAL);
-	return formatList;
-}
+  int ret;
+  memset(&rb, 0, sizeof rb);
+  rb.count = numBufs;
+  rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+  rb.memory = V4L2_MEMORY_MMAP;
 
-QList<QSize> videoCapture::getSizesList() const
-{
-	int i = 0;
-	QList<QSize> rSizes;
-	QSize tmp;
-#ifdef V4L2_CAP_VIDEO_OUTPUT_OVERLAY // sort of test for v4l2 if this one does not exist, v4l2_frmsizeenum will not exist
-	struct v4l2_frmsizeenum sizes;
-  addToLog("getSizesList()",LOGCAM);
-	memset(&sizes, 0, sizeof sizes);
-	sizes.pixel_format = currentPixelFormat();
-	sizes.index = i;
-	while(ioctl(dev, VIDIOC_ENUM_FRAMESIZES, &sizes) != -1)
-	{
-		tmp.setWidth((int)sizes.discrete.width);
-		tmp.setHeight((int)sizes.discrete.height);
-		rSizes.append(tmp);
-		i++;
-		sizes.index = i;
-	}
-#else
-	tmp.setWidth(320);
-	tmp.setHeight(240);
-	rSizes.append(tmp);
-#endif
-	return rSizes;
+  ret = v4l2_ioctl(dev, VIDIOC_REQBUFS, &rb);
+  if (ret < 0)
+    {
+      addToLog(QString("Unable to allocate buffers for %1, %2").arg(videoDevice).arg(errno),LOGCAM);
+    }
+  return ret;
 }
 
 
-bool videoCapture::setFormat(unsigned int width, unsigned int height, int pixelformat)
+bool videoCapture::setFormat(v4l2_format &fmt)
 {
   addToLog("setFormat",LOGCAM);
-  memset(&fmt, 0, sizeof fmt);
+  //  memset(&fmt, 0, sizeof fmt);
   fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-  fmt.fmt.pix.width = width;
-  fmt.fmt.pix.height = height;
+  //  fmt.fmt.pix.width = width;
+  //  fmt.fmt.pix.height = height;
   fmt.fmt.pix.field = V4L2_FIELD_ANY;
-  fmt.fmt.pix.pixelformat = pixelformat;
-	if (ioctl(dev, VIDIOC_S_FMT, &fmt) < 0)
+  //  fmt.fmt.pix.pixelformat = pixelformat;
+  //  fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
+  //  fmt.fmt.pix.pixelformat =V4L2_PIX_FMT_RGB24;
+  fmt.fmt.pix.bytesperline=0;
+  if (v4l2_ioctl(dev, VIDIOC_S_FMT, &fmt) < 0)
     {
       addToLog(QString("Error while setting format , %1").arg(strerror(errno)),LOGCAM);
       return false;
     }
+  getFormat(fmt);
   return true;
 }
 
-bool videoCapture::getFormat()
+bool videoCapture::getFormat(v4l2_format &fmt)
 {
   addToLog("getFormat",LOGCAM);
   memset(&fmt, 0, sizeof fmt);
   fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-  if (ioctl(dev, VIDIOC_G_FMT, &fmt) < 0)
+  if (v4l2_ioctl(dev, VIDIOC_G_FMT, &fmt) < 0)
     {
       addToLog(QString("Error while getting format , %1").arg(errno),LOGCAM);
       return false;
@@ -207,450 +210,74 @@ bool videoCapture::getFormat()
 
 bool videoCapture::getFrame()
 {
-	int ret = 0;
- // addToLog("getFrame",LOGCAM);
+  int ret = 0;
 
-	// Dequeue a buffer.
-  ret = ioctl(dev, VIDIOC_DQBUF, &buf);
+  // Dequeue a buffer.
+  ret = v4l2_ioctl(dev, VIDIOC_DQBUF, &buf);
   //addToLog(QString("Dequeue buffer %1").arg(buf.index),LOGCAM);
   if (ret < 0)
     {
       addToLog(QString("Unable to dequeue buffer , %1").arg(strerror(errno)),LOGCAM);
       return false;
-  }
-//  while(ioctl(dev, VIDIOC_DQBUF, &buf)<0)
-//  {
-//    qApp->processEvents();
-//  }
-
-	// Save the image.
-	if (fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG)
-	{
-    addToLog(QString("Unsupported MJPEG Format"),LOGCAM);
-    return false;
-	}
-
-	if (fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
-	{
-    YUV422toRGB888_ITU_R(mem[buf.index],currentWidth(), currentHeight());
-
-	}
-	
-	// Requeue the buffer.
-	ret = ioctl(dev, VIDIOC_QBUF, &buf);
-  //addToLog(QString("Requeue buffer %1").arg(buf.index),LOGCAM);
-	if (ret < 0) 
-	{
-    addToLog(QString("Unable to requeue buffer %1").arg(errno),LOGCAM);
-    return false;
-	}
-
-  return true;
-}
+    }
 
-/**
-  Convert from YUV422 format to RGB888 using ITU_R_FLOAT. Formulae are described on http://en.wikipedia.org/wiki/YUV
+  convert(mem[buf.index]);
 
-  \param width width of image
-  \param height height of image
-  \param src source
-  \param dst destination
-*/
-void videoCapture::YUV422toRGB888_ITU_R( unsigned char *src,int width, int height)
-{
-  int line, column;
-  unsigned char *py, *pu, *pv;
-  unsigned char r,g,b;
-  QRgb *dst;
-
-  if (localImage!=NULL) delete localImage;
-  localImage=new QImage( width,height,QImage::Format_RGB32);
-
-  /* In this format each four bytes is two pixels. Each four bytes is two Y's, a Cb and a Cr.
-     Each Y goes to one of the pixels, and the Cb and Cr belong to both pixels. */
-  py = src;
-  pu = src + 1;
-  pv = src + 3;
-  for (line = 0; line < height; ++line)
+  // Requeue the buffer.
+  ret = v4l2_ioctl(dev, VIDIOC_QBUF, &buf);
+  //addToLog(QString("Requeue buffer %1").arg(buf.index),LOGCAM);
+  if (ret < 0)
     {
-      dst=(QRgb *)localImage->scanLine(line);
-      for (column = 0; column < width; ++column) // ITU-R float
-        {
-          r = CLIP((double)*py + 1.402*((double)*pv-128.0));
-          g = CLIP((double)*py - 0.344*((double)*pu-128.0) - 0.714*((double)*pv-128.0));
-          b = CLIP((double)*py + 1.772*((double)*pu-128.0));
-          dst[column]=qRgb(r,g,b);
-          // increase py every time
-          py += 2;
-          // increase pu,pv every second time
-          if ((column & 1)==1)
-            {
-              pu += 4;
-              pv += 4;
-            }
-        }
+      addToLog(QString("Unable to requeue buffer %1").arg(errno),LOGCAM);
+      return false;
     }
-}
 
+  return true;
+}
 
-/**
-  Convert from YUV422 format to RGB888 using NTSC. Formulae are described on http://en.wikipedia.org/wiki/YUV
 
-  \param width width of image
-  \param height height of image
-  \param src source
-  \param dst destination
-*/
 
-void videoCapture::YUV422toRGB888_NTSC(unsigned char *src,int width, int height)
+bool videoCapture::convert(unsigned char *src)
 {
-  int line, column;
-  unsigned char *py, *pu, *pv;
-  unsigned char r,g,b;
-  QRgb *dst;
-
-  if (localImage!=NULL) delete localImage;
-  localImage=new QImage( width,height,QImage::Format_RGB32);
-
-  /* In this format each four bytes is two pixels. Each four bytes is two Y's, a Cb and a Cr.
-     Each Y goes to one of the pixels, and the Cb and Cr belong to both pixels. */
-  py = src;
-  pu = src + 1;
-  pv = src + 3;
-  for (line = 0; line < height; ++line)
+  int result=0;
+  //  if (localImage!=NULL) delete localImage;
+  //  localImage=new QImage( dstFmt.fmt.pix.width,dstFmt.fmt.pix.height,qFmt);
+  if(needsConversion)
     {
-      dst=(QRgb *)localImage->scanLine(line);
-      for (column = 0; column < width; ++column)
-        {
-          // NTSC integer
-          r = CLIP( (298*(*py-16) + 409*(*pv-128) + 128) >> 8 );
-          g = CLIP( (298*(*py-16) - 100*(*pu-128) - 208*(*pv-128) + 128) >> 8 );
-          b = CLIP( (298*(*py-16) + 516*(*pu-128) + 128) >> 8 );
-          dst[column]=qRgb(r,g,b);
-          // increase py every time
-          py += 2;
-          // increase pu,pv every second time
-          if ((column & 1)==1)
-            {
-              pu += 4;
-              pv += 4;
-            }
-        }
+      result=v4lconvert_convert(convertData,&srcFmt,&dstFmt,
+                                src,srcFmt.fmt.pix.sizeimage,
+                                localImage->bits(),dstFmt.fmt.pix.sizeimage);
+    }
+  else
+    {
+      memcpy(localImage->bits(),src,localImage->byteCount());
     }
+  if (result<0) return false;
+  return true;
 }
 
 
-int videoCapture::changeCtrl(int ctrl, int value) // an enum for formats and reorganisation would be great...
-{
-	struct v4l2_queryctrl queryctrl;
-	struct v4l2_control control;
-	
-	if(!opened) // At the begining of the function.
-	{
-		return -1;
-	}
-/*
- * ctrl values :
- * 	0 : Saturation
- * 	1 : Power line Frequency (néons)
- * 	2 : Brightness
- * 	3 : Contrast
- * 	4 : Sharpness
- * 	5 : Reset Pan/Tilt
- */
-	__u32 CTRL;
-	switch(ctrl)
-	{
-		case Saturation: 
-		{
-			CTRL = V4L2_CID_SATURATION;
-			break;
-		}
-		case Brightness: 
-		{
-			CTRL = V4L2_CID_BRIGHTNESS;
-			break;
-		}
-  case Hue:
-  {
-    CTRL = V4L2_CID_HUE;
-    break;
-  }
-		case Contrast: 
-		{
-			CTRL = V4L2_CID_CONTRAST;
-			break;
-		}
-//#ifdef V4L2_CID_POWER_LINE_FREQUENCY
-//		case PowerLineFreq:
-//		{
-//			CTRL = V4L2_CID_POWER_LINE_FREQUENCY;
-//			break;
-//		}
-//#endif
-		case Sharpness:
-		{
-#ifdef 	V4L2_CID_SHARPNESS
-		CTRL = V4L2_CID_SHARPNESS;
-#else
-	        CTRL=0;
-#endif
 
-		break;
-		}
-
-		default:
-			CTRL = 0;
-	}
-
-	memset (&queryctrl, 0, sizeof queryctrl);
-	memset (&control, 0, sizeof control);
-	queryctrl.id = CTRL;
-	if (-1 == ioctl (dev, VIDIOC_QUERYCTRL, &queryctrl)) 
-	{
-	        if (errno != EINVAL) 
-		{
-#ifdef DEBUG
-			perror ("VIDIOC_QUERYCTRL");
-#endif
-			return EXIT_FAILURE;
-		} 
-	} else 
-	{
-		control.id = CTRL;
-		control.value = value;
-		if (-1 == ioctl (dev, VIDIOC_S_CTRL, &control)) {
-#ifdef DEBUG
-			perror("VIDIOC_S_CTRL");
-			printf(" * Error while setting control\n");
-#endif
-			return EXIT_FAILURE;
-        	}
-	}
-	return EXIT_SUCCESS;
-}
 
-int videoCapture::currentWidth() const
-{
-	return (int) fmt.fmt.pix.width;
-}
 
-int videoCapture::currentHeight() const
+int videoCapture::currentWidth(v4l2_format fmt) const
 {
-	return (int) fmt.fmt.pix.height;
+  return (int) fmt.fmt.pix.width;
 }
 
-int videoCapture::currentPixelFormat() const
+int videoCapture::currentHeight(v4l2_format fmt) const
 {
-	return (int) fmt.fmt.pix.pixelformat;
+  return (int) fmt.fmt.pix.height;
 }
 
-
-int videoCapture::defaultCtrlVal(unsigned int control, int &defaultValue)
+int videoCapture::currentPixelFormat(v4l2_format fmt) const
 {
-	struct v4l2_queryctrl queryctrl;
-	QString ctrl;
-	
-	if(!opened)
-	{
-		return false;
-	}
-	
-	memset(&queryctrl, 0, sizeof queryctrl);
-	switch(control)
-	{
-		case Saturation : 
-		{
-			ctrl = "Saturation";
-			queryctrl.id = V4L2_CID_SATURATION;
-			break;
-		}
-		case Brightness : 
-		{
-			ctrl = "Brightness";
-			queryctrl.id = V4L2_CID_BRIGHTNESS;
-			break;
-		}
-  case Hue :
-  {
-    ctrl = "Hue";
-    queryctrl.id = V4L2_CID_HUE;
-    break;
-  }
-		case Contrast : 
-		{
-			ctrl = "Contrast";
-			queryctrl.id = V4L2_CID_CONTRAST;
-			break;
-		}
-
-//		case PowerLineFreq :
-//		{
-//			ctrl = "Powerline Frequecy";
-//			queryctrl.id = V4L2_CID_POWER_LINE_FREQUENCY;
-//			break;
-//		}
-
-		case Sharpness : 
-		{
-			ctrl = "Sharpness";
-#ifdef V4L2_CID_SHARPNESS
-			queryctrl.id = V4L2_CID_SHARPNESS;
-#endif
-			break;
-		}
-
-		default :
-			ctrl = "ERROR";
-	}
+  return (int) fmt.fmt.pix.pixelformat;
+}
 
-	QString str;
-	if (-1 == ioctl(dev, VIDIOC_QUERYCTRL, &queryctrl))
-	{
-    addToLog(QString("Unable to set control %1, %2").arg(ctrl).arg(errno),LOGCAM);
-    return false;
-	}
 
-	defaultValue = (int)queryctrl.default_value;
 
-	return true;
-}
 
-//bool videoCapture::panTiltSupported()
-//{
-//	struct v4l2_queryctrl queryctrl;
-
-//  if(!opened)	return false;
-
-//	memset(&queryctrl, 0, sizeof queryctrl);
-//	queryctrl.id = V4L2_CID_TILT_RELATIVE; // Could be V4L2_CID_PAN_RELATIVE.
-
-//  if (ioctl(dev, VIDIOC_QUERYCTRL, &queryctrl)<0)
-//	{
-//     addToLog(QString("Unable to check wether Pan Tilt is supported, %1").arg(errno),LOGCAM);
-//      return false;
-//	}
-
-//	if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED)
-//	{
-//     addToLog("Pan & Tilt not supported."),LOGCAM);
-//     return false; //FLAG_NOT_SUPPORTED;
-//	}
-
-//	return true;
-//}
-
-//void videoCapture::turnRight()
-//{
-//#ifdef V4L2_CID_PAN_RELATIVE
-//	struct v4l2_queryctrl queryctrl;
-//	struct v4l2_control control;
-
-//	memset (&queryctrl, 0, sizeof queryctrl);
-//	memset (&control, 0, sizeof control);
-//	queryctrl.id = V4L2_CID_PAN_RELATIVE;
-//	if (-1 == ioctl (dev, VIDIOC_QUERYCTRL, &queryctrl))
-//	{
-//	        if (errno != EINVAL)
-//		{
-//			perror ("VIDIOC_QUERYCTRL");
-//			return;
-//		}
-//	} else
-//	{
-//		control.id = V4L2_CID_PAN_RELATIVE;
-//		control.value = -320;
-//		if (-1 == ioctl (dev, VIDIOC_S_CTRL, &control)) {
-//			perror("VIDIOC_S_CTRL");
-//			return;
-//        	}
-//	}
-//#endif
-//}
-
-//void videoCapture::turnLeft()
-//{
-//#ifdef V4L2_CID_PAN_RELATIVE
-//	struct v4l2_queryctrl queryctrl;
-//	struct v4l2_control control;
-
-//	memset (&queryctrl, 0, sizeof queryctrl);
-//	memset (&control, 0, sizeof control);
-//	queryctrl.id = V4L2_CID_PAN_RELATIVE;
-//	if (-1 == ioctl (dev, VIDIOC_QUERYCTRL, &queryctrl))
-//	{
-//	        if (errno != EINVAL)
-//		{
-//			perror ("VIDIOC_QUERYCTRL");
-//			return;
-//		}
-//	} else
-//	{
-//		control.id = V4L2_CID_PAN_RELATIVE;
-//		control.value = 320;
-//		if (-1 == ioctl (dev, VIDIOC_S_CTRL, &control)) {
-//			perror("VIDIOC_S_CTRL");
-//			return;
-//        	}
-//	}
-//#endif
-//}
-
-//void videoCapture::turnUp()
-//{
-//#ifdef V4L2_CID_TILT_RELATIVE
-//	struct v4l2_queryctrl queryctrl;
-//	struct v4l2_control control;
-	
-//	memset (&queryctrl, 0, sizeof queryctrl);
-//	memset (&control, 0, sizeof control);
-//	queryctrl.id = V4L2_CID_TILT_RELATIVE;
-//	if (-1 == ioctl (dev, VIDIOC_QUERYCTRL, &queryctrl))
-//	{
-//	        if (errno != EINVAL)
-//		{
-//			perror ("VIDIOC_QUERYCTRL");
-//			return;
-//		}
-//	} else
-//	{
-//		control.id = V4L2_CID_TILT_RELATIVE;
-//		control.value = -320;
-//		if (-1 == ioctl (dev, VIDIOC_S_CTRL, &control)) {
-//			perror("VIDIOC_S_CTRL");
-//			return;
-//        	}
-//	}
-//#endif
-//}
-
-//void videoCapture::turnDown()
-//{
-//#ifdef V4L2_CID_TILT_RELATIVE
-//	struct v4l2_queryctrl queryctrl;
-//	struct v4l2_control control;
-
-//	memset (&queryctrl, 0, sizeof queryctrl);
-//	memset (&control, 0, sizeof control);
-//	queryctrl.id = V4L2_CID_TILT_RELATIVE;
-//	if (-1 == ioctl (dev, VIDIOC_QUERYCTRL, &queryctrl))
-//	{
-//	        if (errno != EINVAL)
-//		{
-//			perror ("VIDIOC_QUERYCTRL");
-//			return;
-//		}
-//	} else
-//	{
-//		control.id = V4L2_CID_TILT_RELATIVE;
-//		control.value = 320;
-//		if (-1 == ioctl (dev, VIDIOC_S_CTRL, &control)) {
-//			perror("VIDIOC_S_CTRL");
-//			return;
-//        	}
-//	}
-//#endif
-//}
 
 
 bool videoCapture::captureStop()
@@ -659,11 +286,11 @@ bool videoCapture::captureStop()
   int ret;
 
   if(!streaming) return false;
-  ret = ioctl(dev, VIDIOC_STREAMOFF, &type);
+  ret = v4l2_ioctl(dev, VIDIOC_STREAMOFF, &type);
   if (ret < 0)
     {
-     addToLog(QString("Unable  to stop capture, %1").arg(errno),LOGCAM);
-     return false;
+      addToLog(QString("Unable  to stop capture, %1").arg(errno),LOGCAM);
+      return false;
     }
 
   streaming = false;
@@ -674,132 +301,109 @@ bool videoCapture::captureStart()
 {
   int i, ret;
   if (!opened) return false;
-  abortCap=false;
   addToLog("captureStart",LOGCAM);
 
-//  if ((ret = setFormat(currentWidth(), currentHeight(), currentPixelFormat())) != 0)
-//    {
-//      addToLog(QString("Set format error :  %1").arg(ret),LOGCAM);
-//      return false;
-//    }
-
-////Allocate buffers
-//  if (!allocated)
-//    {
-//      memset(&rb, 0, sizeof rb);
-//      rb.count = 2;
-//      rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-//      rb.memory = V4L2_MEMORY_MMAP;
-
-//      ret = ioctl(dev, VIDIOC_REQBUFS, &rb);
-//      if (ret < 0)
-//        {
-//         addToLog(QString("Unable to allocate buffers %1").arg(ret),LOGCAM);
-//         return false;
-//      }
-//      allocated = true;
-//    }
-
-  // Map the buffers.
-  memset(&buf, 0, sizeof buf);
-  buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-  buf.memory = V4L2_MEMORY_MMAP;
-  for (i = 0; i < numBuffers; i++)
+  //Allocate buffers
+
+  if(!mmapped)
     {
-      buf.index = i;
-      ret = ioctl(dev, VIDIOC_QUERYBUF, &buf);
-      if (ret < 0)
+
+      // Map the buffers.
+      memset(&buf, 0, sizeof buf);
+      buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+      buf.memory = V4L2_MEMORY_MMAP;
+      for (i = 0; i < numBuffers; i++)
         {
-          addToLog(QString("Unable to query buffer %1").arg(ret),LOGCAM);
-          return false;
+          buf.index = i;
+          ret = v4l2_ioctl(dev, VIDIOC_QUERYBUF, &buf);
+          if (ret < 0)
+            {
+              addToLog(QString("Unable to query buffer %1").arg(ret),LOGCAM);
+              return false;
+            }
+          mem[i] = (uchar *) v4l2_mmap(0, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, dev, buf.m.offset);
+          if (mem[i] == MAP_FAILED)
+            {
+              addToLog(QString("Unable to map buffers %1").arg(ret),LOGCAM);
+              return false;
+            }
+          bufLength = buf.length;
+          mmapped = true;
+        }
+
+      // Queue the buffers
+
+      for (i = 0; i < numBuffers; i++)
+        {
+          buf.index = i;
+          ret = v4l2_ioctl(dev, VIDIOC_QBUF, &buf);
+          if (ret < 0)
+            {
+              addToLog(QString("Unable to queue buffer %1").arg(errno),LOGCAM);
+              return false;
+            }
         }
-      mem[i] = (uchar *) mmap(0, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, dev, buf.m.offset);
-      if (mem[i] == MAP_FAILED)
-         {
-           addToLog(QString("Unable to map buffers %1").arg(ret),LOGCAM);
-           return false;
-         }
-       bufLength = buf.length;
-       mmaped = true;
-     }
-
- // Queue the buffers
-
-  for (i = 0; i < numBuffers; i++)
-  {
-    buf.index = i;
-    ret = ioctl(dev, VIDIOC_QBUF, &buf);
-    if (ret < 0)
-    {
-      addToLog(QString("Unable to queue buffer %1").arg(errno),LOGCAM);
-      return false;
     }
-  }
 
   // Start streaming.
-  ret = ioctl(dev, VIDIOC_STREAMON, &buf.type);
+  ret = v4l2_ioctl(dev, VIDIOC_STREAMON, &buf.type);
   if (ret < 0)
-  {
-    addToLog(QString("Unable to start capture %1").arg(errno),LOGCAM);
-    return false;
-  }
+    {
+      addToLog(QString("Unable to start capture %1").arg(errno),LOGCAM);
+      return false;
+    }
   streaming = true;
   return true;
 }
 
 bool videoCapture::stopStreaming()
 {
+  int i;
+  bool ok=true;
   if(!streaming) return false;
-  if (munmap(mem[0], bufLength) == -1)
-  {
-    addToLog(QString("videoCapture::stopStreaming : munmap 0 failed. errno = %1").arg(errno),LOGCAM);
-  }
-
-  if (munmap(mem[1], bufLength) == -1)
-  {
-    addToLog(QString("videoCapture::stopStreaming : munmap 1 failed. errno = %1").arg(errno),LOGCAM);
-  }
-
-  if (munmap(mem[2], bufLength) == -1)
-  {
-    addToLog(QString("videoCapture::stopStreaming : munmap 2 failed. errno = %1").arg(errno),LOGCAM);
-  }
-
-  if (munmap(mem[3], bufLength) == -1)
-  {
-    addToLog(QString("videoCapture::stopStreaming : munmap 3 failed. errno = %1").arg(errno),LOGCAM);
-  }
-
-
-
+  for(i=0;i<numBuffers;i++)
+    {
+      if (v4l2_munmap(mem[i], bufLength) == -1)
+        {
+          addToLog(QString("videoCapture::stopStreaming : munmap %1 failed. errno = %2").arg(i).arg(errno),LOGCAM);
+          ok=false;
+        }
 
-  else
-    mmaped = false;
+    }
+  if(ok) mmapped = false;
 
-  if(captureStop() == 0)
-  {
-    streaming = false;
-    addToLog(" * Succesful Stopped",LOGCAM);
-  }
+  if(captureStop())
+    {
+      streaming = false;
+      addToLog(" * Succesful Stopped",LOGCAM);
+    }
   return true;
 }
 
-bool videoCapture::takeSnapshot()
-{
-  if(!open()) return false;
-  if(!captureStart()) return false;
-  if(!getFrame()) return false; // first frame always corrupted
-  if(!getFrame()) return false;
-  return stopStreaming();
-}
+
 
 bool videoCapture::startSnapshots()
 {
-  if(!open()) return false;
+  if(!opened) return false;
   if(!captureStart()) return false;
   return true;
 }
 
+enum QImage::Format videoCapture::checkConversionNeeded ()
+{
+  QImage::Format qfmt;
+  switch(srcFmt.fmt.pix.pixelformat)
+    {
+    case V4L2_PIX_FMT_BGR32:   qfmt=QImage::Format_RGB32; break;
+    case V4L2_PIX_FMT_RGB24:   qfmt=QImage::Format_RGB888 ; break;
+    case V4L2_PIX_FMT_RGB565:  qfmt=QImage::Format_RGB16 ; break;
+    case V4L2_PIX_FMT_RGB555:  qfmt=QImage::Format_RGB555 ; break;
+    case V4L2_PIX_FMT_RGB444:  qfmt=QImage::Format_RGB444 ; break;
+    default: qfmt=QImage::Format_Invalid;
+    }
+  return qfmt;
+}
+
 
 void videoCapture::dumpCaps(v4l2_capability &cap)
 {
@@ -821,3 +425,5 @@ void videoCapture::dumpCaps(v4l2_capability &cap)
   if (cap.capabilities & V4L2_CAP_STREAMING) addToLog("The device supports the streaming I/O method.",LOGCAM);
 }
 
+
+
diff --git a/qsstv/videocapt/videocapture.h b/qsstv/videocapt/videocapture.h
index a46b9d4..6b18b66 100644
--- a/qsstv/videocapt/videocapture.h
+++ b/qsstv/videocapt/videocapture.h
@@ -17,7 +17,8 @@
 #include <QObject>
 #include <QImage>
 #include <linux/videodev2.h>
-#include "qsstvdefs.h"
+#include "appdefs.h"
+#include <libv4lconvert.h>
 
 struct tableFormat
 {
@@ -28,7 +29,6 @@ struct tableFormat
 extern tableFormat sizeList[];
 extern tableFormat fpsList[];
 
-enum ecamSize{PICMAX,PICMIN,PICHALF};
 
 class videoCapture : public QObject
 {
@@ -39,39 +39,33 @@ public:
   ~videoCapture();
 	
 	void close();
-  bool  open();
-	QList<int>   getFormatList(QList<QString> &description) const;
-	QList<QSize> getSizesList() const;
-  QList<int> formatList;
-  QList<QSize> sizeList;
+  bool  open(QString videoDev);
+//  QList<int>   getFormatList(QList<QString> &description);
+//	QList<QSize> getSizesList() const;
+//  QList<int> formatList;
+//  QList<QSize> sizeList;
   QList<QString> descripList;
 
-  bool setFormat(unsigned int width, unsigned int height, int pixelformat=V4L2_PIX_FMT_MJPEG);
-  bool getFormat();
+  bool setFormat(v4l2_format &fmt);
+  bool getFormat(v4l2_format &fmt);
   bool getFrame();
-	int currentWidth() const;
-	int currentHeight() const;
-	int currentPixelFormat() const;
-	int changeCtrl(int ctrl, int value = 0);
-	int defaultCtrlVal(unsigned int control, int &defaultValue);
-  bool isOpened() const {return opened;};
-  bool takeSnapshot();
+  int currentWidth(v4l2_format fmt) const;
+  int currentHeight(v4l2_format fmt) const;
+  int currentPixelFormat(v4l2_format fmt) const;
+//	int changeCtrl(int ctrl, int value = 0);
+//	int defaultCtrlVal(unsigned int control, int &defaultValue);
+//  bool isOpened() const {return opened;};
   QImage *getImage() {return localImage;}
   bool captureStart();
   bool captureStop();
   bool stopStreaming();
   bool startSnapshots();
-  void abortCapture() { abortCap=true;}
-
-
-  enum econtrol {Saturation = 0,Hue,Brightness,Contrast,Sharpness};
-signals:
-  void imageReady();
-	
+  bool init(int pixelFormat, int width, int height);
 
 private:
 	int dev;
-	v4l2_format fmt;
+  v4l2_format srcFmt;
+  v4l2_format dstFmt;
 	v4l2_buffer buf;
 	v4l2_requestbuffers rb;
 	bool allocated;
@@ -79,14 +73,20 @@ private:
   uchar *mem[4];
 	size_t bufLength;
   QImage *localImage;
-	bool opened;
-	bool mmaped;
-  void YUV422toRGB888_ITU_R( unsigned char *src,int width, int height);
-  void YUV422toRGB888_NTSC( unsigned char *src,int width, int height);
+  bool opened;
+  bool mmapped;
   bool streaming;
   void dumpCaps(v4l2_capability &cap);
   int numBuffers;
-  bool abortCap;
+  QString pixelFormatStr(int pixelFormat);
+  struct v4lconvert_data *convertData;
+  bool convert(unsigned char *src);
+  enum QImage::Format checkConversionNeeded ();
+  enum QImage::Format qFmt;
+  bool needsConversion;
+  QString videoDevice;
+  int allocateBuffers(int numBufs);
+
 };
 #endif
 
diff --git a/qsstv/widgets/blockview.cpp b/qsstv/widgets/blockview.cpp
deleted file mode 100644
index 521ead0..0000000
--- a/qsstv/widgets/blockview.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-#include "blockview.h"
-#include "ui_blockview.h"
-#include <QPainter>
-
-blockView::blockView(QWidget *parent) :
-  QFrame(parent),
-  ui(new Ui::blockView)
-{
-  maxBlocks=40;
-  colFail=QColor(Qt::red);
-  colOK=QColor(Qt::green);
-  ui->setupUi(this);
-}
-
-blockView::~blockView()
-{
-  delete ui;
-}
-
-
-void blockView::paintEvent(QPaintEvent *)
-{
-  int i;
-  QRectF rct;
-  QPainter painter(this);
-  painter.setPen(QPen(colFail, 1, Qt::SolidLine));
-  painter.setBrush(QBrush(colFail));
-  painter.setRenderHint(QPainter::Antialiasing);
-  rct=QRectF(0,0,maxBlocks-1,30);
-  painter.setWindow(0, 0, maxBlocks-1,30);
-  painter.drawRect(rct);
-  painter.setPen(QPen(colOK, 1, Qt::SolidLine));
-  for(i=0;i<blockList.count();i++)
-    {
-      painter.drawLine(blockList.at(i),0,blockList.at(i),29);
-    }
-}
-
-void blockView::setColorFail(QColor color)
-{
-  colFail = color;
-//  update();
-}
-
-void blockView::setColorOK(QColor color)
-{
-  colOK = color;
-//  update();
-}
-
- void blockView::setBlocks(QList<unsigned short> blkList)
- {
-   blockList=blkList;
-//   update();
- }
diff --git a/qsstv/widgets/blockview.h b/qsstv/widgets/blockview.h
deleted file mode 100644
index 41f8b5f..0000000
--- a/qsstv/widgets/blockview.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef BLOCKVIEW_H
-#define BLOCKVIEW_H
-
-#include <QFrame>
-
-namespace Ui {
-  class blockView;
-  }
-
-class blockView : public QFrame
-{
-  Q_OBJECT
-  
-public:
-  explicit blockView(QWidget *parent = 0);
-  ~blockView();
-  void setColorFail(QColor color);
-  void setColorOK(QColor color);
-  void setMaxBlocks(int mb) {maxBlocks=mb;}
-  void setBlocks(QList<short unsigned int> blkList);
-
-protected:
-
-    void paintEvent(QPaintEvent *);
-  
-private:
-  Ui::blockView *ui;
-  QColor colFail;
-  QColor colOK;
-  QList<short unsigned int> blockList;
-  short int maxBlocks;
-};
-
-#endif // BLOCKVIEW_H
diff --git a/qsstv/widgets/blockview.ui b/qsstv/widgets/blockview.ui
deleted file mode 100644
index 4151c92..0000000
--- a/qsstv/widgets/blockview.ui
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>blockView</class>
- <widget class="QFrame" name="blockView">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>414</width>
-    <height>192</height>
-   </rect>
-  </property>
-  <property name="windowTitle">
-   <string>Frame</string>
-  </property>
-  <property name="frameShape">
-   <enum>QFrame::StyledPanel</enum>
-  </property>
-  <property name="frameShadow">
-   <enum>QFrame::Sunken</enum>
-  </property>
-  <property name="lineWidth">
-   <number>3</number>
-  </property>
- </widget>
- <resources/>
- <connections/>
-</ui>
diff --git a/qsstv/widgets/cameracontrol.cpp b/qsstv/widgets/cameracontrol.cpp
deleted file mode 100644
index 82a8330..0000000
--- a/qsstv/widgets/cameracontrol.cpp
+++ /dev/null
@@ -1,144 +0,0 @@
-#include "cameracontrol.h"
-#include "qsstvglobal.h"
-#include "videocapt/videocapture.h"
-#include "ui_cameracontrol.h"
-#include "utils/supportfunctions.h"
-#include <QSettings>
-#include <QPainter>
-
-cameraControl::cameraControl(QWidget *parent) :
-    QDialog(parent),
-    ui(new Ui::cameraControl)
-{
-    ui->setupUi(this);
-    camera=new videoCapture;
-    readSettings();
-
- }
-
-cameraControl::~cameraControl()
-{
-    camera->close();
-    delete camera;
-    writeSettings();
-    delete ui;
-}
-
-void cameraControl::readSettings()
-{
-  QSettings qSettings;
-  qSettings.beginGroup("Capture");
-  brightness=qSettings.value("brightness",128).toInt();
-  hue=qSettings.value("hue",0).toInt();
-  saturation=qSettings.value("saturation",128).toInt();
-  contrast=qSettings.value("contrast",128).toInt();
-  sharpness=qSettings.value("sharpness",128).toInt();
-  qSettings.endGroup();
-  setParams();
-  cameraActive=camera->open();
-  slotBrightnessSliderChanged();
-  slotHueSliderChanged();
-  slotSaturationSliderChanged();
-  slotContrastSliderChanged();
-  slotSharpnessSliderChanged();
-  connect(ui->brightnessSlider,SIGNAL(valueChanged(int)),SLOT(slotBrightnessSliderChanged()));
-  connect(ui->hueSlider,SIGNAL(valueChanged(int)),SLOT(slotHueSliderChanged()));
-  connect(ui->saturationSlider,SIGNAL(valueChanged(int)),SLOT(slotSaturationSliderChanged()));
-  connect(ui->contrastSlider,SIGNAL(valueChanged(int)),SLOT(slotContrastSliderChanged()));
-  connect(ui->sharpnessSlider,SIGNAL(valueChanged(int)),SLOT(slotSharpnessSliderChanged()));
-}
-
-void cameraControl::writeSettings()
-{
-  getParams();
-  QSettings qSettings;
-  qSettings.beginGroup("Capture");
-  qSettings.setValue( "brightness",brightness);
-  qSettings.setValue( "hue",hue);
-  qSettings.setValue( "saturation",saturation);
-  qSettings.setValue( "contrast",contrast);
-  qSettings.setValue( "sharpness",sharpness);
-  qSettings.endGroup();
-}
-
-
-void cameraControl::getParams()
-{
-  getValue(brightness,ui->brightnessSlider);
-  getValue(hue,ui->hueSlider);
-  getValue(saturation,ui->saturationSlider);
-  getValue(contrast,ui->contrastSlider);
-  getValue(sharpness,ui->sharpnessSlider);
-}
-
-void cameraControl::setParams()
-{
-  setValue(brightness,ui->brightnessSlider);
-  setValue(hue,ui->hueSlider);
-  setValue(saturation,ui->saturationSlider);
-  setValue(contrast,ui->contrastSlider);
-  setValue(sharpness,ui->sharpnessSlider);
-}
-
-int cameraControl::exec()
-{
-  if(!cameraActive) return false;
-  int timerID;
-  int result;
-  addToLog("cameracontrol exec",LOGCAM);
-  camera->startSnapshots();
-  timerID=startTimer(50);
-  result=QDialog::exec();
-  killTimer(timerID);
-  camera->abortCapture();
-  camera->stopStreaming();
-  if(result==QDialog::Accepted) return true;
-  return false;
-}
-
-
-void cameraControl::timerEvent(QTimerEvent *)
- {
-     if(camera->getFrame())
-      {
-        ui->imageFrame->openImage(*camera->getImage());
-      }
- }
-
-QImage *cameraControl::getImage()
-{
-  return camera->getImage();
-}
-
-void cameraControl::slotBrightnessSliderChanged()
-{
-  getParams();
-  camera->changeCtrl(videoCapture::Brightness,brightness);
-}
-
-void cameraControl::slotHueSliderChanged()
-{
-  getParams();
-  camera->changeCtrl(videoCapture::Hue,hue);
-}
-
-void cameraControl::slotSaturationSliderChanged()
-{
-  getParams();
-  camera->changeCtrl(videoCapture::Saturation,saturation);
-}
-
-void cameraControl::slotContrastSliderChanged()
-{
-  getParams();
-  camera->changeCtrl(videoCapture::Contrast,contrast);
-}
-
-void cameraControl::slotSharpnessSliderChanged()
-{
-  getParams();
-  camera->changeCtrl(videoCapture::Sharpness,sharpness);
-}
-
-
-
diff --git a/qsstv/widgets/cameracontrol.h b/qsstv/widgets/cameracontrol.h
deleted file mode 100644
index 98b1454..0000000
--- a/qsstv/widgets/cameracontrol.h
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef CAMERACONTROL_H
-#define CAMERACONTROL_H
-
-#include <QDialog>
-
-
-namespace Ui {
-    class cameraControl;
-}
-class videoCapture;
-
-
-class cameraControl : public QDialog
-{
-    Q_OBJECT
-
-public:
-    explicit cameraControl(QWidget *parent = 0);
-    ~cameraControl();
-    void readSettings();
-    void writeSettings();
-    int exec();
-    QImage *getImage();
-  private slots:
-    void slotBrightnessSliderChanged();
-    void slotHueSliderChanged();
-    void slotSaturationSliderChanged();
-    void slotContrastSliderChanged();
-    void slotSharpnessSliderChanged();
-
-private:
-    Ui::cameraControl *ui;
-    void getParams();
-    void setParams();
-    bool cameraActive;
-
-    int brightness;
-    int hue;
-    int saturation;
-    int contrast;
-    int sharpness;
-    videoCapture *camera;
-    void timerEvent(QTimerEvent *event);
-};
-
-#endif // CAMERACONTROL_H
diff --git a/qsstv/widgets/cameracontrol.ui b/qsstv/widgets/cameracontrol.ui
deleted file mode 100644
index 3bb34dd..0000000
--- a/qsstv/widgets/cameracontrol.ui
+++ /dev/null
@@ -1,400 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>cameraControl</class>
- <widget class="QDialog" name="cameraControl">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>230</width>
-    <height>364</height>
-   </rect>
-  </property>
-  <property name="font">
-   <font>
-    <pointsize>9</pointsize>
-   </font>
-  </property>
-  <property name="windowTitle">
-   <string>Dialog</string>
-  </property>
-  <layout class="QVBoxLayout" name="verticalLayout" stretch="1,0,0,0,0,0,0">
-   <property name="spacing">
-    <number>2</number>
-   </property>
-   <property name="margin">
-    <number>1</number>
-   </property>
-   <item>
-    <widget class="imageViewer" name="imageFrame">
-     <property name="frameShape">
-      <enum>QFrame::StyledPanel</enum>
-     </property>
-     <property name="frameShadow">
-      <enum>QFrame::Raised</enum>
-     </property>
-    </widget>
-   </item>
-   <item>
-    <layout class="QHBoxLayout" name="_5">
-     <item>
-      <widget class="QLabel" name="sharpnessLabel">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
-         <horstretch>0</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
-       </property>
-       <property name="minimumSize">
-        <size>
-         <width>100</width>
-         <height>0</height>
-        </size>
-       </property>
-       <property name="font">
-        <font>
-         <family>Courier [Xft]</family>
-         <pointsize>9</pointsize>
-         <weight>75</weight>
-         <bold>true</bold>
-        </font>
-       </property>
-       <property name="text">
-        <string>Sharpness</string>
-       </property>
-       <property name="alignment">
-        <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
-       </property>
-       <property name="wordWrap">
-        <bool>false</bool>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <widget class="QSlider" name="sharpnessSlider">
-       <property name="minimum">
-        <number>0</number>
-       </property>
-       <property name="maximum">
-        <number>255</number>
-       </property>
-       <property name="singleStep">
-        <number>1</number>
-       </property>
-       <property name="pageStep">
-        <number>10</number>
-       </property>
-       <property name="value">
-        <number>127</number>
-       </property>
-       <property name="orientation">
-        <enum>Qt::Horizontal</enum>
-       </property>
-       <property name="tickInterval">
-        <number>1000</number>
-       </property>
-      </widget>
-     </item>
-    </layout>
-   </item>
-   <item>
-    <layout class="QHBoxLayout" name="_4">
-     <property name="spacing">
-      <number>6</number>
-     </property>
-     <property name="margin">
-      <number>0</number>
-     </property>
-     <item>
-      <widget class="QLabel" name="brightnessLabel">
-       <property name="minimumSize">
-        <size>
-         <width>100</width>
-         <height>0</height>
-        </size>
-       </property>
-       <property name="font">
-        <font>
-         <family>Courier [Xft]</family>
-         <pointsize>9</pointsize>
-         <weight>75</weight>
-         <bold>true</bold>
-        </font>
-       </property>
-       <property name="text">
-        <string>Brightness</string>
-       </property>
-       <property name="alignment">
-        <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
-       </property>
-       <property name="wordWrap">
-        <bool>false</bool>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <widget class="QSlider" name="brightnessSlider">
-       <property name="maximum">
-        <number>255</number>
-       </property>
-       <property name="singleStep">
-        <number>1</number>
-       </property>
-       <property name="pageStep">
-        <number>10</number>
-       </property>
-       <property name="value">
-        <number>127</number>
-       </property>
-       <property name="orientation">
-        <enum>Qt::Horizontal</enum>
-       </property>
-       <property name="tickInterval">
-        <number>1000</number>
-       </property>
-      </widget>
-     </item>
-    </layout>
-   </item>
-   <item>
-    <layout class="QHBoxLayout" name="_3">
-     <property name="spacing">
-      <number>6</number>
-     </property>
-     <property name="margin">
-      <number>0</number>
-     </property>
-     <item>
-      <widget class="QLabel" name="hueLabel">
-       <property name="minimumSize">
-        <size>
-         <width>100</width>
-         <height>0</height>
-        </size>
-       </property>
-       <property name="font">
-        <font>
-         <family>Courier [Xft]</family>
-         <pointsize>9</pointsize>
-         <weight>75</weight>
-         <bold>true</bold>
-        </font>
-       </property>
-       <property name="text">
-        <string>Hue</string>
-       </property>
-       <property name="alignment">
-        <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
-       </property>
-       <property name="wordWrap">
-        <bool>false</bool>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <widget class="QSlider" name="hueSlider">
-       <property name="maximum">
-        <number>255</number>
-       </property>
-       <property name="singleStep">
-        <number>1</number>
-       </property>
-       <property name="pageStep">
-        <number>10</number>
-       </property>
-       <property name="value">
-        <number>127</number>
-       </property>
-       <property name="orientation">
-        <enum>Qt::Horizontal</enum>
-       </property>
-       <property name="tickInterval">
-        <number>1000</number>
-       </property>
-      </widget>
-     </item>
-    </layout>
-   </item>
-   <item>
-    <layout class="QHBoxLayout" name="_2">
-     <property name="spacing">
-      <number>6</number>
-     </property>
-     <property name="margin">
-      <number>0</number>
-     </property>
-     <item>
-      <widget class="QLabel" name="saturationLabel">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
-         <horstretch>0</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
-       </property>
-       <property name="minimumSize">
-        <size>
-         <width>100</width>
-         <height>0</height>
-        </size>
-       </property>
-       <property name="font">
-        <font>
-         <family>Courier [Xft]</family>
-         <pointsize>9</pointsize>
-         <weight>75</weight>
-         <bold>true</bold>
-        </font>
-       </property>
-       <property name="text">
-        <string>Saturation</string>
-       </property>
-       <property name="alignment">
-        <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
-       </property>
-       <property name="wordWrap">
-        <bool>false</bool>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <widget class="QSlider" name="saturationSlider">
-       <property name="maximum">
-        <number>255</number>
-       </property>
-       <property name="singleStep">
-        <number>1</number>
-       </property>
-       <property name="pageStep">
-        <number>10</number>
-       </property>
-       <property name="value">
-        <number>127</number>
-       </property>
-       <property name="orientation">
-        <enum>Qt::Horizontal</enum>
-       </property>
-       <property name="tickInterval">
-        <number>1000</number>
-       </property>
-      </widget>
-     </item>
-    </layout>
-   </item>
-   <item>
-    <layout class="QHBoxLayout">
-     <property name="spacing">
-      <number>6</number>
-     </property>
-     <property name="margin">
-      <number>0</number>
-     </property>
-     <item>
-      <widget class="QLabel" name="contrastLabel">
-       <property name="minimumSize">
-        <size>
-         <width>100</width>
-         <height>0</height>
-        </size>
-       </property>
-       <property name="font">
-        <font>
-         <family>Courier [Xft]</family>
-         <pointsize>9</pointsize>
-         <weight>75</weight>
-         <bold>true</bold>
-        </font>
-       </property>
-       <property name="text">
-        <string>Contrast</string>
-       </property>
-       <property name="alignment">
-        <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
-       </property>
-       <property name="wordWrap">
-        <bool>false</bool>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <widget class="QSlider" name="contrastSlider">
-       <property name="minimum">
-        <number>0</number>
-       </property>
-       <property name="maximum">
-        <number>255</number>
-       </property>
-       <property name="singleStep">
-        <number>1</number>
-       </property>
-       <property name="pageStep">
-        <number>10</number>
-       </property>
-       <property name="value">
-        <number>127</number>
-       </property>
-       <property name="orientation">
-        <enum>Qt::Horizontal</enum>
-       </property>
-       <property name="tickInterval">
-        <number>1000</number>
-       </property>
-      </widget>
-     </item>
-    </layout>
-   </item>
-   <item>
-    <widget class="QDialogButtonBox" name="buttonBox">
-     <property name="orientation">
-      <enum>Qt::Horizontal</enum>
-     </property>
-     <property name="standardButtons">
-      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
-     </property>
-    </widget>
-   </item>
-  </layout>
- </widget>
- <customwidgets>
-  <customwidget>
-   <class>imageViewer</class>
-   <extends>QFrame</extends>
-   <header>widgets/imageviewer.h</header>
-   <container>1</container>
-  </customwidget>
- </customwidgets>
- <resources/>
- <connections>
-  <connection>
-   <sender>buttonBox</sender>
-   <signal>accepted()</signal>
-   <receiver>cameraControl</receiver>
-   <slot>accept()</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>248</x>
-     <y>254</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>157</x>
-     <y>274</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
-   <sender>buttonBox</sender>
-   <signal>rejected()</signal>
-   <receiver>cameraControl</receiver>
-   <slot>reject()</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>316</x>
-     <y>260</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>286</x>
-     <y>274</y>
-    </hint>
-   </hints>
-  </connection>
- </connections>
-</ui>
diff --git a/qsstv/widgets/drmsegmentsview.cpp b/qsstv/widgets/drmsegmentsview.cpp
new file mode 100644
index 0000000..749e47f
--- /dev/null
+++ b/qsstv/widgets/drmsegmentsview.cpp
@@ -0,0 +1,75 @@
+#include "drmsegmentsview.h"
+#include <QPainter>
+#include <QDebug>
+#include <QPaintEvent>
+
+#include <math.h>
+
+
+drmSegmentsView::drmSegmentsView(QWidget *parent) :QLabel(parent)
+
+{
+  maxBlocks=1;
+  colFail=QColor(Qt::red);
+  colOK=QColor(Qt::green);
+  setFrameShape(QFrame::Box);
+  setFrameShadow(QFrame::Sunken);
+  setLineWidth(3);
+  setScaledContents(true);
+  blockListCount=-1;
+}
+
+drmSegmentsView::~drmSegmentsView()
+{
+
+}
+
+void drmSegmentsView::paintEvent(QPaintEvent *e)
+{
+  int i;
+  int blockX;
+  float blockWidth;
+
+  QRectF rct;
+  QLabel::paintEvent(e);
+//  if(blockListCount==blockList.count())
+//    {
+//      return;
+//    }
+//  blockListCount=blockList.count();
+  QPainter painter(this);
+  painter.setPen(QPen(colFail, 1, Qt::SolidLine));
+  painter.setBrush(QBrush(colFail));
+  painter.setRenderHint(QPainter::Antialiasing);
+
+  rct=QRectF(contentsRect().left(),contentsRect().top() ,contentsRect().width()-4 ,contentsRect().height()-4 );
+  blockWidth=(float)(contentsRect().width()-4)/maxBlocks;
+  painter.drawRect(rct);
+  painter.setBrush(QBrush(colOK));
+
+  painter.setPen(QPen(colOK, 1, Qt::SolidLine));
+  for(i=0;i<blockList.count();i++)
+    {
+
+      blockX=floor(blockList.at(i)*blockWidth)+contentsRect().left()+2;
+      painter.drawRect(blockX,contentsRect().top(),ceil(blockWidth),contentsRect().height()-4);
+    }
+}
+
+void drmSegmentsView::setColorFail(QColor color)
+{
+  colFail = color;
+
+}
+
+void drmSegmentsView::setColorOK(QColor color)
+{
+  colOK = color;
+}
+
+ void drmSegmentsView::setBlocks(QList<unsigned short> blkList)
+ {
+   blockList=blkList;
+ }
+
+
diff --git a/qsstv/widgets/drmsegmentsview.h b/qsstv/widgets/drmsegmentsview.h
new file mode 100644
index 0000000..b503773
--- /dev/null
+++ b/qsstv/widgets/drmsegmentsview.h
@@ -0,0 +1,37 @@
+#ifndef DRMSEGMENTSVIEW_H
+#define DRMSEGMENTSVIEW_H
+
+#include <QLabel>
+
+
+
+
+class drmSegmentsView : public QLabel
+{
+  Q_OBJECT
+
+public:
+  explicit drmSegmentsView(QWidget *parent = 0);
+  ~drmSegmentsView();
+  void setColorFail(QColor color);
+  void setColorOK(QColor color);
+  void setMaxBlocks(int mb) {
+   if(mb==0) maxBlocks=1;
+   else
+    maxBlocks=mb;}
+  void setBlocks(QList<short unsigned int> blkList);
+
+protected:
+
+    void paintEvent(QPaintEvent *e);
+
+private:
+
+  QColor colFail;
+  QColor colOK;
+  QList<short unsigned int> blockList;
+  short int maxBlocks;
+  int blockListCount;
+};
+
+#endif // DRMSEGMENTSVIEW_H
diff --git a/qsstv/widgets/drmsegmentsview.ui b/qsstv/widgets/drmsegmentsview.ui
new file mode 100644
index 0000000..227e4ae
--- /dev/null
+++ b/qsstv/widgets/drmsegmentsview.ui
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>drmSegmentsView</class>
+ <widget class="QWidget" name="drmSegmentsView">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>302</width>
+    <height>48</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <property name="autoFillBackground">
+   <bool>true</bool>
+  </property>
+  <layout class="QHBoxLayout" name="horizontalLayout">
+   <property name="spacing">
+    <number>0</number>
+   </property>
+   <property name="leftMargin">
+    <number>1</number>
+   </property>
+   <property name="topMargin">
+    <number>1</number>
+   </property>
+   <property name="rightMargin">
+    <number>1</number>
+   </property>
+   <property name="bottomMargin">
+    <number>1</number>
+   </property>
+   <item>
+    <widget class="QLabel" name="drmSegmentLabel">
+     <property name="frameShape">
+      <enum>QFrame::Box</enum>
+     </property>
+     <property name="frameShadow">
+      <enum>QFrame::Sunken</enum>
+     </property>
+     <property name="lineWidth">
+      <number>3</number>
+     </property>
+     <property name="text">
+      <string>TextLabel</string>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/qsstv/widgets/extviewer.cpp b/qsstv/widgets/extviewer.cpp
new file mode 100644
index 0000000..40770cd
--- /dev/null
+++ b/qsstv/widgets/extviewer.cpp
@@ -0,0 +1,31 @@
+#include "extviewer.h"
+#include "ui_extviewer.h"
+#include <QFileInfo>
+#include <QDebug>
+
+extViewer::extViewer(QWidget *parent) :   QDialog(parent),   ui(new Ui::extViewer)
+{
+  ui->setupUi(this);
+  activeMovie=false;
+  setModal(false);
+}
+
+extViewer::~extViewer()
+{
+  delete ui;
+}
+
+
+void extViewer::setup(QString fn)
+{
+  int fw,fh;
+
+  // we want the original image
+  ui->imViewer->openImage(fn,false,false,false);
+  fileName=fn;
+  QFileInfo fi(fn);
+  fw=ui->imViewer-> getImagePtr()->width();
+  fh=ui->imViewer->getImagePtr()->height();
+  ui->lineEdit->setText(QString("%1 %2x%3").arg(fi.fileName()).arg(fw).arg(fh));
+}
+
diff --git a/qsstv/widgets/extviewer.h b/qsstv/widgets/extviewer.h
new file mode 100644
index 0000000..1b5d30a
--- /dev/null
+++ b/qsstv/widgets/extviewer.h
@@ -0,0 +1,30 @@
+#ifndef EXTVIEWER_H
+#define EXTVIEWER_H
+
+#include <QDialog>
+#include <QMovie>
+
+namespace Ui {
+class extViewer;
+}
+
+class extViewer : public QDialog
+{
+  Q_OBJECT
+  
+public:
+  explicit extViewer(QWidget *parent = 0);
+  ~extViewer();
+  void setup(QString fn);
+  
+private:
+  Ui::extViewer *ui;
+  int w,h;
+  int labelWidth,labelHeight;
+  QString fileName;
+  QMovie qm;
+  QImage im;
+  bool activeMovie;
+};
+
+#endif // EXTVIEWER_H
diff --git a/qsstv/widgets/extviewer.ui b/qsstv/widgets/extviewer.ui
new file mode 100644
index 0000000..82ede73
--- /dev/null
+++ b/qsstv/widgets/extviewer.ui
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>extViewer</class>
+ <widget class="QDialog" name="extViewer">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>524</width>
+    <height>327</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Viewer</string>
+  </property>
+  <property name="windowIcon">
+   <iconset resource="../qsstv.qrc">
+    <normaloff>:/icons/qsstv.png</normaloff>:/icons/qsstv.png</iconset>
+  </property>
+  <property name="sizeGripEnabled">
+   <bool>true</bool>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="imageViewer" name="imViewer" native="true"/>
+   </item>
+   <item>
+    <widget class="QLineEdit" name="lineEdit"/>
+   </item>
+  </layout>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>imageViewer</class>
+   <extends>QWidget</extends>
+   <header>widgets/imageviewer.h</header>
+   <container>1</container>
+  </customwidget>
+ </customwidgets>
+ <resources>
+  <include location="../qsstv.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/qsstv/widgets/fftdisplay.cpp b/qsstv/widgets/fftdisplay.cpp
index 86cc0de..56cb4a1 100644
--- a/qsstv/widgets/fftdisplay.cpp
+++ b/qsstv/widgets/fftdisplay.cpp
@@ -1,205 +1,158 @@
 #include "fftdisplay.h"
-#include "qsstvglobal.h"
+#include "appglobal.h"
+#include "configparams.h"
 #include "math.h"
+#include "arraydumper.h"
 #include <QPainter>
 
 
-
-
-
-
-
 fftDisplay::fftDisplay(QWidget *parent) : QLabel(parent)
 {
-  blockIndex=0;
-  arMag=NULL;
-  arMagAvg=NULL;
-//  ready=false;
-  windowWidth=0;
-  windowHeight=0;
-  im=NULL;
+  //  blockIndex=0;
+  arMagSAvg=NULL;
+  //  hammingBuffer=NULL;
   fftArray=NULL;
-//  windowWidth=294;windowHeight=112;
-//  im=new QImage( windowWidth,windowHeight,QImage::Format_RGB32);
-  setSize(120,180);
-
-  out=NULL;
-  dataBuffer=NULL;
+  //  out=NULL;
+  //  dataBuffer=NULL;
   showWaterfall=false;
   fftMax=FFTMAX;
   range=RANGE;
+  avgVal=0.05;
+  //  plan=0;
+  setScaledContents(true);
+  imagePtr=NULL;
+  imWidth=-1;
+  imHeight=-1;
+  arMagWAvg=NULL;
+  displayCounter=0;
 }
 
 fftDisplay::~fftDisplay()
 {
-//  ready=false;
-  delete im;
+  delete imagePtr;
   if(fftArray) delete fftArray;
-  fftw_destroy_plan(plan);
-  if(out) fftw_free(out);
-  if(dataBuffer) fftw_free(dataBuffer);
-  if (arMag) delete [] arMag;
-  if(arMagAvg) delete []arMagAvg;
+  if(arMagSAvg) delete []arMagSAvg;
+  if(arMagWAvg) delete []arMagWAvg;
 }
 
 
-
-void fftDisplay::setSize(int w,int h)
-{
-  windowWidth=w;
-  windowHeight=h;
-  if(w==0 || h==0)
-  {
-
-      qDebug() << "Null Image";
-  }
-  if(im)
-    {
-      *im=im->scaled(QSize(windowWidth, windowHeight));
-     }
-  else
-    {
-      im=new QImage( windowWidth,windowHeight,QImage::Format_RGB32);
-      im->fill(Qt::black);
-    }
-  if(fftArray) delete fftArray;
-  fftArray=new QPolygon(windowWidth);
-
-  if(arMag) delete []arMag;
-  arMag=new double[windowWidth];
-  if(arMagAvg) delete []arMagAvg;
-  arMagAvg=new double[windowWidth];
-  for(int i=0;i<windowWidth;i++) arMag[i]=0.;
-  for(int i=0;i<windowWidth;i++) arMagAvg[i]=0.;
-}
-
-
-
-void fftDisplay::init(int size,int nblocks,int isamplingrate)
+void fftDisplay::init(int length,int nblocks,int isamplingrate)
 {
   int i;
-  windowSize=size;
+  windowSize=length;
   fftLength=windowSize*nblocks;
-  blocks=nblocks;
-  createHamming();
   samplingrate=isamplingrate;
-  //prepare fft
-  out = (double *)fftw_malloc(fftLength * sizeof(double));
-  dataBuffer  = (double *)fftw_malloc(fftLength * sizeof(double));
-  arMag=new double[windowSize];
-  for(i=0;i<windowWidth;i++) arMag[i]=0.;
-  arMagAvg=new double[windowSize];
-  for(i=0;i<windowWidth;i++) arMagAvg[i]=0.;
-  fftArray=new QPolygon(windowWidth);
-   // create the fftw plan
-  plan = fftw_plan_r2r_1d(fftLength, dataBuffer, out, FFTW_R2HC, FFTW_ESTIMATE);
-  update();
-  QLabel::update();
+  if(fftArray) delete fftArray;
+  if(arMagSAvg) delete [] arMagSAvg;
+  step=(double)samplingrate/(double)fftLength;  //freq step per bin
+  binBegin=(int) rint(FFTLOW/step);
+  binEnd  =(int) rint(FFTHIGH/step);
+  binDiff=binEnd-binBegin;
 
-}
+  fftArray=new QPolygon(binDiff);
+  arMagSAvg=new double[binDiff];
 
-void fftDisplay::createHamming()
-{
-  int i;
-  hammingBuffer= new double[fftLength];
-  for(i=0;i<fftLength;i++)
+  for(i=0;i<binDiff;i++)
     {
-      hammingBuffer[i]=0.54-(0.46*cos(2*M_PI*((double)i/((double)(fftLength-1)))));
+      arMagSAvg[i]=-30.;
     }
 
+  // create the fftw plan
+  //  plan = fftw_plan_r2r_1d(fftLength, dataBuffer, out, FFTW_R2HC, FFTW_ESTIMATE);
+  update();
+  QLabel::update();
 }
 
-void fftDisplay::realFFT(short int *data)
-{
-  int i,j;
-  for(i=0,j=windowSize*blockIndex;i<windowSize;i++,j++)
-  {
-    dataBuffer[j]=(double)data[i];
-  }
-  doFFT();
-}
 
-void fftDisplay::realFFT(float *data)
-{
-  int i,j;
-  double max=0;
-  for(i=0,j=windowSize*blockIndex;i<windowSize;i++,j++)
-  {
-    dataBuffer[j]=(double)data[i];
-    if(dataBuffer[j]>max) max=dataBuffer[j];
-  }
-  doFFT();
-}
 
-void fftDisplay::realFFT(double *data)
-{
-  int i,j;
-  for(i=0,j=windowSize*blockIndex;i<windowSize;i++,j++)
-  {
-    dataBuffer[j]=data[i];
 
-  }
-  doFFT();
+void fftDisplay::setMarkers(int mrk1, int mrk2, int mrk3)
+{
+  marker1=mrk1;
+  marker2=mrk2;
+  marker3=mrk3;
+  update();
 }
 
-void fftDisplay::doFFT()
+void fftDisplay::showFFT(double *fftData)
 {
-  int i;
-  double val;
-  double re,imag,tmp,step;
-  double maxTmp=0;
-  double magTmp;
+  int i,j;
   QColor c;
-  blockIndex++;
-  if(blockIndex<blocks) return;
-  blockIndex=0;
-//   apply hamming
-//  if(!ready) return;
-  for(i=0;i<fftLength;i++)
+  double re,imag,tmp;
+  if((!showWaterfall) && (slowCPU))
     {
-
-      dataBuffer[i]*=hammingBuffer[i];
-      if(dataBuffer[i]>maxTmp) maxTmp=dataBuffer[i];
+      if(displayCounter++<1) return;
+      else displayCounter=0;
     }
-
-  fftw_execute(plan);
-  step=(double)samplingrate/(double)fftLength;  //freq step per bin
-  arMag[0]=0;
-  arMagAvg[0]=0;
-  for(i=0;i<windowWidth;i++)
+  if((imWidth!=width()) || (imHeight!=height()))
     {
-      int idx=rint((FFTLOW+(i*FFTSPAN)/windowWidth)/step);
-      re=out[idx]/fftLength;
-      imag=out[fftLength-idx]/fftLength;
-      tmp=10*log10(2*(re*re+imag*imag))-55;
-      arMag[i]=tmp;
-      if(arMagAvg[i]<tmp) arMagAvg[i]=tmp;
-      else arMagAvg[i]=arMagAvg[i]*(1-VALAVG)+VALAVG*tmp;
+      if(imWidth!=width())
+        {
+          if(arMagWAvg!=NULL) delete [] arMagWAvg;
+          arMagWAvg=new double[width()];
+          for(i=0;i<width();i++)
+            {
+              arMagWAvg[i]=0;
+            }
+        }
+      imWidth=width();
+      imHeight=height();
+      if(showWaterfall)
+        {
+          if(imagePtr==NULL)
+            {
+              imagePtr=new QImage( width(),height(),QImage::Format_RGB32);
+              imagePtr->fill(Qt::black);
+            }
+          else
+            {
+
+              *imagePtr=imagePtr->scaled(QSize(imWidth,imHeight));
+            }
+        }
     }
-  maxMagnitude=fftMax;
-
-  for(i=0;i<windowWidth;i++)
+  if(!showWaterfall)
     {
-      magTmp=arMagAvg[i];
-      if(magTmp<(maxMagnitude-range)) magTmp=maxMagnitude-range;
-      fftArray->setPoint(i,i,((windowHeight)*(maxMagnitude-magTmp))/range);
+      for (i=binBegin,j=0;i<binEnd;i++,j++)
+        {
+          re=fftData[i]/fftLength;
+          imag=fftData[fftLength-i]/fftLength;
+          tmp=10*log10((re*re+imag*imag))-77.27;  // 0.5 Vtt is 0db
+          if(arMagSAvg[j]<-100)
+            {
+              arMagSAvg[j]=-100;
+            }
+          if(arMagSAvg[j]<tmp)  arMagSAvg[j]=arMagSAvg[j]*(1-0.4)+0.4*tmp;
+          else arMagSAvg[j]=arMagSAvg[j]*(1-avgVal)+avgVal*tmp;
+          tmp=(fftMax-arMagSAvg[j])/range;
+          if(tmp<0) tmp=0;
+          if (tmp>1)tmp=1;
+          int pos=(int)rint((double)(j*(imWidth-1))/(double)binDiff);
+          fftArray->setPoint(j,pos,(imHeight-1)*tmp); // range 0 -> -1
+        }
     }
-  memmove(im->scanLine(1),im->scanLine(0),(windowWidth*(windowHeight-2))*sizeof(uint));
-  uint *ptr=(uint *)im->scanLine(0);
-  for(i=0;i<windowWidth;i++)
+  else
     {
-      //              arMag[i]=fftMin;
-      if(arMag[i]>fftMax) arMag[i]=fftMax;
-      if(arMag[i]<fftMax-range) arMag[i]=fftMax-range;
-      val=((arMag[i]-(fftMax-range))/range); // value in range 0-1
-      if(val<0) val=0;
-      if(val>1) val=1;
-      //              tmp=rint(180*((double)i)/((double)FFTSPAN));
-      //              c.setHsv(240-val*240,255,255);
-      c.setHsv(240-val*60,255,val*255);
-      //      c.setRgb(val*255,val*255,val*255);
-      ptr[i]=c.rgb();
-      //              ptr[i]=(uint) val*256+255;
+
+      memmove(imagePtr->scanLine(1),imagePtr->scanLine(0),(imWidth*(imHeight-2))*sizeof(uint));
+      uint *ptr=(uint *)imagePtr->scanLine(0);
+      for(i=0;i<imWidth;i++)
+        {
+          int idx=rint((double)(FFTLOW+(i*FFTSPAN)/(double)imWidth)/step);
+          re=fftData[idx]/fftLength;
+          imag=fftData[fftLength-idx]/fftLength;
+          tmp=10*log10((re*re+imag*imag))-77.27;  // 0.5 Vtt is 0db
+          arMagWAvg[i]=arMagWAvg[i]*(1-avgVal)+avgVal*tmp;
+          if( arMagWAvg[i]<-100)
+            {
+               arMagWAvg[i]=-100;
+            }
+          tmp=1-(fftMax-arMagWAvg[i])/range;
+          if(tmp<0) tmp=0;
+          if (tmp>1)tmp=1;
+          c.setHsv(240-tmp*60,255,tmp*255);
+          ptr[i]=c.rgb();
+        }
     }
   update();
 }
@@ -209,46 +162,29 @@ void fftDisplay::doFFT()
 
 void fftDisplay::paintEvent(QPaintEvent *p)
 {
-
   QPen pn;
-
-  //  if(!ready) return;
   QPainter painter(this);
-  //  painter.setWindow(0,0,windowWidth,windowHeight);
-  if((windowWidth!=width())||(windowHeight!=height()))
-    {
-      setSize(width(),height());
-      return;
-    }
-  //  painter.setRenderHint(QPainter::Antialiasing);
+  painter.setRenderHint(QPainter::Antialiasing);
   if(!showWaterfall)
     {
       pn.setColor(Qt::red);
       pn.setWidth(1);
       painter.setPen(pn);
-      painter.drawLine((((marker1-FFTLOW)*windowWidth)/FFTSPAN),0,(((marker1-FFTLOW)*windowWidth)/FFTSPAN),windowHeight);
-      painter.drawLine((((marker2-FFTLOW)*windowWidth)/FFTSPAN),0,(((marker2-FFTLOW)*windowWidth)/FFTSPAN),windowHeight);
-      painter.drawLine((((marker3-FFTLOW)*windowWidth)/FFTSPAN),0,(((marker3-FFTLOW)*windowWidth)/FFTSPAN),windowHeight);
-
+      painter.drawLine((((marker1-FFTLOW)*imWidth)/FFTSPAN),0,(((marker1-FFTLOW)*imWidth)/FFTSPAN),imHeight);
+      painter.drawLine((((marker2-FFTLOW)*imWidth)/FFTSPAN),0,(((marker2-FFTLOW)*imWidth)/FFTSPAN),imHeight);
+      painter.drawLine((((marker3-FFTLOW)*imWidth)/FFTSPAN),0,(((marker3-FFTLOW)*imWidth)/FFTSPAN),imHeight);
       pn.setColor(Qt::green);
       painter.setPen(pn);
       painter.drawPolyline(*fftArray);
-
     }
   else
     {
-      painter.drawImage(0,0,*im);
+      if(imagePtr)
+        {
+          scaledImage=imagePtr->scaled(QSize(width(),height()));
+          painter.drawImage(0,0,scaledImage);
+        }
     }
   QLabel::paintEvent(p);
 }
 
-
-
-void fftDisplay::mousePressEvent( QMouseEvent *e )
-{
-  if (e->button() == Qt::LeftButton)
-    {
-      showWaterfall=!showWaterfall;
-    }
-}
-
diff --git a/qsstv/widgets/fftdisplay.h b/qsstv/widgets/fftdisplay.h
index 91bf8c3..0b48eb4 100644
--- a/qsstv/widgets/fftdisplay.h
+++ b/qsstv/widgets/fftdisplay.h
@@ -2,18 +2,19 @@
 #define FFTDISPLAY_H
 #include <QtGui>
 #include <QLabel>
-#include "qsstvdefs.h"
+#include "appdefs.h"
 #include "fftw3.h"
 #include <qpolygon.h>
 #include <QImage>
 
 
 #define FFTAVERAGING 0.1
-#define VALAVG 0.02
-#define FFTHIGH 3000
+#define VOLAVG 0.1
+//#define VALAVG 1.
+#define FFTHIGH 2900
 #define FFTLOW  200
 #define FFTSPAN (FFTHIGH-FFTLOW)
-#define FFTMAX 75.
+#define FFTMAX 6
 #define RANGE 30.
 
 class fftDisplay : public QLabel
@@ -23,49 +24,44 @@ class fftDisplay : public QLabel
 public:
   explicit fftDisplay(QWidget *parent=0);
   ~fftDisplay();
-
-  void init(int size,int slices,int isamplingrate);
-  void realFFT(short int *iBuffer);
-  void realFFT(float *iBuffer);
-  void realFFT(double *iBuffer);
+  void init(int length, int slices, int isamplingrate);
+  void showFFT(double *fftData);
   void setMaxDb(int mb){fftMax=mb;}
   void setRange(int rg) {range=rg;}
   void displayWaterfall(bool wf) {showWaterfall=wf;}
-  void setMarkers(int mrk1=0, int mrk2=0, int mrk3=0){ marker1=mrk1;marker2=mrk2;marker3=mrk3;update();}
-
+  void setMarkers(int mrk1=0, int mrk2=0, int mrk3=0);
+  void setAvg(double d) {avgVal=d;}
 
 private:
-  void createHamming();
-  void doFFT();
+
   void paintEvent(QPaintEvent *p);
-  void mousePressEvent( QMouseEvent *e );
-  double *hammingBuffer;
-  double *dataBuffer;
+//  void mousePressEvent( QMouseEvent *e );
   int windowSize;
   int fftLength;
   int samplingrate;
-  unsigned int blocks;
-  unsigned int blockIndex;
-  fftw_plan plan;
-  double *arMag;
-  double *arMagAvg;
-  double *out;
+  double *arMagSAvg;
+  double *arMagWAvg;
   double maxMagnitude;
   QPolygon *fftArray;
 //  bool ready;
   bool showWaterfall;
   double fftMax;
-  double fftMin;
   double range;
-  QImage *im;
-  int windowWidth;
-  int windowHeight;
-  void setSize(int w,int h);
+  QImage *imagePtr;
+  QImage scaledImage;
+//  void setSize(int w,int h);
   QMutex mutex;
   int marker1;
   int marker2;
   int marker3;
-
+  double step;  //freq step per bin
+  int binBegin;
+  int binEnd;
+  int binDiff;
+  double avgVal;
+  int imWidth;
+  int imHeight;
+  int displayCounter;
 };
 
 #endif // FFTDISPLAY_H
diff --git a/qsstv/widgets/imagematrix.cpp b/qsstv/widgets/imagematrix.cpp
new file mode 100644
index 0000000..5f92e23
--- /dev/null
+++ b/qsstv/widgets/imagematrix.cpp
@@ -0,0 +1,219 @@
+#include "imagematrix.h"
+#include <QDir>
+#include <QDebug>
+#include <iostream>
+
+#define MINCOLSIZE 32
+#define MINROWSIZE 26
+#define MAXCOLSIZE 64
+#define MAXROWSIZE 52
+
+
+imageMatrix::imageMatrix(QWidget *parent) :  QWidget(parent)
+{
+
+  parentPtr=parent;
+  parentPtr->resize(511, 300);
+  verticalLayout = NULL;
+  horizontalLayout=NULL;
+  sortFlags=QDir::Time;
+}
+
+imageMatrix::~imageMatrix()
+{
+//  if(verticalLayout!=NULL) delete verticalLayout;
+//  if( horizontalLayout!=NULL) delete horizontalLayout;
+}
+
+void imageMatrix::setupLayout()
+{
+  if(verticalLayout!=NULL) delete verticalLayout;
+  verticalLayout = new QVBoxLayout(parentPtr);
+  horizontalLayout=new QHBoxLayout();
+  verticalLayout->setObjectName(QString::fromUtf8("vt1"));
+  verticalLayout->setSpacing(2);
+  verticalLayout->setContentsMargins(1, 1, 1, 1);
+  gridLayout = new QGridLayout();
+  gridLayout->setSpacing(1);
+  gridLayout->setObjectName(QString::fromUtf8("gridLo"));
+  gridLayout->setSizeConstraint(QLayout::SetNoConstraint);
+  verticalLayout->addLayout(gridLayout);
+
+  horizontalLayout = new QHBoxLayout();
+  horizontalLayout->setObjectName(QString::fromUtf8("htl"));
+  horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+  horizontalLayout->addItem(horizontalSpacer);
+
+  beginPushButton = new QPushButton(this);
+  beginPushButton->setObjectName(QString::fromUtf8("beginPushButton"));
+  QIcon icon2;
+  icon2.addFile(QString::fromUtf8(":/icons/doubleleft.png"), QSize(), QIcon::Normal, QIcon::Off);
+  beginPushButton->setIcon(icon2);
+  horizontalLayout->addWidget(beginPushButton);
+
+  prevPushButton = new QPushButton(this);
+  prevPushButton->setObjectName(QString::fromUtf8("prevPushButton"));
+  QIcon icon;
+  icon.addFile(QString::fromUtf8(":/icons/left.png"), QSize(), QIcon::Normal, QIcon::Off);
+  prevPushButton->setIcon(icon);
+  horizontalLayout->addWidget(prevPushButton);
+  pageLabel=new QLabel;
+  horizontalLayout->addWidget(pageLabel);
+
+//  horizontalSpacer_2 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+//  horizontalLayout->addItem(horizontalSpacer_2);
+  nextPushButton = new QPushButton(this);
+  nextPushButton->setObjectName(QString::fromUtf8("nextPushButton"));
+  QIcon icon1;
+  icon1.addFile(QString::fromUtf8(":/icons/start.png"), QSize(), QIcon::Normal, QIcon::Off);
+  nextPushButton->setIcon(icon1);
+  horizontalLayout->addWidget(nextPushButton);
+
+  endPushButton = new QPushButton(this);
+  endPushButton->setObjectName(QString::fromUtf8("endPushButton"));
+  QIcon icon3;
+  icon3.addFile(QString::fromUtf8(":/icons/doubleright.png"), QSize(), QIcon::Normal, QIcon::Off);
+  endPushButton->setIcon(icon3);
+  horizontalLayout->addWidget(endPushButton);
+
+  horizontalSpacer_3 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+  horizontalLayout->addItem(horizontalSpacer_3);
+  verticalLayout->addLayout(horizontalLayout);
+  connect(prevPushButton,SIGNAL(clicked()),SLOT(slotPrev()));
+  connect(nextPushButton,SIGNAL(clicked()),SLOT(slotNext()));
+  connect(beginPushButton,SIGNAL(clicked()),SLOT(slotBegin()));
+  connect(endPushButton,SIGNAL(clicked()),SLOT(slotEnd()));
+}
+
+
+void imageMatrix::init(int numRows, int numColumns, QString dir,imageViewer::thumbType tt)
+{
+  int i,j;
+  rows=numRows;
+  columns=numColumns;
+  dirPath=dir;
+  imageViewer *imv;
+  setupLayout();
+  for(i=0;i<rows;i++)
+    {
+      for(j=0;j<columns;j++)
+        {
+          imv = new imageViewer(this);
+          imv->setType(tt);
+          gridLayout->addWidget(imv, i, j, 1, 1);
+          connect(imv,SIGNAL(layoutChanged()),SLOT(slotLayoutChanged()));
+        }
+    }
+  for (i=0;i<rows;i++)
+    {
+      gridLayout->setRowMinimumHeight(i,MINROWSIZE);
+      gridLayout->setRowStretch(i,0);
+    }
+
+  for (i=0;i<columns;i++)
+    {
+      gridLayout->setColumnMinimumWidth(i,MINCOLSIZE);
+      gridLayout->setColumnStretch(i,1);
+    }
+  currentPage=0;
+  getList();
+//  displayFiles();
+}
+
+
+void imageMatrix::getList()
+{
+
+
+  QDir dir(dirPath);
+  dir.setFilter(QDir::Files | QDir::NoSymLinks);
+  dir.setSorting(sortFlags);
+  fileList = dir.entryInfoList();
+  numPages=ceil((double)fileList.count()/(double)(rows*columns));
+  if(numPages==0) numPages=1;
+  slotBegin();
+}
+
+QString imageMatrix::getLastFile()
+{
+  if (fileList.count()>0)
+    {
+      return fileList.last().absoluteFilePath();
+    }
+  else return QString();
+}
+
+void imageMatrix::displayFiles()
+{
+  int i,j,k;
+
+  QString tempStr;
+  int offset=currentPage*rows*columns;
+  pageLabel->setText(QString("   Page %1 of %2").arg(currentPage+1).arg(numPages).leftJustified(17,' '));
+  for(i=0;i<rows;i++)
+    {
+      for(j=0;j<columns;)
+        {
+          k=offset+i*columns+j;
+          if(k>=fileList.count())
+            {
+              ((imageViewer *)gridLayout->itemAtPosition(i,j)->widget())->clear();
+              j++;
+            }
+          else
+            {
+           tempStr=fileList.at(k).absoluteFilePath();
+           if(((imageViewer *)gridLayout->itemAtPosition(i,j)->widget())->openImage(tempStr,false,false,true))
+             {
+                j++;
+             }
+           else
+             {
+               fileList.removeAt(k);
+             }
+            }
+        }
+    }
+}
+
+void imageMatrix::changed()
+{
+    getList();
+//    displayFiles();
+}
+
+
+void imageMatrix::slotPrev()
+{
+  if(currentPage!=0) currentPage--;
+  displayFiles();
+}
+
+void imageMatrix::slotNext()
+{
+  currentPage++;
+  if(currentPage>=numPages)
+    {
+      currentPage--;
+    }
+  displayFiles();
+}
+
+void imageMatrix::slotBegin()
+{
+  currentPage=0;
+  displayFiles();
+}
+
+void imageMatrix::slotEnd()
+{
+  currentPage=numPages-1;
+  if(currentPage<0) currentPage=0;
+  displayFiles();
+}
+
+void imageMatrix::slotLayoutChanged()
+{
+  getList();
+  displayFiles();
+}
diff --git a/qsstv/widgets/imagematrix.h b/qsstv/widgets/imagematrix.h
new file mode 100644
index 0000000..3397943
--- /dev/null
+++ b/qsstv/widgets/imagematrix.h
@@ -0,0 +1,60 @@
+#ifndef IMAGEMATRIX_H
+#define IMAGEMATRIX_H
+
+#include <QWidget>
+#include <QList>
+#include <QVBoxLayout>
+#include <QGridLayout>
+#include "widgets/imageviewer.h"
+
+
+
+class imageMatrix : public QWidget
+{
+  Q_OBJECT
+  
+public:
+  explicit imageMatrix(QWidget *parent = 0);
+  ~imageMatrix();
+  void init(int numRows, int numColumns, QString dir, imageViewer::thumbType tt);
+  void setupFiles();
+  void changed();
+  QFileInfoList getFileList(){return fileList;}
+  QString getLastFile();
+  void setSortFlag(QDir::SortFlags sf) {sortFlags=sf;}
+
+private:
+  void getList();
+  void displayFiles();
+  void setupLayout();
+  QVBoxLayout *verticalLayout;
+  QHBoxLayout *horizontalLayout;
+  QGridLayout *gridLayout;
+  QSpacerItem *horizontalSpacer;
+  QSpacerItem *horizontalSpacer_2;
+  QSpacerItem *horizontalSpacer_3;
+  QString dirPath;
+  QPushButton *prevPushButton;
+  QPushButton *nextPushButton;
+  QPushButton *beginPushButton;
+  QPushButton *endPushButton;
+  QLabel *pageLabel;
+  QList<imageViewer *> imageViewerPtrList;
+  QFileInfoList fileList;
+  int rows;
+  int columns;
+  int numPages;
+  int currentPage;
+  QWidget *parentPtr;
+  QDir::SortFlags sortFlags;
+
+private slots:
+  void slotPrev();
+  void slotNext();
+  void slotBegin();
+  void slotEnd();
+  void slotLayoutChanged();
+
+};
+
+#endif // IMAGEMATRIX_H
diff --git a/qsstv/widgets/imageviewer.cpp b/qsstv/widgets/imageviewer.cpp
index 77af53f..289c503 100644
--- a/qsstv/widgets/imageviewer.cpp
+++ b/qsstv/widgets/imageviewer.cpp
@@ -19,17 +19,21 @@
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 #include "imageviewer.h"
-#include "utils/supportfunctions.h"
+#include "appglobal.h"
 #include "utils/logging.h"
 #include "configparams.h"
 #include "dispatcher.h"
-#include "txwidget.h"
-#include "utils/qjp2io.h"
+#include "dirdialog.h"
+#include "extviewer.h"
+#include "jp2io.h"
+#include <configdialog.h>
+
 
 #include <QtGui>
 #include <QMenu>
 
-#define RATIOSCALE 800.
+#define RATIOSCALE 1.
+
 
 /**
   \class imageViewer
@@ -54,7 +58,7 @@ imageViewer::imageViewer(QWidget *parent): QLabel(parent)
   setPalette(palette);
   setBackgroundRole(QPalette::Base);
   setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
-  setScaledContents(true);
+
   setBackgroundRole(QPalette::Dark);
 
   popup=new QMenu (this);
@@ -70,23 +74,12 @@ imageViewer::imageViewer(QWidget *parent): QLabel(parent)
   connect(printAct, SIGNAL(triggered()), this, SLOT(slotPrint()));
   deleteAct = new QAction(tr("&Delete"), this);
   connect(deleteAct, SIGNAL(triggered()), this, SLOT(slotDelete()));
+  viewAct = new QAction(tr("&View"), this);
+  connect(viewAct, SIGNAL(triggered()), this, SLOT(slotView()));
   propertiesAct = new QAction(tr("Propert&ies"), this);
   connect(propertiesAct, SIGNAL(triggered()), this, SLOT(slotProperties()));
-  popup->addAction(newAct);
-  popup->addAction(loadAct);
-  popup->addAction(toTXAct);
-  popup->addAction(editAct);
-  popup->addAction(printAct);
-  popup->addAction(deleteAct);
-  popup->addAction(propertiesAct);
-  setScaledContents(false);
-  setAlignment(Qt::AlignCenter);
-  setAutoFillBackground(true);
-  QPalette mpalette;
-  mpalette.setColor(QPalette::Window,QColor(0,0,128));
-  setBackgroundRole(QPalette::Window);
-  mpalette.setColor(QPalette::WindowText, Qt::yellow);
-  setPalette(mpalette);
+  connect(configDialogPtr,SIGNAL(bgColorChanged()), SLOT(slotBGColorChanged()));
+
   init(RXIMG);
   activeMovie=false;
   //
@@ -101,108 +94,158 @@ void imageViewer::init(thumbType tp)
   setScaledContents(false);
   setAlignment(Qt::AlignCenter);
   setAutoFillBackground(true);
-  QPalette mpalette;
-  mpalette.setColor(QPalette::Window,QColor(0,0,128));
-  setBackgroundRole(QPalette::Window);
-  mpalette.setColor(QPalette::WindowText, Qt::yellow);
-  setPalette(mpalette);
-  addToLog("image creation",LOGIMAG);
-  imageFileName="";
-  image=QImage();
+  slotBGColorChanged();
+  addToLog(QString("image creation %1").arg(tp),LOGIMAG);
   setType(tp);
-  popupEnabled=true;
   setPixmap(QPixmap());
   clear();
 }
 
-bool imageViewer::openImage(QString &filename,QString start,bool ask,bool showMessage,bool emitSignal)
+bool imageViewer::openImage(QString &filename,QString start,bool ask,bool showMessage,bool emitSignal,bool fromCache)
 {
   QImage tempImage;
+  QFile fi(filename);
+  QFileInfo finf(filename);
+  QString cacheFileName;
+  jp2IO jp2;
   displayMBoxEvent *stmb=0;
   editorScene ed;
+  bool success=false;
+  bool cacheHit=false;
+  cacheFileName=finf.absolutePath()+"/cache/"+finf.baseName()+finf.created().toString()+".png";
+
   if(activeMovie)
-    {
-      activeMovie=false;
-      qm.stop();
-    }
+  {
+    activeMovie=false;
+    qm.stop();
+  }
   if (filename.isEmpty()&&!ask) return false;
   if(ask)
+  {
+    dirDialog dd((QWidget *)this,"Browse");
+    filename=dd.openFileName(start,"*");
+  }
+  if(filename.isEmpty())
+  {
+    imageFileName="";
+    return false;
+  }
+
+  if(fromCache)
+  {
+    if(tempImage.load(cacheFileName))
     {
-      dirDialog dd((QWidget *)this,"Browse");
-      filename=dd.openFileName(start,"*");
+      cacheHit=true;
+      success=true;
+      orgWidth=tempImage.text("orgWidth").toInt();
+      orgHeight=tempImage.text("orgHeight").toInt();
     }
-  if(filename.isEmpty())
+  }
+  if(!success)
+  {
+    if(tempImage.load(filename))
     {
-      imageFileName="";
-      return false;
+      success=true;
     }
-  if(!tempImage.load(filename))
+    else if(ed.load(fi))
     {
-      QFile fi(filename);
-      // try to load it with the editor, it coud be a template file
-      if(!ed.load(fi))
-        {
-          //try loading jpg2
-          tempImage=readJP2Image(filename);
-          if(tempImage.isNull())
-            {
-              if(showMessage)
-                {
-                  stmb= new displayMBoxEvent("Image Loader",QString("Unable to load image:\n%1").arg(filename));
-                  QApplication::postEvent( dispatcherPtr, stmb );  // Qt will delete it when done
-                }
-              validImage=false;
-              imageFileName="";
-              return false;
-            }
-        }
-      else
-        {
-          tempImage=QImage(ed.renderImage(0,0)->copy());
-        }
+      success=true;
+      tempImage=QImage(ed.renderImage(0,0)->copy());
     }
-  image=tempImage.convertToFormat(QImage::Format_ARGB32_Premultiplied);
-  imageFileName=filename;
-  QFileInfo fi(filename);
-  if (fi.suffix().toLower()=="gif")
+    else if(jp2.check(filename))
     {
-      //we will try a animated gif
-      qm.setFileName(filename);
-      if(qm.isValid())
-        {
-          if(qm.frameCount()>1)
-            {
-              activeMovie=true;
-              setMovie(&qm);
-              qm.start();
-            }
-        }
+      tempImage=jp2.decode(filename);
+      if(!tempImage.isNull())
+      {
+        success=true;
+      }
     }
+  }
+
+  if(!success)
+  {
+    if(showMessage)
+    {
+      stmb= new displayMBoxEvent("Image Loader",QString("Unable to load image:\n%1").arg(filename));
+      QApplication::postEvent( dispatcherPtr, stmb );  // Qt will delete it when done
+    }
+    validImage=false;
+    imageFileName="";
+    return false;
+  }
+
+  if(fromCache)
+  {
+    sourceImage=QImage();
+
+    if(!cacheHit)
+    {
+      orgWidth=tempImage.width();
+      orgHeight=tempImage.height();
+      tempImage=tempImage.scaledToWidth(120, Qt::FastTransformation);
+      // save cacheImage for next time
+      tempImage.setText("orgWidth",QString::number(orgWidth));
+      tempImage.setText("orgHeight",QString::number(orgHeight));
+      tempImage.save(cacheFileName,"PNG");
+    }
+    displayedImage=tempImage;
+  }
   else
+  {
+    orgWidth=tempImage.width();
+    orgHeight=tempImage.height();
+    displayedImage=tempImage;
+    sourceImage=tempImage;
+  }
+
+  imageFileName=filename;
+
+  QFileInfo finfo(filename);
+  if (finfo.suffix().toLower()=="gif")
+  {
+    //we will try a animated gif
+    qm.setFileName(filename);
+    if(qm.isValid())
     {
-      displayImage(false);
+      if(qm.frameCount()>1)
+      {
+        activeMovie=true;
+        setMovie(&qm);
+        qm.start();
+        displayedImage=QImage();
+      }
+      else
+      {
+        displayImage();  // we have a single image gif
+      }
     }
+  }
+  else
+  {
+    displayImage();
+  }
   validImage=true;
   if (emitSignal) emit imageChanged();
   return true;
 }
 
-bool imageViewer::openImage(QString &filename,bool showMessage,bool emitSignal)
+bool imageViewer::openImage(QString &filename,bool showMessage,bool emitSignal,bool fromCache)
 {
-  return openImage(filename,"",false,showMessage,emitSignal);
+  return openImage(filename,"",false,showMessage,emitSignal,fromCache);
 }
 
 bool imageViewer::openImage(QImage im)
 {
-  image=im;
-  if(!image.isNull())
-    {
-      displayImage(false);
-      validImage=true;
-      return true;
-    }
+  imageFileName="";
+  if(!im.isNull())
+  {
+    validImage=true;
+    sourceImage=im;
+    displayedImage=im;
+    displayImage();
+    return true;
+  }
   validImage=false;
-
   return false;
 }
 
@@ -212,144 +255,170 @@ bool imageViewer::openImage(QByteArray *ba)
   QBuffer buffer(ba);
   buffer.open(QIODevice::ReadOnly);
   if(tempImage.load(&buffer,NULL))
-    {
-      imageFileName="";
-      validImage=true;
-      image=tempImage.convertToFormat(QImage::Format_ARGB32_Premultiplied);
-      displayImage(false);
-      return true;
-    }
+  {
+    return  openImage(tempImage.convertToFormat(QImage::Format_ARGB32_Premultiplied));
+  }
   validImage=false;
   return false;
 }
 
-
+void imageViewer::clear()
+{
+  validImage=false;
+  imageFileName.clear();
+  sourceImage=QImage();
+  displayedImage=QImage();
+  setPixmap(QPixmap());
+  targetWidth=0;
+  targetHeight=0;
+  templateFileName.clear();
+  useTemplate=false;
+}
 
 bool imageViewer::hasValidImage()
 {
   return validImage;
 }
 
-QImage *imageViewer::createImage(QSize sz,QColor fill)
+void imageViewer::createImage(QSize sz,QColor fill,bool scale)
 {
-  image=QImage(sz,QImage::Format_ARGB32_Premultiplied);
-  image.fill(fill.rgb());
-  displayImage(false);
+  clear();
+  displayedImage=QImage(sz,QImage::Format_ARGB32_Premultiplied);
+  if(!displayedImage.isNull())
+  {
+    displayedImage.fill(fill.rgb());
+    useCompression=false;
+  }
+  stretch=scale;
+  displayImage();
   emit imageChanged();
-  return ℑ
 }
 
 void imageViewer::copy(imageViewer *src)
 {
   imageFileName=src->imageFileName;
   ttype=src->ttype;
-  openImage(imageFileName,false,false);
+  openImage(imageFileName,false,false,false);
 }
 
 
 
 QRgb *imageViewer::getScanLineAddress(int line)
 {
-  return (QRgb *)image.scanLine(line);
+  return (QRgb *)displayedImage.scanLine(line);
 }
 
 
 
-
-void imageViewer::displayImage(bool useCompression)
+void imageViewer::displayImage()
 {
-  QTemporaryFile itmp(QDir::tempPath()+"/qsstvXXXXXX.jp2");
-  if((image.width()==0) || (image.height()==0)) return;
-
-  //  qDebug()<< "displayImage" << image.width() << image.height() << width() << height();
-  if(ttype==TXIMG)
-    {
-      // we want to display the image with the defined quality
-      QBuffer buffer;
-      if(useCompression)
-        {
-          if(!itmp.open()) return;
-          writeJP2Image(image.convertToFormat(QImage::Format_RGB32), itmp.fileName(),psizeRatio);
-          compressedImage=readJP2Image(itmp.fileName());
-        }
-      else
-        {
-          compressedImage=image.copy();
-        }
-
-
-
-      if(compressedImage.isNull()||width()==0 || height()==0)
-        {
-
-          return;
-        }
-
-      if(hasScaledContents())
-        {
-          setPixmap(QPixmap::fromImage(compressedImage));
-        }
-      else
-        {
-//         qDebug() << "WxH" << width() << height() << compressedImage.width() << compressedImage.height();
-          setPixmap(QPixmap::fromImage(compressedImage.scaled(width(),height(),Qt::KeepAspectRatio,Qt::SmoothTransformation)));
-        }
-
-    }
+  if(displayedImage.isNull())
+  {
+    return;
+  }
+  if(hasScaledContents() || (displayedImage.width()>width()) || (displayedImage.height()>height()) || stretch)
+  {
+    setPixmap(QPixmap::fromImage(displayedImage.scaled(width()-2,height()-2,Qt::KeepAspectRatio,Qt::SmoothTransformation)));
+
+  }
   else
-    {
-      if(hasScaledContents())
-        {
-          setPixmap(QPixmap::fromImage(image));
-        }
-      else
-        {
-//          qDebug() << "WxH" << width() << height() << image.width() << image.height();
-          setPixmap(QPixmap::fromImage(image.scaled(width()-2,height()-2,Qt::KeepAspectRatio,Qt::SmoothTransformation)));
-        }
-    }
+  {
+    setPixmap(QPixmap::fromImage(displayedImage));
+  }
 
 }
 
 
-bool imageViewer::readThumbSettings(QSettings *qs)
-{
-  qs->beginGroup("Thumbnails");
-  addToLog(QString("/THUMB/"+objectName()+"/"),LOGIMAG);
-  imageFileName =qs->value(objectName()+"/filename","").toString();
-  qs->endGroup();
-  return openImage(imageFileName,false,false);
-}
-
-void imageViewer::writeThumbSettings(QSettings *qs)
-{
-  qs->beginGroup("Thumbnails");
-  qs->setValue(objectName()+"/filename",imageFileName);
-  qs->endGroup();
-}
 
 void imageViewer::setType(thumbType tp)
 {
   ttype=tp;
+  switch(ttype)
+  {
+  case RXIMG:
+  case PREVIEW:
+  case RXSSTVTHUMB:
+    imageFilePath=rxSSTVImagesPath;
+    break;
+  case RXDRMTHUMB:
+    imageFilePath=rxDRMImagesPath;
+    break;
+
+  case TXSSTVTHUMB:
+    imageFilePath=txSSTVImagesPath;
+    break;
+  case TXDRMTHUMB:
+    imageFilePath=txDRMImagesPath;
+    break;
+  case TXIMG:
+  case TXSTOCKTHUMB:
+    imageFilePath=txStockImagesPath;
+    break;
+  case TEMPLATETHUMB:
+    imageFilePath=templatesPath;
+    break;
+
+  }
+  if((tp==RXSSTVTHUMB) || (tp==RXDRMTHUMB) || (tp==TXSSTVTHUMB) || (tp==TXDRMTHUMB) ||(tp==TXSTOCKTHUMB) ||(tp==TEMPLATETHUMB))
+  {
+    setScaledContents(false);
+    setAlignment(Qt::AlignCenter);
+  }
+  popup->removeAction(newAct);
+  popup->removeAction(loadAct);
+  popup->removeAction(toTXAct);
+  popup->removeAction(editAct);
+  popup->removeAction(printAct);
+  popup->removeAction(deleteAct);
+  popup->removeAction(viewAct);
+  popup->removeAction(propertiesAct);
   switch(tp)
-    {
-    case RXIMG:
-    case RXTHUMB:
-      imageFilePath=rxImagesPath;
+  {
+  case RXIMG:
+    popup->addAction(viewAct);
+    popup->addAction(propertiesAct);
     break;
-    case TXIMG:
-    case TXTHUMB:
-      imageFilePath=txImagesPath;
+
+  case TXIMG:
+    popup->addAction(newAct);
+    popup->addAction(loadAct);
+    popup->addAction(editAct);
+    popup->addAction(printAct);
+    popup->addAction(viewAct);
+    popup->addAction(propertiesAct);
     break;
-    case TEMPLATETHUMB:
-      imageFilePath=templatesPath;
+
+  case PREVIEW:
+    popup->addAction(loadAct);
+    popup->addAction(toTXAct);
+    popup->addAction(viewAct);
+    popup->addAction(propertiesAct);
     break;
-    }
-  if((tp==RXTHUMB) || (tp==TXTHUMB) || (tp==TEMPLATETHUMB))
-    {
-      setScaledContents(true);
-      setAlignment(Qt::AlignCenter);
-    }
+
+  case RXSSTVTHUMB:
+  case RXDRMTHUMB:
+  case TXSSTVTHUMB:
+  case TXDRMTHUMB:
+    popup->addAction(printAct);
+    popup->addAction(deleteAct);
+    popup->addAction(viewAct);
+    popup->addAction(propertiesAct);
+    break;
+
+  case TXSTOCKTHUMB:
+  case TEMPLATETHUMB:
+    popup->addAction(newAct);
+    popup->addAction(loadAct);
+    popup->addAction(toTXAct);
+    popup->addAction(editAct);
+    popup->addAction(printAct);
+    popup->addAction(deleteAct);
+    popup->addAction(viewAct);
+    popup->addAction(propertiesAct);
+    break;
+  }
+  popupEnabled=true;
+
 }
 
 void imageViewer::mousePressEvent( QMouseEvent *e )
@@ -357,21 +426,21 @@ void imageViewer::mousePressEvent( QMouseEvent *e )
   QString temp;
   QString fn;
   if (e->button() == Qt::RightButton)
+  {
+    if(popupEnabled)
     {
-      if(popupEnabled)
-        {
-          popup->popup(QCursor::pos());
-        }
+      popup->popup(QCursor::pos());
     }
+  }
 }
 
 void imageViewer::slotDelete()
 {
   if(imageFileName.isEmpty()) return;
   if(QMessageBox::question(this,"Delete file","Do you want to delete the file and\n move it to the trash folder?",QMessageBox::Yes|QMessageBox::No)==QMessageBox::Yes)
-    {
-      trash(imageFileName,true);
-    }
+  {
+    trash(imageFileName,true);
+  }
   imageFileName="";
   emit layoutChanged();
 }
@@ -379,10 +448,10 @@ void imageViewer::slotDelete()
 void imageViewer::slotEdit()
 {
   if(imageFileName.isEmpty())
-    {
-      slotLoad();
-      if (imageFileName.isEmpty()) return;
-    }
+  {
+    slotLoad();
+    if (imageFileName.isEmpty()) return;
+  }
   callEditorEvent *ce = new callEditorEvent( this,imageFileName );
   QApplication::postEvent(dispatcherPtr, ce );  // Qt will delete it when done
 }
@@ -393,15 +462,20 @@ void imageViewer::slotLoad()
   QString fileNameTmp;
   dirDialog dd((QWidget *)this,"Browse");
   fileNameTmp=dd.openFileName(imageFilePath);
-  if(openImage(fileNameTmp,true,true))
+  if(openImage(fileNameTmp,true,false,false))
+  {
+    imageFileName=fileNameTmp;
+    if(ttype==TEMPLATETHUMB)
     {
-      imageFileName=fileNameTmp;
-      if(ttype==TEMPLATETHUMB)
-        {
-          templatesChangedEvent *ce = new templatesChangedEvent( );
-          QApplication::postEvent(dispatcherPtr, ce );  // Qt will delete it when done
-        }
+      templatesChangedEvent *ce = new templatesChangedEvent( );
+      QApplication::postEvent(dispatcherPtr, ce );  // Qt will delete it when done
     }
+    else if((ttype==TXIMG) ||(ttype==PREVIEW))
+    {
+      emit imageChanged();
+    }
+
+  }
 }
 
 
@@ -417,92 +491,152 @@ void imageViewer::slotPrint()
 {
 }
 
+
+void imageViewer::slotView()
+{
+  extViewer vm(this);
+  vm.setup(imageFileName);
+  vm.exec();
+}
+
+
+void imageViewer::slotBGColorChanged()
+{
+  QPalette mpalette;
+  mpalette.setColor(QPalette::Window,backGroundColor);
+  setBackgroundRole(QPalette::Window);
+  mpalette.setColor(QPalette::WindowText, Qt::yellow);
+  setPalette(mpalette);
+}
+
 void imageViewer::slotProperties()
 {
   QFileInfo fi(imageFileName);
   if(fi.exists())
-    {
-      QMessageBox::information(this,"Image Properties",
-                               "File: " + imageFileName
-                               + "\n File size:     " + QString::number(fi.size())
-                               + "\n Image width:   " + QString::number(image.width())
-                               + "\n Image heigth:  " + QString::number(image.height())
-                               + "\n Last Modified: " + fi.lastModified().toString()
-                               ,QMessageBox::Ok);
-    }
+  {
+    QMessageBox::information(this,"Image Properties",
+                             "File: " + imageFileName
+                             + "\n File size:     " + QString::number(fi.size())
+                             + "\n Image width:   " + QString::number(orgWidth)
+                             + "\n Image heigth:  " + QString::number(orgHeight)
+                             + "\n Last Modified: " + fi.lastModified().toString()
+                             ,QMessageBox::Ok);
+  }
   else
-    {
-      QMessageBox::information(this,"Image Properties",
-                               "No image loaded",QMessageBox::Ok);
-    }
+  {
+    QMessageBox::information(this,"Image Properties",
+                             " Image width:   " + QString::number(orgWidth)
+                             + "\n Image heigth:  " + QString::number(orgHeight)
+                             ,QMessageBox::Ok);
+  }
 
 }
 
 void imageViewer::slotToTX()
 {
-  txWidgetPtr->setImage(imageFileName);
+  moveToTxEvent *mt=0;
+  mt=new moveToTxEvent(imageFileName);
+  QApplication::postEvent(dispatcherPtr, mt); // Qt will delete it when done
 }
 
 
-void imageViewer::save(QString fileName,QString fmt,bool convertRGB)
+void imageViewer::save(QString fileName,QString fmt,bool convertRGB, bool source)
 {
   QImage im;
-  if(image.isNull()) return;
+  if(source)
+  {
+    if(sourceImage.isNull()) return;
+  }
+  else
+  {
+    if(displayedImage.isNull()) return;
+  }
   if(!convertRGB)
-    {
-      image.save(fileName,fmt.toUpper().toLatin1().data());
-    }
+  {
+    if(source) im=sourceImage;
+    else im=displayedImage;
+  }
   else
-    {
-      im=image.convertToFormat(QImage::Format_RGB32);
-      im.save(fileName,fmt.toUpper().toLatin1().data());
-    }
+  {
+    if(source) im=sourceImage.convertToFormat(QImage::Format_RGB32);
+    else im=displayedImage.convertToFormat(QImage::Format_RGB32);;
+  }
+  im.save(fileName,fmt.toUpper().toLatin1().data());
 }
 
-void imageViewer::copyToBuffer(QByteArray *ba)
+bool imageViewer::copyToBuffer(QByteArray *ba)
 {
-  QTemporaryFile itmp(QDir::tempPath()+"/qsstvXXXXXX.jp2");
-  if(image.isNull()) return;
-  if(!itmp.open()) return;
-  writeJP2Image(image.convertToFormat(QImage::Format_RGB32), itmp.fileName(),psizeRatio);
-  *ba=itmp.readAll();
-}
-
-int imageViewer::calcSize(int &sizeRatio)
-{
-  if(sizeRatio>100) sizeRatio=100;
-  if(sizeRatio<1) sizeRatio=1;
-  return (int)(rint(((double)image.byteCount()*sizeRatio))/(RATIOSCALE*1000.));
+  QImage im;
+  jp2IO jp2;
+  int fileSize;
+  if(displayedImage.isNull())
+  {
+    return false;
+  }
+  *ba=jp2.encode(displayedImage.convertToFormat(QImage::Format_RGB32),im,fileSize,compressionRatio);
+  if(fileSize==0)
+  {
+    return false;
+  }
+  return true;
 }
 
 
-void imageViewer:: setSizeRatio(int sizeRatio)
+uint  imageViewer:: setSizeRatio(int sizeRatio,bool usesCompression)
 {
-  format="jp2";
-  if(sizeRatio>100) sizeRatio=100;
-  if(sizeRatio<1) sizeRatio=1;
-  psizeRatio=sizeRatio/RATIOSCALE;
+  if(!usesCompression) return sourceImage.byteCount();
+  compressionRatio=sizeRatio;
+  return applyTemplate();
 }
 
 bool imageViewer::reload()
 {
-  return openImage(imageFileName ,true,false);
+  return openImage(imageFileName ,true,false,false);
 }
 
 
-void imageViewer::scale( int w, int h)
+void imageViewer::setParam(QString templateFn,bool usesTemplate,int width,int height)
 {
-  image=image.scaled(QSize(w,h),Qt::IgnoreAspectRatio,Qt::SmoothTransformation);
+  targetWidth=width;
+  targetHeight=height;
+  templateFileName=templateFn;
+  useTemplate=usesTemplate;
+  applyTemplate();
+  displayImage();
 }
 
-void imageViewer::applyTemplate(QString templateName, bool useTemplate,int w,int h)
+
+int imageViewer::applyTemplate()
 {
-  if(!reload()) return ;
-  addToLog("apply temlate",LOGIMAG);
-  //  sconvert cnv;
+  QImage *resultImage;
+  jp2IO jp2;
+  QImage overlayedImage;
+  if(sourceImage.isNull()) return 0;
+  QFile fi(templateFileName);
+  if(ttype!=TXIMG) return 0;
   editorScene tscene(0);
-  QFile fi(templateName);
-  if((!fi.fileName().isEmpty())  && (useTemplate))
+  resultImage=&sourceImage;
+  if(transmissionModeIndex==TRXDRM) useCompression=true;
+  else useCompression=false;
+  if((fi.fileName().isEmpty())  || (!useTemplate))
+  {
+    if(targetWidth!=0 && targetHeight!=0)
+    {
+      displayedImage= QImage(sourceImage.scaled(targetWidth,targetHeight,Qt::IgnoreAspectRatio,Qt::SmoothTransformation)); // same resolution as sstv mode
+
+    }
+    else
+    {
+      displayedImage=sourceImage;
+    }
+    resultImage=&displayedImage;
+  }
+  else
+  {
+    addToLog("apply temlate",LOGIMAG);
+    //  sconvert cnv;
+
+    if((!fi.fileName().isEmpty())  && (useTemplate))
     {
       tscene.load(fi);
       tscene.addConversion('c',toCall,true);
@@ -520,30 +654,36 @@ void imageViewer::applyTemplate(QString templateName, bool useTemplate,int w,int
       tscene.addConversion('y',comment2);
       tscene.addConversion('z',comment3);
       addToLog(QString("applyTemplate size=%1,%2").arg(tscene.width()).arg(tscene.height()),LOGIMAG);
-      if(w!=0 && h!=0)
-        {
-          overlayedImage= QImage(image.scaled(w,h));
-          tscene.overlay(&overlayedImage);
-        }
+      if(targetWidth!=0 && targetHeight!=0)
+      {
+        overlayedImage= QImage(sourceImage.scaled(targetWidth,targetHeight));
+        tscene.overlay(&overlayedImage);
+      }
       else
-        {
-          tscene.overlay(&image);
-        }
-      openImage(*tscene.getImagePtr());
+      {
+        tscene.overlay(&sourceImage);
+      }
+      resultImage=tscene.getImagePtr();
     }
+  }
+  if(useCompression)
+  {
+    int fileSize;
+    jp2.encode(resultImage->convertToFormat(QImage::Format_RGB32),compressedImage,fileSize,compressionRatio);
+    displayedImage=compressedImage;
+    return fileSize;
+  }
   else
-    {
-      if(w!=0 && h!=0)
-        {
-          overlayedImage= QImage(image.scaled(w,h,Qt::IgnoreAspectRatio,Qt::SmoothTransformation)); // same resolution as sstv mode
-          openImage(overlayedImage);
-        }
-      else openImage(image);
-    }
-  overlayedImage=QImage();
+  {
+    displayedImage=*resultImage;
+    return displayedImage.byteCount();
+  }
 }
 
 
-
+void imageViewer::resizeEvent(QResizeEvent *)
+{
+  displayImage();
+}
 
 
diff --git a/qsstv/widgets/imageviewer.h b/qsstv/widgets/imageviewer.h
index 761b0f0..4c44e12 100644
--- a/qsstv/widgets/imageviewer.h
+++ b/qsstv/widgets/imageviewer.h
@@ -41,35 +41,42 @@ public:
     {
     RXIMG, /*!< just for receiver */
     TXIMG, /*!< just for transmitter */
-    RXTHUMB, /*!< thumbnail for receiver. */
-    TXTHUMB,/*!< thumbnail for transmitter. */
-    TEMPLATETHUMB /*!< thumbnail for template. */
+    RXSSTVTHUMB, /*!< thumbnail for receiver. */
+    RXDRMTHUMB, /*!< thumbnail for receiver. */
+    TXSSTVTHUMB,/*!< thumbnail for transmitter. */
+    TXDRMTHUMB,/*!< thumbnail for transmitter. */
+    TXSTOCKTHUMB,/*!< thumbnail for transmitter. */
+    TEMPLATETHUMB, /*!< thumbnail for template. */
+    PREVIEW /*!< preview tx. */
     };
   imageViewer(QWidget *parent=0);
   ~imageViewer();
+
+
   void init(thumbType tp);
-  bool openImage(QString &filename, QString start, bool ask, bool showMessage, bool emitSignal);
-  bool openImage(QString &filename, bool showMessage, bool emitSignal);
+  bool openImage(QString &filename, QString start, bool ask, bool showMessage, bool emitSignal,bool fromCache);
+  bool openImage(QString &filename, bool showMessage, bool emitSignal, bool fromCache);
   bool openImage(QImage im);
   bool openImage(QByteArray *ba);
+  void setParam(QString templateFn,bool usesTemplate,int width=0,int height=0);
+  void clear();
   bool reload();
-  void scale( int w, int h);
-  QImage * getImagePtr() {return ℑ}
+
+
+//  void scale( int w, int h);
+  QImage * getImagePtr() {return &sourceImage;}
   bool hasValidImage();
-  QImage *createImage(QSize sz,QColor fill);
+  void createImage(QSize sz, QColor fill, bool scale);
   QRgb *getScanLineAddress(int line);
   void copy(imageViewer *src);
-
-  bool readThumbSettings(QSettings *qs);
-  void writeThumbSettings(QSettings *qs);
   void setType(thumbType t);
   QString getFilename() {return imageFileName;}
   void enablePopup(bool en) {popupEnabled=en;}
-  void displayImage(bool useCompression);
-  void save(QString fileName, QString fmt, bool convertRGB);
-  void copyToBuffer(QByteArray *ba);
-  int calcSize(int &sizeRatio);
-  void setSizeRatio(int sizeRatio);
+  void displayImage();
+  void save(QString fileName, QString fmt, bool convertRGB, bool source);
+  bool copyToBuffer(QByteArray *ba);
+//  int calcSize(int &sizeRatio);
+  uint setSizeRatio(int sizeRatio,bool usesCompression);
   int getFileSize(){return fileSize;}
   QString toCall;
   QString toOperator;
@@ -77,20 +84,36 @@ public:
   QString comment1;
   QString comment2;
   QString comment3;
+  bool stretch;
+  void getOrgSize(int &w,int &h) {w=orgWidth; h=orgHeight;}
+
+
+  int applyTemplate();
 
 
+protected:
+  void resizeEvent(QResizeEvent *);
 
-  void applyTemplate(QString templateName, bool useTemplate, int w=0, int h=0);
 
-  //  QSize sizeHint () {return QSize(32,26);}
+private slots:
+  void slotDelete();
+  void slotEdit();
+  void slotLoad();
+  void slotNew();
+  void slotPrint();
+  void slotProperties();
+  void slotToTX();
+  void slotView();
+  void slotBGColorChanged();
+
 
 signals:
   void layoutChanged();
   void imageChanged();
 
 private:
-  QImage image;
-  QImage overlayedImage;
+  QImage displayedImage;
+  QImage sourceImage;
   QImage compressedImage;
 
   void mousePressEvent( QMouseEvent *e );
@@ -107,27 +130,23 @@ private:
   QAction *editAct;
   QAction *printAct;
   QAction *deleteAct;
+  QAction *viewAct;
   QAction *propertiesAct;
 
-  double psizeRatio;
+//  double psizeRatio;
+  int compressionRatio; // 0=lossless 99 is max compression
   int fileSize;
   QString format;
   QMovie qm;
   bool activeMovie;
+  bool useCompression;
+  QString templateFileName;
+  bool useTemplate;
+  int targetWidth;
+  int targetHeight;
+  int orgWidth;
+  int orgHeight;
 
-
-  // for overlays
-
-
-
-private slots:
-  void slotDelete();
-  void slotEdit();
-  void slotLoad();
-  void slotNew();
-  void slotPrint();
-  void slotProperties();
-  void slotToTX();
 };
 
 #endif
diff --git a/qsstv/widgets/qscale.cpp b/qsstv/widgets/qscale.cpp
deleted file mode 100644
index 7897e3b..0000000
--- a/qsstv/widgets/qscale.cpp
+++ /dev/null
@@ -1,371 +0,0 @@
-/*
- *   Copyright 2008-2012 Meinert Jordan <meinert at gmx.at>
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU Library General Public License as
- *   published by the Free Software Foundation; either version 2, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details
- *
- *   You should have received a copy of the GNU Library 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.
- */
-
-#include "qscale.h"
-#include <QtGui/QPainter>
-#include <cmath>
-
-QScale::QScale(QWidget *parent)
-    : QWidget(parent)
-{
-    m_minimum = 0;
-    m_maximum = 100;
-
-    m_value = 0;
-
-    m_labelsVisible = true;
-    m_scaleVisible = true;
-
-    m_borderWidth = 6;
-
-    m_labelsFormat = 'g';
-    m_labelsPrecision = -1;
-
-    m_majorStepSize = 0;
-    m_minorStepCount = -1;
-
-    m_invertedAppearance = false;
-
-    m_orientations = (Qt::Horizontal | Qt::Vertical);
-
-    pi = acos(-1);
-
-    setBackgroundRole(QPalette::Base);
-
-    updateLabelSample();
-    setMinimumSize(80,60);
-    setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
-}
-
-QScale::~QScale()
-{
-
-}
-
-void QScale::setMinimum(double min)
-{
-    if(min < INFINITY && min > -INFINITY)
-        m_minimum = min;
-    updateLabelSample();
-    update();
-}
-
-double QScale::minimum() const
-{
-    return m_minimum;
-}
-
-void QScale::setMaximum(double max)
-{
-    if(max < INFINITY && max > -INFINITY)
-        m_maximum = max;
-    updateLabelSample();
-    update();
-}
-
-double QScale::maximum() const
-{
-   return m_maximum;
-}
-
-void QScale::setRange(double min, double max)
-{
-    if(max < INFINITY && max > -INFINITY)
-        m_maximum = max;
-    if(min < INFINITY && min > -INFINITY)
-        m_minimum = min;
-    updateLabelSample();
-    update();
-}
-
-void QScale::setValue(double value)
-{
-   m_value = value;
-   update();
-}
-
-double QScale::value() const
-{
-   return m_value;
-}
-
-void QScale::setLabelsVisible(bool visible)
-{
-    m_labelsVisible = visible;
-    update();
-}
-
-bool QScale::isLabelsVisible() const
-{
-    return m_labelsVisible;
-}
-
-void QScale::setScaleVisible(bool visible)
-{
-    m_scaleVisible = visible;
-    update();
-}
-
-bool QScale::isScaleVisible() const
-{
-    return m_scaleVisible;
-}
-
-void QScale::setBorderWidth(int width)
-{
-    m_borderWidth = qMin(width, 0);
-    update();
-}
-
-int QScale::borderWidth() const
-{
-    return m_borderWidth;
-}
-
-void QScale::setLabelsFormat(char format, int precision)
-{
-    m_labelsFormat = format;
-    m_labelsPrecision = precision;
-    updateLabelSample();
-    update();
-}
-
-void QScale::setMajorStepSize(double stepSize)
-{
-    m_majorStepSize = stepSize;
-    update();
-}
-
-double QScale::majorStepSize() const
-{
-    return m_majorStepSize;
-}
-
-void QScale::setMinorStepCount(int stepCount)
-{
-    m_minorStepCount = stepCount;
-    update();
-}
-
-int QScale::minorStepCount() const
-{
-    return m_minorStepCount;
-}
-
-void QScale::setInvertedAppearance(bool invert)
-{
-    m_invertedAppearance = invert;
-    update();
-}
-
-bool QScale::invertedAppearance() const
-{
-    return m_invertedAppearance;
-}
-
-void QScale::setOrientations(Qt::Orientations orientations)
-{
-    m_orientations = orientations;
-    update();
-}
-
-Qt::Orientations QScale::orientations() const
-{
-    return m_orientations;
-}
-
-void QScale::resizeEvent(QResizeEvent *re)
-{
-    QWidget::resizeEvent(re);
-}
-
-void QScale::paintEvent(QPaintEvent*)
-{
-    painter = new QPainter(this);
-
-    bool vertical;
-    int wWidget, hWidget;
-    double wLabel, hLabel;
-    double wScale, hScale;
-    double radius;
-    double angleSpan;
-    double angleStart;
-    double valueSpan;
-    double majorStep;
-    int minorSteps;
-    int order;
-    QRectF boundingRect;
-    QPointF center;
-    QPolygon polygon;
-
-    double u;
-
-    if(!(m_orientations & Qt::Vertical) ^ !(m_orientations & Qt::Horizontal))
-        vertical = (bool)(m_orientations & Qt::Vertical);
-    else
-        vertical = (height() > width());
-
-    wWidget = width();
-    hWidget = height();
-
-    painter->setRenderHint(QPainter::Antialiasing, true);
-
-    boundingRect = painter->boundingRect(QRectF(0, 0, width(), height()),
-                               Qt::AlignBottom | Qt::AlignHCenter, labelSample);
-    wLabel = (m_labelsVisible)? boundingRect.width() : 0;
-    hLabel = (m_labelsVisible)? boundingRect.height() : 0;
-
-    if(vertical){
-        qSwap(wWidget, hWidget);
-        qSwap(wLabel, hLabel);
-    }
-
-    wScale = wWidget - wLabel - 2. * m_borderWidth;
-    hScale = .5 * hWidget - hLabel - m_borderWidth;
-
-    radius = .125 * pow( wScale, 2) / hScale + .5 * hScale;
-    if(radius < hScale + .5* hWidget - m_borderWidth){
-        radius = (4. * (hLabel + m_borderWidth) +
-                  sqrt(4. * pow(hLabel + m_borderWidth, 2) +
-                       3. * pow(wScale, 2))
-                  ) / 3. - hLabel - 2. * m_borderWidth;
-        center = QPointF(.5 * wWidget, hWidget - m_borderWidth);
-    }
-    else
-        center = QPointF(.5 * wWidget, radius + hLabel + m_borderWidth);
-
-    angleSpan = - 360 / pi * asin(wScale/(2. * radius));
-    angleStart = 90. - .5 * angleSpan;
-
-    valueSpan = m_maximum - m_minimum;
-    majorStep = fabs(valueSpan) * qMax(wLabel, 1.5 * boundingRect.height()) /
-                                                                         wScale;
-    order = 0;
-    while(majorStep < 1)
-        majorStep *= 10, order--;
-    while(majorStep >= 10)
-        majorStep /= 10, order++;
-    if(majorStep > 5)
-        majorStep = 10 * pow(10, order), minorSteps = 5;
-    else if(majorStep > 2)
-        majorStep = 5 * pow(10, order), minorSteps = 5;
-    else
-        majorStep = 2 * pow(10, order), minorSteps = 4;
-    if(m_majorStepSize > 0)
-        majorStep = m_majorStepSize;
-    if(m_minorStepCount > 0)
-        minorSteps = m_minorStepCount;
-
-    // draw scale
-    painter->setPen(QPen(palette().color(QPalette::Text), 1));
-    if(m_scaleVisible && majorStep != 0){
-        if(vertical){
-            painter->rotate(90);
-            painter->translate(0, -hWidget + wLabel / 4);
-        }
-        painter->translate(center);
-        painter->rotate(fmod(m_minimum, majorStep / minorSteps) /
-                        valueSpan * angleSpan - angleStart);
-        int offsetCount = (minorSteps - (int)ceil(fmod(m_minimum, majorStep) /
-                                          majorStep * minorSteps)) % minorSteps;
-        double scaleWidth = qMin(qMin(.25 * (hWidget - m_borderWidth),
-                                    .25 * radius), 2.5 * boundingRect.height());
-        for(int i = 0; i <= (int)(minorSteps * valueSpan / majorStep); i++){
-            if(i % minorSteps == offsetCount)
-                painter->drawLine(QLineF(radius - scaleWidth, 0, radius, 0));
-            else
-                painter->drawLine(QLineF(radius - scaleWidth, 0,
-                                         radius - scaleWidth * 0.4, 0));
-            painter->rotate(majorStep * angleSpan / (-valueSpan * minorSteps));
-        }
-        painter->resetMatrix();
-    }
-
-    // draw labels
-    if(m_labelsVisible && majorStep != 0)
-        for(int i = (int)ceil(m_minimum / majorStep);
-            i <= (int)(m_maximum / majorStep); i++){
-            u = pi/180 * ((majorStep * i - m_minimum) / valueSpan *
-                                     angleSpan + angleStart);
-            QRect position;
-            Qt::Alignment align;
-            if(vertical){
-                align = Qt::AlignLeft | Qt::AlignVCenter;
-                position = QRect(width() - center.y() + radius * sin(u), 0,
-                                   width(), height() + 2 * radius * cos(u));
-            }
-            else{
-                align = Qt::AlignHCenter | Qt::AlignBottom;
-                position = QRect(0, 0, 2. * (center.x() + radius * cos(u)),
-                                              center.y() - radius * sin(u));
-            }
-            painter->resetMatrix();
-            painter->drawText(position, align, QString::number(i * majorStep,
-                                            m_labelsFormat, m_labelsPrecision));
-       }
-
-    // draw needle
-    if(vertical){
-        painter->rotate(90);
-        painter->translate(0, -hWidget + wLabel / 4);
-    }
-    painter->translate(center);
-    painter->rotate((m_minimum - m_value) / valueSpan * angleSpan - angleStart);
-    painter->setPen(Qt::NoPen);
-    painter->setBrush(palette().color(QPalette::Text));
-    polygon.setPoints(5, 0, -2, (int)radius - 10, -2, (int)radius, 0,
-                      (int)radius - 10, 2, 0, 2);
-    painter->drawConvexPolygon(polygon);
-    painter->setPen(QPen(palette().color(QPalette::Base), 2));
-    painter->drawLine(0, 0, radius - 15, 0);
-    painter->resetMatrix();
-
-    // draw cover
-    painter->setPen(Qt::NoPen);
-    painter->setBrush(palette().color(QPalette::Mid));
-
-    if(vertical){
-        painter->drawRect(QRect(0, 0, m_borderWidth, height()));
-        center = QPointF(width() - center.y() - wLabel / 4, .5 * height());
-        u = .25 * (hWidget - wLabel) - center.x() - m_borderWidth;
-    }
-    else{
-        painter->drawRect(QRect(0, hWidget, wWidget, -m_borderWidth));
-        u = center.y() - m_borderWidth - .75 * hWidget;
-    }
-    u = qMax(u, .25 * radius);
-    painter->drawEllipse(center, u, u);
-
-    delete painter;
-}
-
-void QScale::updateLabelSample()
-{
-    double margin = qMax(fabs(m_minimum), fabs(m_maximum));
-    double wildcard = (qMin(m_minimum, m_maximum) < 0)? -8 : 8;
-    while(margin < 1){
-        margin *= 10;
-        wildcard /= 10;
-    }
-    while(margin >= 10){
-        margin /= 10;
-        wildcard *= 10;
-    }
-    labelSample = QString::number(wildcard, m_labelsFormat, m_labelsPrecision);
-}
diff --git a/qsstv/widgets/qscale.h b/qsstv/widgets/qscale.h
deleted file mode 100644
index 330dd94..0000000
--- a/qsstv/widgets/qscale.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- *   Copyright 2008-2012 Meinert Jordan <meinert at gmx.at>
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU Library General Public License as
- *   published by the Free Software Foundation; either version 2, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details
- *
- *   You should have received a copy of the GNU Library 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.
- */
-
-#ifndef QSCALE_H
-#define QSCALE_H
-#include "qglobal.h"
-
-#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
-#include <QtWidgets>
-#else
-#include <QWidget>
-#endif
-
-class QScale : public QWidget
-{
-    Q_OBJECT
-
-public:
-    QScale(QWidget *parent = 0);
-    ~QScale();
-
-    double minimum() const;
-    double maximum() const;
-
-    double value() const;
-
-    void setLabelsVisible(bool);
-    bool isLabelsVisible() const;
-
-    void setScaleVisible(bool);
-    bool isScaleVisible() const;
-
-    void setBorderWidth(int);
-    int borderWidth() const;
-
-    void setLabelsFormat(char format, int precision = -1);
-
-    double majorStepSize() const;
-    int minorStepCount() const;
-
-    void setInvertedAppearance(bool invert);
-    bool invertedAppearance() const;
-
-    Qt::Orientations orientations() const;
-
-//    QSize sizeHint() const;
-//    QSize minimumSizeHint() const;
-
-public Q_SLOTS:
-    void setMinimum(double);
-    void setMaximum(double);
-    void setRange(double min, double max);
-
-    void setValue(double);
-
-    void setMajorStepSize(double);
-    void setMinorStepCount(int);
-
-    void setOrientations(Qt::Orientations);
-
-protected:
-//    bool event(QEvent *e);
-    void resizeEvent(QResizeEvent *re);
-    void paintEvent(QPaintEvent *pe);
-
-private:
-    double m_minimum;
-    double m_maximum;
-
-    double m_value;
-
-    bool m_labelsVisible;
-    bool m_scaleVisible;
-
-    int m_borderWidth;
-
-    char m_labelsFormat;
-    int m_labelsPrecision;
-
-    double m_majorStepSize;
-    int m_minorStepCount;
-
-    bool m_invertedAppearance;
-
-    Qt::Orientations m_orientations;
-
-    QPainter *painter;
-    QString labelSample;
-
-    double pi;
-
-    void updateLabelSample();
-};
-
-#endif // QSCALE_H
diff --git a/qsstv/widgets/spectrumwidget.cpp b/qsstv/widgets/spectrumwidget.cpp
index 064dae2..516c1ef 100644
--- a/qsstv/widgets/spectrumwidget.cpp
+++ b/qsstv/widgets/spectrumwidget.cpp
@@ -1,18 +1,17 @@
 #include "spectrumwidget.h"
-#include "qsstvglobal.h"
+#include "appglobal.h"
 #include "ui_spectrumwidget.h"
 #include "utils/supportfunctions.h"
 #include "utils/logging.h"
 #include "markerwidget.h"
 
-spectrumWidget::spectrumWidget(QWidget *parent) :
-  QFrame(parent),
-  ui(new Ui::spectrumWidget)
+spectrumWidget::spectrumWidget(QWidget *parent) : QFrame(parent),  ui(new Ui::spectrumWidget)
 {
   ui->setupUi(this);
   readSettings();
   connect(ui->maxDbSpinbox,SIGNAL(valueChanged(int)),SLOT(slotMaxDbChanged(int)));
-  connect(ui->rangeSpinBox,SIGNAL(valueChanged(int)),SLOT(slotRangeChanged(int)));
+  connect(ui->rangeSpinbox,SIGNAL(valueChanged(int)),SLOT(slotRangeChanged(int)));
+  connect(ui->avgDoubleSpinBox,SIGNAL(valueChanged(double)),SLOT(slotAvgChanged(double)));
 }
 
 spectrumWidget::~spectrumWidget()
@@ -21,49 +20,30 @@ spectrumWidget::~spectrumWidget()
   delete ui;
 }
 
-void spectrumWidget::init(int size,int slices,int isamplingrate)
+void spectrumWidget::init(int length,int slices,int isamplingrate)
 {
-  addToLog(QString("Size: %1, Slices %2, Samplingrate %3").arg(size).arg(slices).arg(isamplingrate),LOGFFT);
-  ui->fftFrame->init(size,slices,isamplingrate);
-//  ui->fftFrame->setMarkerLabel(ui->markerLabel);
-//  ui->fftFrame->setSize(ui->fftFrame->width(),ui->fftFrame->height());
-}
-void spectrumWidget::realFFT(short int *iBuffer)
-{
-  ui->fftFrame->realFFT(iBuffer);
-}
-void spectrumWidget::realFFT(float *iBuffer)
-{
-  ui->fftFrame->realFFT(iBuffer);
+  addToLog(QString("Size: %1, Slices %2, Samplingrate %3").arg(length).arg(slices).arg(isamplingrate),LOGFFT); 
+  fftFunc.init(length,slices,isamplingrate);
+  ui->spectrWidget->init(length,slices,isamplingrate);
+  ui->waterfallWidget->init(length,slices,isamplingrate);
 }
 
+
 void spectrumWidget::realFFT(double *iBuffer)
 {
-  ui->fftFrame->realFFT(iBuffer);
+    fftFunc.realFFT(iBuffer);
+    ui->spectrWidget->showFFT(fftFunc.out);
+    ui->waterfallWidget->showFFT(fftFunc.out);
 }
 
 
-
-
-void spectrumWidget::slotMaxDbChanged(int mb)
-{
-  ui->fftFrame->setMaxDb(mb);
-  maxdb=mb;
-}
-void spectrumWidget::slotRangeChanged(int rg)
-{
-  ui->fftFrame->setRange(rg);
-  range=rg;
-}
-
 void spectrumWidget::readSettings()
 {
   QSettings qSettings;
   qSettings.beginGroup("SPECTRUM");
-  maxdb=qSettings.value("maxdb",0).toInt();
-  slotMaxDbChanged(maxdb);
+  maxdb=qSettings.value("maxdb",-25).toInt();
   range=qSettings.value("range",35).toInt();
-  slotRangeChanged(range);
+  avg=qSettings.value("avg",0.90).toDouble();
   qSettings.endGroup();
   setParams();
 }
@@ -76,36 +56,66 @@ void spectrumWidget::writeSettings()
   qSettings.beginGroup("SPECTRUM");
   qSettings.setValue( "maxdb",maxdb);
   qSettings.setValue( "range",range);
+  qSettings.setValue("avg",avg);
   qSettings.endGroup();
 }
 
 void spectrumWidget::getParams()
 {
   getValue(maxdb,ui->maxDbSpinbox);
-  getValue(range,ui->rangeSpinBox);
+  getValue(range,ui->rangeSpinbox);
+  getValue(avg,ui->avgDoubleSpinBox);
 }
 
 void spectrumWidget::setParams()
 {
   setValue(maxdb,ui->maxDbSpinbox);
-  setValue(range,ui->rangeSpinBox);
+  setValue(range,ui->rangeSpinbox);
+  setValue(avg,ui->avgDoubleSpinBox);
   slotMaxDbChanged(maxdb);
   slotRangeChanged(range);
+  slotAvgChanged(avg);
+
 }
 
-void spectrumWidget::displaySettings(bool wf, bool drm)
+void spectrumWidget::displaySettings(bool drm)
 {
-  ui->fftFrame->displayWaterfall(wf);
+  ui->spectrWidget->displayWaterfall(false);
+  ui->waterfallWidget->displayWaterfall(true);
   if(drm)
   {
-      ui->fftFrame->setMarkers(725,1475,1850);
-      ui->markerLabel->setMarkers(725,1475,1850);
+      ui->spectrWidget->setMarkers(725,1475,1850);
+      ui->waterfallWidget->setMarkers(725,1475,1850);
+      ui->markerLabelSpectrum->setMarkers(725,1475,1850);
+      ui->markerLabelWF->setMarkers(725,1475,1850);
+
     }
   else
     {
-      ui->fftFrame->setMarkers(1200,1500,2300);
-      ui->markerLabel->setMarkers(1200,1500,2300);
+      ui->spectrWidget->setMarkers(1200,1500,2300);
+      ui->waterfallWidget->setMarkers(1200,1500,2300);
+      ui->markerLabelSpectrum->setMarkers(1200,1500,2300);
+      ui->markerLabelWF->setMarkers(1200,1500,2300);
     }
 }
 
+void spectrumWidget::slotMaxDbChanged(int mb)
+{
+  ui->spectrWidget->setMaxDb(mb);
+  ui->waterfallWidget->setMaxDb(mb);
+  maxdb=mb;
+}
+void spectrumWidget::slotRangeChanged(int rg)
+{
+  ui->spectrWidget->setRange(rg);
+  ui->waterfallWidget->setRange(rg);
+  range=rg;
+}
+
+void spectrumWidget::slotAvgChanged(double d)
+{
+   ui->spectrWidget->setAvg(d);
+   ui->waterfallWidget->setAvg(d);
+}
+
 
diff --git a/qsstv/widgets/spectrumwidget.h b/qsstv/widgets/spectrumwidget.h
index ea18822..a3b3a93 100644
--- a/qsstv/widgets/spectrumwidget.h
+++ b/qsstv/widgets/spectrumwidget.h
@@ -2,6 +2,7 @@
 #define SPECTRUMWIDGET_H
 
 #include <QFrame>
+#include "fftcalc.h"
 
 namespace Ui {
   class spectrumWidget;
@@ -14,23 +15,27 @@ class spectrumWidget : public QFrame
 public:
   spectrumWidget(QWidget *parent = 0);
   ~spectrumWidget();
-  void init(int size,int slices,int isamplingrate);
-  void realFFT(short int *iBuffer);
-  void realFFT(float *iBuffer);
+  void init(int length, int slices, int isamplingrate);
+//  void realFFT(short int *iBuffer);
+//  void realFFT(float *iBuffer);
   void realFFT(double *iBuffer);
   void readSettings();
   void writeSettings();
-  void displaySettings(bool wf,bool drm);
+  void displaySettings(bool drm);
+  double getVolumeDb();
 private slots:
   void slotMaxDbChanged(int mb);
   void slotRangeChanged(int rg);
   void getParams();
   void setParams();
+  void slotAvgChanged(double);
   
 private:
   Ui::spectrumWidget *ui;
   int maxdb;
   int range;
+  double avg;
+  fftCalc fftFunc;
 };
 
 #endif // SPECTRUMWIDGET_H
diff --git a/qsstv/widgets/spectrumwidget.ui b/qsstv/widgets/spectrumwidget.ui
index 1be7e66..e9828d7 100644
--- a/qsstv/widgets/spectrumwidget.ui
+++ b/qsstv/widgets/spectrumwidget.ui
@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>334</width>
-    <height>219</height>
+    <width>515</width>
+    <height>696</height>
    </rect>
   </property>
   <property name="minimumSize">
@@ -36,15 +36,24 @@
   <property name="lineWidth">
    <number>2</number>
   </property>
-  <layout class="QVBoxLayout" name="verticalLayout" stretch="0,10,0">
+  <layout class="QVBoxLayout" name="verticalLayout" stretch="0,1,0,3,0">
    <property name="spacing">
     <number>0</number>
    </property>
-   <property name="margin">
+   <property name="leftMargin">
+    <number>0</number>
+   </property>
+   <property name="topMargin">
+    <number>0</number>
+   </property>
+   <property name="rightMargin">
+    <number>0</number>
+   </property>
+   <property name="bottomMargin">
     <number>0</number>
    </property>
    <item>
-    <widget class="markerWidget" name="markerLabel">
+    <widget class="markerWidget" name="markerLabelSpectrum">
      <property name="maximumSize">
       <size>
        <width>16777215</width>
@@ -57,7 +66,7 @@
     </widget>
    </item>
    <item>
-    <widget class="fftDisplay" name="fftFrame">
+    <widget class="fftDisplay" name="spectrWidget" native="true">
      <property name="palette">
       <palette>
        <active>
@@ -476,14 +485,21 @@
      <property name="autoFillBackground">
       <bool>true</bool>
      </property>
-     <property name="frameShape">
-      <enum>QFrame::NoFrame</enum>
+     <property name="lineWidth" stdset="0">
+      <number>1</number>
      </property>
-     <property name="frameShadow">
-      <enum>QFrame::Plain</enum>
+     <property name="text" stdset="0">
+      <string/>
      </property>
-     <property name="lineWidth">
-      <number>1</number>
+    </widget>
+   </item>
+   <item>
+    <widget class="markerWidget" name="markerLabelWF">
+     <property name="maximumSize">
+      <size>
+       <width>16777215</width>
+       <height>8</height>
+      </size>
      </property>
      <property name="text">
       <string/>
@@ -491,25 +507,437 @@
     </widget>
    </item>
    <item>
-    <layout class="QHBoxLayout" name="horizontalLayout">
-     <property name="spacing">
-      <number>4</number>
+    <widget class="fftDisplay" name="waterfallWidget" native="true">
+     <property name="palette">
+      <palette>
+       <active>
+        <colorrole role="WindowText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>255</red>
+           <green>255</green>
+           <blue>255</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Button">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>127</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Light">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>191</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Midlight">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>159</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Dark">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>63</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Mid">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>84</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Text">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>255</red>
+           <green>255</green>
+           <blue>255</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="BrightText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>255</red>
+           <green>255</green>
+           <blue>255</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="ButtonText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>255</red>
+           <green>255</green>
+           <blue>255</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Base">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>0</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Window">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>127</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Shadow">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>0</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="AlternateBase">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>63</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="ToolTipBase">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>255</red>
+           <green>255</green>
+           <blue>220</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="ToolTipText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>0</blue>
+          </color>
+         </brush>
+        </colorrole>
+       </active>
+       <inactive>
+        <colorrole role="WindowText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>255</red>
+           <green>255</green>
+           <blue>255</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Button">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>127</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Light">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>191</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Midlight">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>159</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Dark">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>63</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Mid">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>84</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Text">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>255</red>
+           <green>255</green>
+           <blue>255</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="BrightText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>255</red>
+           <green>255</green>
+           <blue>255</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="ButtonText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>255</red>
+           <green>255</green>
+           <blue>255</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Base">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>0</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Window">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>127</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Shadow">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>0</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="AlternateBase">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>63</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="ToolTipBase">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>255</red>
+           <green>255</green>
+           <blue>220</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="ToolTipText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>0</blue>
+          </color>
+         </brush>
+        </colorrole>
+       </inactive>
+       <disabled>
+        <colorrole role="WindowText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>63</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Button">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>127</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Light">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>191</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Midlight">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>159</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Dark">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>63</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Mid">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>84</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Text">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>63</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="BrightText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>255</red>
+           <green>255</green>
+           <blue>255</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="ButtonText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>63</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Base">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>127</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Window">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>127</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Shadow">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>0</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="AlternateBase">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>127</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="ToolTipBase">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>255</red>
+           <green>255</green>
+           <blue>220</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="ToolTipText">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>0</red>
+           <green>0</green>
+           <blue>0</blue>
+          </color>
+         </brush>
+        </colorrole>
+       </disabled>
+      </palette>
      </property>
-     <item>
-      <spacer name="horizontalSpacer">
-       <property name="orientation">
-        <enum>Qt::Horizontal</enum>
-       </property>
-       <property name="sizeHint" stdset="0">
-        <size>
-         <width>40</width>
-         <height>20</height>
-        </size>
-       </property>
-      </spacer>
-     </item>
-     <item>
-      <widget class="QLabel" name="label">
+     <property name="autoFillBackground">
+      <bool>true</bool>
+     </property>
+     <property name="lineWidth" stdset="0">
+      <number>1</number>
+     </property>
+     <property name="text" stdset="0">
+      <string/>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <layout class="QGridLayout" name="gridLayout">
+     <item row="0" column="0">
+      <widget class="QLabel" name="maxDbLabel">
        <property name="font">
         <font>
          <pointsize>10</pointsize>
@@ -521,9 +949,40 @@
        <property name="text">
         <string>Max dB</string>
        </property>
+       <property name="alignment">
+        <set>Qt::AlignCenter</set>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
       </widget>
      </item>
-     <item>
+     <item row="0" column="1">
+      <widget class="QLabel" name="rangeLabel">
+       <property name="font">
+        <font>
+         <pointsize>10</pointsize>
+        </font>
+       </property>
+       <property name="text">
+        <string>Range</string>
+       </property>
+       <property name="alignment">
+        <set>Qt::AlignCenter</set>
+       </property>
+      </widget>
+     </item>
+     <item row="0" column="2">
+      <widget class="QLabel" name="label_3">
+       <property name="text">
+        <string>Avg</string>
+       </property>
+       <property name="alignment">
+        <set>Qt::AlignCenter</set>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="0">
       <widget class="QSpinBox" name="maxDbSpinbox">
        <property name="sizePolicy">
         <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
@@ -534,39 +993,25 @@
        <property name="maximumSize">
         <size>
          <width>16777215</width>
-         <height>20</height>
+         <height>30</height>
         </size>
        </property>
-       <property name="font">
-        <font>
-         <pointsize>9</pointsize>
-        </font>
+       <property name="buttonSymbols">
+        <enum>QAbstractSpinBox::PlusMinus</enum>
        </property>
        <property name="minimum">
-        <number>-30</number>
+        <number>-40</number>
        </property>
        <property name="maximum">
-        <number>20</number>
+        <number>10</number>
        </property>
        <property name="value">
         <number>0</number>
        </property>
       </widget>
      </item>
-     <item>
-      <widget class="QLabel" name="label_2">
-       <property name="font">
-        <font>
-         <pointsize>10</pointsize>
-        </font>
-       </property>
-       <property name="text">
-        <string>Range</string>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <widget class="QSpinBox" name="rangeSpinBox">
+     <item row="1" column="1">
+      <widget class="QSpinBox" name="rangeSpinbox">
        <property name="sizePolicy">
         <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
          <horstretch>0</horstretch>
@@ -576,37 +1021,44 @@
        <property name="maximumSize">
         <size>
          <width>16777215</width>
-         <height>20</height>
+         <height>30</height>
         </size>
        </property>
-       <property name="font">
-        <font>
-         <pointsize>9</pointsize>
-        </font>
+       <property name="buttonSymbols">
+        <enum>QAbstractSpinBox::PlusMinus</enum>
        </property>
        <property name="minimum">
-        <number>25</number>
+        <number>10</number>
        </property>
        <property name="maximum">
-        <number>40</number>
+        <number>50</number>
        </property>
        <property name="value">
-        <number>30</number>
+        <number>10</number>
        </property>
       </widget>
      </item>
-     <item>
-      <spacer name="horizontalSpacer_2">
-       <property name="orientation">
-        <enum>Qt::Horizontal</enum>
-       </property>
-       <property name="sizeHint" stdset="0">
+     <item row="1" column="2">
+      <widget class="QDoubleSpinBox" name="avgDoubleSpinBox">
+       <property name="maximumSize">
         <size>
-         <width>40</width>
-         <height>20</height>
+         <width>16777215</width>
+         <height>30</height>
         </size>
        </property>
-      </spacer>
+       <property name="buttonSymbols">
+        <enum>QAbstractSpinBox::PlusMinus</enum>
+       </property>
+       <property name="minimum">
+        <double>0.010000000000000</double>
+       </property>
+       <property name="maximum">
+        <double>1.000000000000000</double>
+       </property>
+       <property name="singleStep">
+        <double>0.010000000000000</double>
+       </property>
+      </widget>
      </item>
     </layout>
    </item>
@@ -615,8 +1067,9 @@
  <customwidgets>
   <customwidget>
    <class>fftDisplay</class>
-   <extends>QLabel</extends>
-   <header>widgets/fftdisplay.h</header>
+   <extends>QWidget</extends>
+   <header>fftdisplay.h</header>
+   <container>1</container>
   </customwidget>
   <customwidget>
    <class>markerWidget</class>
diff --git a/qsstv/widgets/vumeter.cpp b/qsstv/widgets/vumeter.cpp
index ed35e35..8796eeb 100644
--- a/qsstv/widgets/vumeter.cpp
+++ b/qsstv/widgets/vumeter.cpp
@@ -20,7 +20,7 @@
 
 
 #include "vumeter.h"
-#include <qsstvdefs.h>
+#include "configparams.h"
 
 #define BW 5
 #define SG 100
@@ -68,10 +68,11 @@ void vuMeter::paintEvent(QPaintEvent *)
       rw=30;
       rh=5; // rect rounding
     }
-  paintBorder();
+  if(!slowCPU)
+    {
+      paintBorder();
+    }
   paintBar();
-  //paintValue();
-
 }
 
 void vuMeter::paintBorder()
@@ -226,21 +227,24 @@ void vuMeter::setColorLow(QColor color)
 
 void vuMeter::setValue(double value)
 {
+  if((fabs(1-(value/prevValue))<0.05)  && (slowCPU))
+    {
+      return;
+    }
   if (value > max)
     {
       val = max;
-      update();
     }
   else if (value < min)
     {
       val = min;
-      update();
     }
   else
     {
       val = value;
-      update();
     }
+  prevValue=value;
+  update();
 }
 
 
diff --git a/qsstv/widgets/vumeter.h b/qsstv/widgets/vumeter.h
index 2ba24a5..4f104cc 100644
--- a/qsstv/widgets/vumeter.h
+++ b/qsstv/widgets/vumeter.h
@@ -92,6 +92,7 @@ private:
     int rh;
     int divisions;
     QString labelText;
+    double prevValue;
 
 
 };
diff --git a/qsstv/widgets/waterfallform.cpp b/qsstv/widgets/waterfallform.cpp
index cd868e2..0e8af53 100644
--- a/qsstv/widgets/waterfallform.cpp
+++ b/qsstv/widgets/waterfallform.cpp
@@ -1,6 +1,6 @@
 #include "waterfallform.h"
 #include "ui_waterfallform.h"
-#include "qsstvglobal.h"
+#include "appglobal.h"
 #include "sound/waterfalltext.h"
 
 
diff --git a/qsstv/widgets/waterfallform.ui b/qsstv/widgets/waterfallform.ui
index af2e6f5..c2cd68a 100644
--- a/qsstv/widgets/waterfallform.ui
+++ b/qsstv/widgets/waterfallform.ui
@@ -16,34 +16,10 @@
    </font>
   </property>
   <property name="windowTitle">
-   <string>Dialog</string>
+   <string>Waterfall Text</string>
   </property>
   <layout class="QVBoxLayout" name="verticalLayout">
    <item>
-    <layout class="QHBoxLayout" name="horizontalLayout">
-     <item>
-      <widget class="QLabel" name="label">
-       <property name="text">
-        <string>Maximum 10 charaters per line</string>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <spacer name="horizontalSpacer">
-       <property name="orientation">
-        <enum>Qt::Horizontal</enum>
-       </property>
-       <property name="sizeHint" stdset="0">
-        <size>
-         <width>40</width>
-         <height>20</height>
-        </size>
-       </property>
-      </spacer>
-     </item>
-    </layout>
-   </item>
-   <item>
     <layout class="QGridLayout" name="gridLayout">
      <item row="0" column="0">
       <widget class="QPlainTextEdit" name="wfText1">
diff --git a/qsstv/widgets/xyzplaintextedit.cpp b/qsstv/widgets/xyzplaintextedit.cpp
new file mode 100644
index 0000000..0190f94
--- /dev/null
+++ b/qsstv/widgets/xyzplaintextedit.cpp
@@ -0,0 +1,14 @@
+#include "xyzplaintextedit.h"
+#include <QDebug>
+
+xyzPlainTextEdit::xyzPlainTextEdit(QWidget *parent) :
+  QPlainTextEdit(parent)
+{
+
+}
+
+void xyzPlainTextEdit::focusOutEvent(QFocusEvent * event)
+{
+  emit editingFinished();
+  QPlainTextEdit::focusOutEvent(event);
+}
diff --git a/qsstv/widgets/xyzplaintextedit.h b/qsstv/widgets/xyzplaintextedit.h
new file mode 100644
index 0000000..95b057f
--- /dev/null
+++ b/qsstv/widgets/xyzplaintextedit.h
@@ -0,0 +1,21 @@
+#ifndef XYZPLAINTEXTEDIT_H
+#define XYZPLAINTEXTEDIT_H
+
+#include <QPlainTextEdit>
+#include <QFocusEvent>
+
+class xyzPlainTextEdit : public QPlainTextEdit
+{
+  Q_OBJECT
+public:
+  explicit xyzPlainTextEdit(QWidget *parent = 0);
+  void focusOutEvent(QFocusEvent * event);
+
+signals:
+  void editingFinished();
+
+public slots:
+
+};
+
+#endif // XYZPLAINTEXTEDIT_H
diff --git a/qsstv/xmlrpc/ipcmessage.cpp b/qsstv/xmlrpc/ipcmessage.cpp
index 7861972..6c3f653 100644
--- a/qsstv/xmlrpc/ipcmessage.cpp
+++ b/qsstv/xmlrpc/ipcmessage.cpp
@@ -1,6 +1,7 @@
 #include "ipcmessage.h"
 
 #include <QDebug>
+#include "appglobal.h"
 
 
 #include<string.h>
@@ -10,6 +11,7 @@
 #include<sys/wait.h>
 #include<sys/errno.h>
 
+
 //extern int errno;       // error NO.
 
 
@@ -17,8 +19,7 @@ ipcMessage::ipcMessage(int messageKey)
 {
   key=messageKey;
   messageQId = msgget(key, MSGPERM|IPC_CREAT);
-  if(messageQId<0) qDebug() << "IPC Error" << strerror(errno);
-//  else   qDebug()<< "queue opened: id=" << messageQId;
+  if(messageQId<0) errorOut() << "IPC Error" << strerror(errno);
 }
 
 
@@ -41,11 +42,9 @@ bool ipcMessage::sendMessage(QString t)
   rc = msgsnd(messageQId, &msgBuf, len+1, IPC_NOWAIT);
   if (rc < 0)
     {
-      if(rc<0) qDebug() << "IPC Error" << strerror(errno);
+      if(rc<0) errorOut() << "IPC Error" << strerror(errno);
       return false;
     }
-//  qDebug() << "message type" << msgBuf.mtype;
-//  qDebug() << "tx message:" << t;
 
   return true;
 }
@@ -57,13 +56,12 @@ bool ipcMessage::receiveMessage(QString &t)
   rc = msgrcv(messageQId, &msgBuf, sizeof(msgBuf.mtext), 0, IPC_NOWAIT);
   if (rc < -1)
     {
-      if(rc<0) qDebug() << "IPC Error" << strerror(errno);
+      if(rc<0) errorOut() << "IPC Error" << strerror(errno);
       return false;
     }
   if(rc>=0)
     {
       t=msgBuf.mtext;
-//      qDebug() << "rx message:" << t;
       return true;
     }
   return false;
@@ -75,9 +73,8 @@ bool ipcMessage::closeQueue()
   rc=msgctl(messageQId,IPC_RMID,NULL);
   if (rc < 0)
     {
-      if(rc<0) qDebug() << "IPC Error" << strerror(errno);
+      if(rc<0) errorOut() << "IPC Error" << strerror(errno);
       return false;
     }
-//  qDebug()<< "queue closed";
   return 0;
 }
diff --git a/qsstv/xmlrpc/maiaObject.cpp b/qsstv/xmlrpc/maiaObject.cpp
index 3c103b8..5c7d44b 100644
--- a/qsstv/xmlrpc/maiaObject.cpp
+++ b/qsstv/xmlrpc/maiaObject.cpp
@@ -27,6 +27,7 @@
  */
 
 #include "maiaObject.h"
+#include "appglobal.h"
 
 MaiaObject::MaiaObject(QObject* parent) : QObject(parent)
 {
@@ -178,7 +179,7 @@ QDomElement MaiaObject::toXml(QVariant arg)
 
     }
     default:
-        qDebug() << "Failed to marshal unknown variant type: " << arg.type() << endl;
+        errorOut() << "Failed to marshal unknown variant type: " << arg.type() << endl;
     }
     return QDomElement(); //QString::null;
 }
@@ -200,7 +201,10 @@ QVariant MaiaObject::fromXml(const QDomElement &elem)
     const QString typeName = typeElement.tagName().toLower();
 
     if(typeName == "string") return QVariant(typeElement.text());
-    else if(typeName == "i4" || typeName == "int") return QVariant(typeElement.text().toInt());
+    else if(typeName == "i4" || typeName == "int")
+      {
+        return QVariant(typeElement.text().toInt());
+      }
     else if(typeName == "double") return QVariant(typeElement.text().toDouble());
     else if (typeName == "boolean")
     {
@@ -236,7 +240,7 @@ QVariant MaiaObject::fromXml(const QDomElement &elem)
     }
     else
     {
-        qDebug() << "Cannot demarshal unknown type " << typeElement.tagName().toLower();
+        errorOut() << "Cannot demarshal unknown type " << typeElement.tagName().toLower();
     }
     return QVariant();
 }
diff --git a/qsstv/xmlrpc/maiaXmlRpcServer.cpp b/qsstv/xmlrpc/maiaXmlRpcServer.cpp
index 0d90bbe..9b22eb3 100644
--- a/qsstv/xmlrpc/maiaXmlRpcServer.cpp
+++ b/qsstv/xmlrpc/maiaXmlRpcServer.cpp
@@ -76,9 +76,10 @@ void MaiaXmlRpcServer::newConnection()
   if (!this->allowedAddresses || this->allowedAddresses->isEmpty() || this->allowedAddresses->contains(connection->peerAddress()))
     {
       MaiaXmlRpcServerConnection *client = new MaiaXmlRpcServerConnection(connection, this);
-      connect(client, SIGNAL(getMethod(QString, QObject **, const char**)),
-              this, SLOT(getMethod(QString, QObject **, const char**)));
-    } else {
+      connect(client, SIGNAL(getMethod(QString, QObject **, const char**)),this, SLOT(getMethod(QString, QObject **, const char**)));
+    }
+  else
+    {
       qWarning() << "Rejected connection attempt from" << connection->peerAddress().toString();
       connection->disconnectFromHost();
     }
diff --git a/qsstv/xmlrpc/maiaXmlRpcServerConnection.cpp b/qsstv/xmlrpc/maiaXmlRpcServerConnection.cpp
index 141e0eb..d608bbc 100644
--- a/qsstv/xmlrpc/maiaXmlRpcServerConnection.cpp
+++ b/qsstv/xmlrpc/maiaXmlRpcServerConnection.cpp
@@ -27,13 +27,14 @@
 
 #include "maiaXmlRpcServerConnection.h"
 #include "maiaXmlRpcServer.h"
+#include "appglobal.h"
 
 MaiaXmlRpcServerConnection::MaiaXmlRpcServerConnection(QTcpSocket *connection, QObject* parent) : QObject(parent)
 {
   header = NULL;
   clientConnection = connection;
   connect(clientConnection, SIGNAL(readyRead()), this, SLOT(readFromSocket()));
-  connect(clientConnection, SIGNAL(disconnected()), this, SLOT(deleteLater()));
+  connect(clientConnection, SIGNAL(disconnected()), this, SLOT(slotDisconnect()));
 }
 
 MaiaXmlRpcServerConnection::~MaiaXmlRpcServerConnection()
@@ -42,6 +43,12 @@ MaiaXmlRpcServerConnection::~MaiaXmlRpcServerConnection()
   delete header;
 }
 
+
+void MaiaXmlRpcServerConnection::slotDisconnect()
+{
+  deleteLater();
+}
+
 void MaiaXmlRpcServerConnection::readFromSocket()
 {
   QString lastLine;
@@ -55,19 +62,19 @@ void MaiaXmlRpcServerConnection::readFromSocket()
           if(!header->isValid())
             {
               /* return http error */
-              qDebug() << "Invalid Header";
+              errorOut() << "Invalid Header";
               return;
             }
           else if(header->method() != "POST")
             {
               /* return http error */
-              qDebug() << "No Post!";
+              errorOut() << "No Post!";
               return;
             }
           else if(!header->contentLength())
             {
               /* return fault */
-              qDebug() << "No Content Length";
+              errorOut() << "No Content Length";
               return;
             }
         }
@@ -79,6 +86,8 @@ void MaiaXmlRpcServerConnection::readFromSocket()
         {
           /* all data complete */
           parseCall(clientConnection->readAll());
+          delete header;
+          header=NULL;
         }
     }
 }
@@ -93,7 +102,7 @@ void MaiaXmlRpcServerConnection::sendResponse(QString content) {
   block.append(header.toString().toUtf8());
   block.append(content.toUtf8());
   clientConnection->write(block);
-  clientConnection->disconnectFromHost();
+//  clientConnection->disconnectFromHost();
 }
 
 void MaiaXmlRpcServerConnection::parseCall(QString call)
@@ -104,7 +113,6 @@ void MaiaXmlRpcServerConnection::parseCall(QString call)
   QString response;
   QObject *responseObject;
   const char *responseSlot;
-
   if(!doc.setContent(call)) { /* received invalid xml */
       MaiaFault fault(-32700, "parse error: not well formed");
       sendResponse(fault.toString());
@@ -120,7 +128,6 @@ void MaiaXmlRpcServerConnection::parseCall(QString call)
     }
 
   QString methodName = methodNameElement.text();
-//  qDebug() << "methodname" << methodName;
 
   emit getMethod(methodName, &responseObject, &responseSlot);
   if(!responseObject)
@@ -168,7 +175,6 @@ bool invokeMethodWithVariants(QObject *obj,
   // QMetaObject::invokeMethod() has a 10 argument maximum
   if(args.count() > 10)
     return false;
-
   QList<QByteArray> argTypes;
   for(int n = 0; n < args.count(); ++n)
     argTypes += args[n].typeName();
@@ -179,7 +185,6 @@ bool invokeMethodWithVariants(QObject *obj,
   if(!retTypeName.isEmpty()  && retTypeName != "QVariant")
     {
       metatype = QMetaType::type(retTypeName.data());
-      //      qDebug() << QMetaType::typeName(metatype);
       if(metatype == 0) // lookup failed
         return false;
     }
diff --git a/qsstv/xmlrpc/maiaXmlRpcServerConnection.h b/qsstv/xmlrpc/maiaXmlRpcServerConnection.h
index bad1d88..b0469cd 100644
--- a/qsstv/xmlrpc/maiaXmlRpcServerConnection.h
+++ b/qsstv/xmlrpc/maiaXmlRpcServerConnection.h
@@ -82,6 +82,7 @@ class MaiaXmlRpcServerConnection : public QObject {
 
 	private slots:
 		void readFromSocket();
+    void slotDisconnect();
 	
 	private:
 		void sendResponse(QString content);
diff --git a/qsstv/xmlrpc/xmlinterface.cpp b/qsstv/xmlrpc/xmlinterface.cpp
index 3a838c1..f105412 100644
--- a/qsstv/xmlrpc/xmlinterface.cpp
+++ b/qsstv/xmlrpc/xmlinterface.cpp
@@ -1,5 +1,5 @@
 #include "xmlinterface.h"
-#include "qsstvglobal.h"
+#include "appglobal.h"
 
 xmlInterface::xmlInterface(QObject *parent) : QObject(parent)
 {
@@ -18,6 +18,7 @@ xmlInterface::xmlInterface(QObject *parent) : QObject(parent)
   rpcServer->addMethod("main.get_frequency", this, "getFrequency");
   rpcServer->addMethod("rig.get_mode", this, "getMode");
   rpcServer->addMethod("rig.get_bandwidth", this, "getBandwidth");
+  rpcServer->addMethod("rig.get_notch", this, "getNotch");
 }
 
 
@@ -38,6 +39,7 @@ void xmlInterface::setMode(QString t)
 void xmlInterface::setModes(QVariantList t)
 {
     log("setModes",t);
+
 }
 
 void xmlInterface::setBandwidths(QVariantList t)
@@ -70,8 +72,7 @@ QString xmlInterface::getTrxState()
 double  xmlInterface::getFrequency()
 {
   log("getFrequency",QString::number(rigInfo.frequency,'g',9));
-//  return rigInfo.frequency;
-  return 14077777;
+  return rigInfo.frequency;
 }
 
 QString  xmlInterface::getMode()
@@ -79,6 +80,14 @@ QString  xmlInterface::getMode()
     log("getMode",rigInfo.mode);
     return rigInfo.mode;
 }
+
+int xmlInterface::getNotch(int t)
+{
+    log("getNotch",QString::number(rigInfo.notch));
+    rigInfo.notch=t;
+    return 1;
+}
+
 QString  xmlInterface::getBandwidth()
 {
     log("getBandwidth",rigInfo.bandWidth);
@@ -142,6 +151,9 @@ void xmlInterface::activatePTT(bool b)
 
 void xmlInterface::log(QString cmd,QString t)
 {
+  Q_UNUSED(cmd);
+  Q_UNUSED(t);
+
   addToLog(cmd+": "+t,LOGXML);
 }
 
diff --git a/qsstv/xmlrpc/xmlinterface.h b/qsstv/xmlrpc/xmlinterface.h
index ef3295f..bbe2b73 100644
--- a/qsstv/xmlrpc/xmlinterface.h
+++ b/qsstv/xmlrpc/xmlinterface.h
@@ -16,6 +16,7 @@ struct sxmlInfo
   double frequency;
   QString mode;
   QString trxState;
+  int notch;
 };
 
 class xmlInterface : public QObject
@@ -40,6 +41,7 @@ public slots:
   QString getMode();
   QString getBandwidth();
   QString getTrxState();
+  int getNotch(int t);
 
 
 private:
diff --git a/qsstv_8_2.pro b/qsstv_9_1.pro
similarity index 88%
rename from qsstv_8_2.pro
rename to qsstv_9_1.pro
index 6da9e42..49b7588 100644
--- a/qsstv_8_2.pro
+++ b/qsstv_9_1.pro
@@ -1,9 +1,6 @@
 TEMPLATE = subdirs
 
-CONFIG(release ,debug|release){
-SUBDIRS += \
-    qsstv
-}
+CONFIG += ordered
 
 CONFIG(debug ,debug|release){
 SUBDIRS += \
@@ -12,4 +9,7 @@ SUBDIRS += \
 }
 
 
-
+CONFIG(release ,debug|release){
+SUBDIRS += \
+    qsstv
+}
diff --git a/qwt/qwt_transform.cpp b/qwt/qwt_transform.cpp
index 359fc9f..345e3ec 100644
--- a/qwt/qwt_transform.cpp
+++ b/qwt/qwt_transform.cpp
@@ -15,10 +15,10 @@
 #endif
 
 //! Smallest allowed value for logarithmic scales: 1.0e-150
-QT_STATIC_CONST_IMPL double QwtLogTransform::LogMin = 1.0e-150;
+const double QwtLogTransform::LogMin = 1.0e-150;
 
 //! Largest allowed value for logarithmic scales: 1.0e150
-QT_STATIC_CONST_IMPL double QwtLogTransform::LogMax = 1.0e150;
+const double QwtLogTransform::LogMax = 1.0e150;
 
 //! Constructor
 QwtTransform::QwtTransform()
diff --git a/qwt/qwt_transform.h b/qwt/qwt_transform.h
index ce13fa6..05f016a 100644
--- a/qwt/qwt_transform.h
+++ b/qwt/qwt_transform.h
@@ -107,8 +107,8 @@ public:
 
     virtual QwtTransform *copy() const;
 
-    QT_STATIC_CONST double LogMin;
-    QT_STATIC_CONST double LogMax;
+    static const double LogMin;
+   static const double LogMax;
 };
 
 /*!

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-hamradio/qsstv.git



More information about the pkg-hamradio-commits mailing list