[hamradio-commits] [linpsk] 01/07: Imported Upstream version 1.1
Iain Learmonth
irl-guest at moszumanska.debian.org
Sun May 3 19:57:19 UTC 2015
This is an automated email from the git hooks/post-receive script.
irl-guest pushed a commit to branch master
in repository linpsk.
commit c026f86c68fbbf2920894e69846fd15caab75504
Author: Iain R. Learmonth <irl at fsfe.org>
Date: Sun May 3 20:27:27 2015 +0100
Imported Upstream version 1.1
---
COPYING | 340 +++++++
ChangeLog | 103 +++
README | 12 +
asoundrc | 22 +
gui/.directory | 3 +
gui/addmacro.cpp | 91 ++
gui/addmacro.h | 60 ++
gui/addmacro.ui | 383 ++++++++
gui/addrxwindow.cpp | 55 ++
gui/addrxwindow.h | 52 ++
gui/addrxwindow.ui | 247 +++++
gui/deletemacro.cpp | 87 ++
gui/deletemacro.h | 53 ++
gui/deletemacro.ui | 292 ++++++
gui/editmacro.cpp | 72 ++
gui/editmacro.h | 55 ++
gui/editmacro.ui | 165 ++++
gui/generalsettings.cpp | 180 ++++
gui/generalsettings.h | 53 ++
gui/generalsettings.ui | 512 +++++++++++
gui/gui.pro | 48 +
gui/modemenu.cpp | 104 +++
gui/modemenu.h | 54 ++
gui/modemenu.ui | 344 +++++++
gui/qsodata.cpp | 425 +++++++++
gui/qsodata.h | 80 ++
gui/qsodata.ui | 1883 +++++++++++++++++++++++++++++++++++++++
gui/renamemacro.cpp | 61 ++
gui/renamemacro.h | 53 ++
gui/renamemacro.ui | 227 +++++
images/linpsk.png | Bin 0 -> 294 bytes
linpsk.pro | 23 +
src/application.qrc | 5 +
src/bpskdemodulator.cpp | 118 +++
src/bpskdemodulator.h | 46 +
src/bpskmodulator.cpp | 83 ++
src/bpskmodulator.h | 36 +
src/cdemodulator.cpp | 101 +++
src/cdemodulator.h | 85 ++
src/cledbutton.cpp | 93 ++
src/cledbutton.h | 51 ++
src/cmodulator.cpp | 38 +
src/cmodulator.h | 59 ++
src/color.h | 289 ++++++
src/constants.h | 96 ++
src/controlpanel.cpp | 76 ++
src/controlpanel.h | 43 +
src/cpskdemodulator.cpp | 719 +++++++++++++++
src/cpskdemodulator.h | 118 +++
src/crecording.cpp | 76 ++
src/crecording.h | 46 +
src/crxchannel.cpp | 322 +++++++
src/crxchannel.h | 92 ++
src/crxdisplay.cpp | 416 +++++++++
src/crxdisplay.h | 112 +++
src/crxwindow.cpp | 291 ++++++
src/crxwindow.h | 90 ++
src/csound.cpp | 498 +++++++++++
src/csound.h | 63 ++
src/csquelch.cpp | 187 ++++
src/csquelch.h | 77 ++
src/ctrigger.cpp | 68 ++
src/ctrigger.h | 54 ++
src/ctxbuffer.cpp | 111 +++
src/ctxbuffer.h | 44 +
src/ctxdisplay.cpp | 120 +++
src/ctxdisplay.h | 60 ++
src/ctxwindow.cpp | 292 ++++++
src/ctxwindow.h | 71 ++
src/deinterleaver.cpp | 57 ++
src/deinterleaver.h | 37 +
src/feccoder.cpp | 56 ++
src/feccoder.h | 36 +
src/fircoeffs.h | 485 ++++++++++
src/firfilter.cpp | 114 +++
src/firfilter.h | 43 +
src/frequencyselect.cpp | 204 +++++
src/frequencyselect.h | 67 ++
src/fskmodulator.cpp | 66 ++
src/fskmodulator.h | 48 +
src/input.cpp | 47 +
src/input.h | 71 ++
src/interleaver.cpp | 52 ++
src/interleaver.h | 39 +
src/linpsk.cpp | 982 ++++++++++++++++++++
src/linpsk.h | 146 +++
src/macros.cpp | 259 ++++++
src/macros.h | 61 ++
src/macrowindow.cpp | 135 +++
src/macrowindow.h | 53 ++
src/main.cpp | 40 +
src/mfskdemodulator.cpp | 249 ++++++
src/mfskdemodulator.h | 84 ++
src/mfskmodulator.cpp | 117 +++
src/mfskmodulator.h | 67 ++
src/mfskvaricode.cpp | 71 ++
src/mfskvaricode.h | 36 +
src/parameter.cpp | 55 ++
src/parameter.h | 89 ++
src/processlogdata.cpp | 150 ++++
src/processlogdata.h | 62 ++
src/pskmodulator.cpp | 632 +++++++++++++
src/pskmodulator.h | 111 +++
src/psktable.h | 120 +++
src/qpskdemodulator.cpp | 156 ++++
src/qpskdemodulator.h | 47 +
src/qpskmodulator.cpp | 103 +++
src/qpskmodulator.h | 37 +
src/readonlystringlistmodel.cpp | 35 +
src/readonlystringlistmodel.h | 41 +
src/rttydemodulator.cpp | 611 +++++++++++++
src/rttydemodulator.h | 120 +++
src/rttymodulator.cpp | 470 ++++++++++
src/rttymodulator.h | 68 ++
src/spectrumdisplay.cpp | 354 ++++++++
src/spectrumdisplay.h | 96 ++
src/src.pro | 130 +++
src/textinput.cpp | 129 +++
src/textinput.h | 53 ++
src/viterbi.cpp | 135 +++
src/viterbi.h | 50 ++
src/viterbisoft.cpp | 953 ++++++++++++++++++++
src/viterbisoft.h | 75 ++
src/waveinput.cpp | 297 ++++++
src/waveinput.h | 61 ++
125 files changed, 20247 insertions(+)
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..5b6e7c6
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..fca8c3b
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,103 @@
+LinPsk ChangeLog
+
+1.1
+
+Fixed wrong code for 'LF' in rttymodulator.cpp, Thanks to kf9a
+'Home key' mapped to 'cr'
+Possibility introduced to send 'CR' 'LF' on enter key. Selectable by setup.
+Reintroduced squelch for rtty .
+Expand auto CR LF to sendfile
+
+1.0
+
+Reading and writing data from /to soundcard now happens in an extra threads.
+Switch from qt3 to qt4. This implies major modifications of gui code.
+LinPsk now supports Loging via LinLog
+New menu for taking qso data for loging. ( Right mouse click in the active rx window )
+MFSK16 is now operational. Thanks to Chen, W7AY, who gave me the essential hints.
+
+0.9
+
+Switching from portaudio to native alsa support
+Modified Afc for BPSK31 decoder
+Integrating patches
+
+0.8.1
+
+Improved RTTY decoder
+
+Setting for slashed 0 now will be saved
+
+Fixed some memory leakages
+
+Removed dependancy on qwindowsstyle.h, so LinPsk now should compile on Slackware without problems.
+
+Some minor bugfixes
+
+0.8.0.4
+
+Experimental RTTY decoder ( rtty2 ).
+
+Now 8 bit wav files in Demo mode will be supported.
+
+In RTTY shifts up to 999 Hz are possible now.
+
+RTTY is now able to transmit in LSB.
+
+USB to Serial Converter for RX/TX switching now really works
+
+Hopefully fixed crash on quit
+
+Using UTC in QSOData
+
+0.8.0.3
+
+New features
+
+Supporting USB to Serial Converter for RX/TX switching
+
+( Due to missing hardware untested )
+
+Looks in the /dev directory for devices that contain the string usbserial.
+
+added to General Settings
+
+Delete macro
+Rename macro
+
+
+Save QSOData now implemented
+Data are saved in ADIF format. You can set the name of this file in General settings. The file will be located in the users home directory.
+
+Command c now copies text from the clipboard into the tx buffer, if the TX window is the active window.
+
+The proportion between colour spectrum and spectrum can be modified.
+
+
+Fixes
+
+Hopefully fixed the reported freeze when switching from TX to RX.
+
+Fixed that portaudio changes the output volume when level < 10.
+
+Now squelch changes colour when the level goes above selected squelch level ( like LinPsk does).
+
+Some minor bugs fixed. Now using qt 3.3.2 , which improves the layout of some buttons.
+
+Switched to fftw 3.0.1
+
+
+0.8.0.2
+
+Characters, that were deleted , won't be transmitted together with the delete anymore.
+
+Fixed bug in setting input and output volume
+
+Windows position now will be saved when exiting the application by Quit.
+
+Trying to fix crash, when closing DarwinPsk by the little red button
+
+
+0.8.0.1
+
+Fixing the "spinning disc of death"
diff --git a/README b/README
new file mode 100644
index 0000000..da8ec9b
--- /dev/null
+++ b/README
@@ -0,0 +1,12 @@
+To build linpsk, untar the tar archiv and switch to the linpsk directory.
+
+run:
+qmake -unix -o Makefile linpsk.pro
+make
+
+The executable linpsk is build in the bin subdirectory. Move the binary into prefered location , probably /usr/local/bin
+
+LinPSK now uses the alsa sound system.
+The names of the used alsa devices are LinPSK_Record and LinPSK_Play.
+To map these names to your soundcard edit the file asoundrc in the linpsk directory appropriately and append it to .asoundrc in your homedirectory.
+If no .asoundrc exists copy the edited asoundrc to .asoundrc in your homedirectory instead of appending.
\ No newline at end of file
diff --git a/asoundrc b/asoundrc
new file mode 100644
index 0000000..2e047a1
--- /dev/null
+++ b/asoundrc
@@ -0,0 +1,22 @@
+pcm.LinPSK_card {
+ type hw
+# Replace the following line by the name of your card
+ card M5455
+ }
+ctl.LinPSK_card {
+ type hw
+# Replace the following line by the name of your card
+ card M5455
+ }
+pcm.LinPSK_Play {
+ type plug
+ slave {
+ pcm "LinPSK_card"
+ }
+}
+pcm.LinPSK_Record {
+ type plug
+ slave {
+ pcm "LinPSK_card"
+ }
+}
diff --git a/gui/.directory b/gui/.directory
new file mode 100644
index 0000000..09ee32e
--- /dev/null
+++ b/gui/.directory
@@ -0,0 +1,3 @@
+[Dolphin]
+Timestamp=2009,11,14,11,57,46
+ViewMode=1
diff --git a/gui/addmacro.cpp b/gui/addmacro.cpp
new file mode 100644
index 0000000..14dfbae
--- /dev/null
+++ b/gui/addmacro.cpp
@@ -0,0 +1,91 @@
+/***************************************************************************
+ * Copyright (C) 2007 by volker, DL1KSV *
+ * schroer at tux64 *
+ * *
+ * 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 "addmacro.h"
+#include "readonlystringlistmodel.h"
+#include <QMessageBox>
+AddMacro::AddMacro(Macros *k,QWidget* parent, Qt::WFlags fl)
+: QDialog( parent, fl ), Ui::AddMacro()
+{
+ setupUi(this);
+ReadOnlyStringListModel *model= new ReadOnlyStringListModel();
+model->setStringList(k->getKeyWordList());
+KeywordDisplay->setModel(model);
+connect(KeywordDisplay,SIGNAL(clicked(const QModelIndex &)),this,SLOT(insertKeyword(const QModelIndex &)));
+model= new ReadOnlyStringListModel();
+model->setStringList(k->getMacroList());
+MacroDisplay->setModel(model);
+Position->setMaximum(k->getMacroList().size()+1);
+Position->setValue(k->getMacroList().size()+1);
+
+}
+
+AddMacro::~AddMacro()
+{
+}
+void AddMacro::accept()
+{
+if (MacroName->text().length()== 0)
+ {
+ QMessageBox::warning(this,"Incomplete Macro Definition","Name of Macro is missing \n Enter Name of Macro",
+ QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
+ return;
+ }
+if (MacroDefinition->toPlainText().length()== 0)
+ {
+ QMessageBox::warning(this,"Incomplete Macro Definition","Macrodefinition is missing \n Enter Macrodefinition",
+ QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
+ return;
+ }
+int anzahl=MacroDefinition->toPlainText().count(QLatin1Char('@'));
+
+ if (( anzahl > 0) && ((anzahl/2)*2 != anzahl) )
+ {
+ QMessageBox::warning(this,"Error in Macro Definition","Error in Macrodefinition. Incorrect number of @ \n Enter Macrodefinition",
+ QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
+ return;
+ }
+ QDialog::accept();
+}
+
+void AddMacro::insertKeyword(const QModelIndex &index)
+{
+ QString s=index.data().toString();
+ MacroDefinition->insertPlainText(s);
+ MacroDefinition->setFocus();
+}
+
+QString AddMacro::macroName()
+{
+ return MacroName->text();
+}
+QString AddMacro::macroDefinition()
+{
+ return MacroDefinition->toPlainText();
+}
+int AddMacro::position()
+{
+ return Position->value();
+}
+QString AddMacro::accelerator()
+{
+ return Accelerator->text();
+}
diff --git a/gui/addmacro.h b/gui/addmacro.h
new file mode 100644
index 0000000..3b704a4
--- /dev/null
+++ b/gui/addmacro.h
@@ -0,0 +1,60 @@
+/***************************************************************************
+ * Copyright (C) 2007 by volker, DL1KSV *
+ * schroer at tux64 *
+ * *
+ * 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 ADDMACRO_H
+#define ADDMACRO_H
+
+#include <QDialog>
+#include <QString>
+
+#include "macros.h"
+
+#include "ui_addmacro.h"
+
+class Macros;
+class QModelIndex;
+class AddMacro : public QDialog, private Ui::AddMacro
+{
+ Q_OBJECT
+
+public:
+ AddMacro(Macros *,QWidget* parent = 0, Qt::WFlags fl = 0 );
+ ~AddMacro();
+ /*$PUBLIC_FUNCTIONS$*/
+//void setKeywords( Macros *k );
+QString macroName();
+QString macroDefinition();
+int position();
+QString accelerator();
+
+public slots:
+ /*$PUBLIC_SLOTS$*/
+
+protected:
+ /*$PROTECTED_FUNCTIONS$*/
+
+protected slots:
+ /*$PROTECTED_SLOTS$*/
+ virtual void accept();
+void insertKeyword(const QModelIndex &);
+};
+
+#endif
+
diff --git a/gui/addmacro.ui b/gui/addmacro.ui
new file mode 100644
index 0000000..33d10ea
--- /dev/null
+++ b/gui/addmacro.ui
@@ -0,0 +1,383 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>AddMacro</class>
+ <widget class="QDialog" name="AddMacro">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>676</width>
+ <height>531</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>600</width>
+ <height>450</height>
+ </size>
+ </property>
+ <property name="baseSize">
+ <size>
+ <width>600</width>
+ <height>350</height>
+ </size>
+ </property>
+ <property name="windowTitle">
+ <string>Add Macro</string>
+ </property>
+ <property name="sizeGripEnabled">
+ <bool>true</bool>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0" colspan="2">
+ <widget class="QLabel" name="textLabel1">
+ <property name="minimumSize">
+ <size>
+ <width>90</width>
+ <height>20</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Macro Name</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QLineEdit" name="MacroName">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>210</width>
+ <height>20</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3" colspan="2">
+ <widget class="QLabel" name="textLabel2">
+ <property name="minimumSize">
+ <size>
+ <width>145</width>
+ <height>20</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Position in Macro List</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="5">
+ <spacer name="horizontalSpacer_5">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>72</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="0" column="6">
+ <widget class="QSpinBox" name="Position">
+ <property name="minimumSize">
+ <size>
+ <width>45</width>
+ <height>20</height>
+ </size>
+ </property>
+ <property name="minimum">
+ <number>1</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="2">
+ <widget class="QLabel" name="textLabel1_3">
+ <property name="minimumSize">
+ <size>
+ <width>90</width>
+ <height>20</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Accelerator</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QLineEdit" name="Accelerator">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>210</width>
+ <height>20</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="4">
+ <spacer name="horizontalSpacer_4">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>72</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="textLabel3">
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>20</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Macro Text</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="3">
+ <widget class="QLabel" name="textLabel4">
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>20</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>List of macros</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" colspan="3">
+ <widget class="QTextEdit" name="MacroDefinition">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="3" colspan="4">
+ <widget class="QListView" name="MacroDisplay"/>
+ </item>
+ <item row="4" column="0" rowspan="2" colspan="3">
+ <widget class="QListView" name="KeywordDisplay">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="3">
+ <widget class="QPushButton" name="buttonOk">
+ <property name="text">
+ <string>&OK</string>
+ </property>
+ <property name="shortcut">
+ <string/>
+ </property>
+ <property name="autoDefault">
+ <bool>true</bool>
+ </property>
+ <property name="default">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="4">
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>72</width>
+ <height>22</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="5" column="5">
+ <widget class="QPushButton" name="buttonCancel">
+ <property name="text">
+ <string>&Cancel</string>
+ </property>
+ <property name="shortcut">
+ <string/>
+ </property>
+ <property name="autoDefault">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="6">
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>71</width>
+ <height>22</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="6" column="0">
+ <widget class="QLabel" name="textLabel1_2">
+ <property name="text">
+ <string>Keywords</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="1" colspan="2">
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>237</width>
+ <height>21</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="6" column="3" colspan="5">
+ <spacer name="horizontalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>338</width>
+ <height>21</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="4" column="3" colspan="5">
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string>Example</string>
+ </property>
+ <widget class="QLabel" name="textLabel6">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>20</y>
+ <width>281</width>
+ <height>41</height>
+ </rect>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Plain</enum>
+ </property>
+ <property name="text">
+ <string>@TX@ cq cq de @CALLSIGN@ pse k @RX@</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <pixmapfunction>qPixmapFromMimeSource</pixmapfunction>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonOk</sender>
+ <signal>clicked()</signal>
+ <receiver>AddMacro</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>buttonCancel</sender>
+ <signal>clicked()</signal>
+ <receiver>AddMacro</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/gui/addrxwindow.cpp b/gui/addrxwindow.cpp
new file mode 100644
index 0000000..e0f6969
--- /dev/null
+++ b/gui/addrxwindow.cpp
@@ -0,0 +1,55 @@
+/***************************************************************************
+ * Copyright (C) 2007 by volker, DL1KSV *
+ * schroer at tux64 *
+ * *
+ * 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 "addrxwindow.h"
+#include "parameter.h"
+
+extern Parameter settings;
+
+AddRxWindow::AddRxWindow(QWidget* parent, Qt::WFlags fl)
+: QDialog( parent, fl ), Ui::AddRxWindow()
+{
+ setupUi(this);
+RxMode->insertItem(0,"BPSK");
+RxMode->insertItem(1,"QPSK");
+RxMode->insertItem(2,"RTTY");
+RxMode->insertItem(3,"MFSK16");
+RxMode->setCurrentRow(0);
+TitleText->setText("Rx " + QString().setNum(settings.RxChannels+1));
+
+}
+
+AddRxWindow::~AddRxWindow()
+{
+}
+Mode AddRxWindow::selectedMode()
+{
+return (Mode) RxMode->currentRow();
+}
+QString AddRxWindow::titleText()
+{
+ return TitleText->text();
+}
+int AddRxWindow::frequency()
+{
+ return Frequency->value();
+}
+
diff --git a/gui/addrxwindow.h b/gui/addrxwindow.h
new file mode 100644
index 0000000..f519ff8
--- /dev/null
+++ b/gui/addrxwindow.h
@@ -0,0 +1,52 @@
+/***************************************************************************
+ * Copyright (C) 2007 by volker, DL1KSV *
+ * schroer at tux64 *
+ * *
+ * 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 ADDRXWINDOW_H
+#define ADDRXWINDOW_H
+
+#include <QDialog>
+#include "ui_addrxwindow.h"
+#include "constants.h"
+
+class AddRxWindow : public QDialog, private Ui::AddRxWindow
+{
+ Q_OBJECT
+
+public:
+ AddRxWindow(QWidget* parent = 0, Qt::WFlags fl = 0 );
+ ~AddRxWindow();
+Mode selectedMode();
+QString titleText();
+int frequency();
+ /*$PUBLIC_FUNCTIONS$*/
+
+public slots:
+ /*$PUBLIC_SLOTS$*/
+
+protected:
+ /*$PROTECTED_FUNCTIONS$*/
+
+protected slots:
+ /*$PROTECTED_SLOTS$*/
+
+};
+
+#endif
+
diff --git a/gui/addrxwindow.ui b/gui/addrxwindow.ui
new file mode 100644
index 0000000..ef2ccb3
--- /dev/null
+++ b/gui/addrxwindow.ui
@@ -0,0 +1,247 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>AddRxWindow</class>
+ <widget class="QDialog" name="AddRxWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>325</width>
+ <height>299</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Add another RxWIndow</string>
+ </property>
+ <property name="sizeGripEnabled">
+ <bool>true</bool>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="RxWindowName">
+ <property name="text">
+ <string>Title</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" colspan="2">
+ <widget class="QLineEdit" name="TitleText">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>80</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="1" rowspan="3" colspan="3">
+ <widget class="QListWidget" name="RxMode">
+ <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="Modulation">
+ <property name="text">
+ <string>Mode</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <spacer name="verticalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>80</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="RxFrequency">
+ <property name="text">
+ <string>Rx Frequency</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QSpinBox" name="Frequency">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="suffix">
+ <string>Hz</string>
+ </property>
+ <property name="minimum">
+ <number>300</number>
+ </property>
+ <property name="maximum">
+ <number>2500</number>
+ </property>
+ <property name="value">
+ <number>1000</number>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="2" colspan="2">
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>147</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="5" column="0" colspan="3">
+ <layout class="QHBoxLayout">
+ <item>
+ <widget class="QPushButton" name="buttonOk">
+ <property name="focusPolicy">
+ <enum>Qt::ClickFocus</enum>
+ </property>
+ <property name="text">
+ <string>OK</string>
+ </property>
+ <property name="shortcut">
+ <string/>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ <property name="default">
+ <bool>false</bool>
+ </property>
+ <property name="flat">
+ <bool>false</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>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonCancel">
+ <property name="focusPolicy">
+ <enum>Qt::ClickFocus</enum>
+ </property>
+ <property name="text">
+ <string>Cancel</string>
+ </property>
+ <property name="shortcut">
+ <string/>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="5" column="3">
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>126</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="7"/>
+ <pixmapfunction>qPixmapFromMimeSource</pixmapfunction>
+ <includes>
+ <include location="local">constants.h</include>
+ </includes>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonOk</sender>
+ <signal>clicked()</signal>
+ <receiver>AddRxWindow</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>buttonCancel</sender>
+ <signal>clicked()</signal>
+ <receiver>AddRxWindow</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/gui/deletemacro.cpp b/gui/deletemacro.cpp
new file mode 100644
index 0000000..5296127
--- /dev/null
+++ b/gui/deletemacro.cpp
@@ -0,0 +1,87 @@
+/***************************************************************************
+ * Copyright (C) 2007 by volker, DL1KSV *
+ * schroer at tux64 *
+ * *
+ * 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 "deletemacro.h"
+#include "macros.h"
+//#include <QStringListModel>
+#include "readonlystringlistmodel.h"
+DeleteMacro::DeleteMacro ( Macros *M, QWidget* parent, Qt::WFlags fl )
+ : QDialog ( parent, fl ), Ui::DeleteMacro()
+{
+ setupUi ( this );
+ AllMacros = M;
+// model = new QStringListModel ( AllMacros->getMacroList() );
+ model = new ReadOnlyStringListModel ( AllMacros->getMacroList() );
+// deleteList = new QStringListModel ( this );
+ deleteList = new ReadOnlyStringListModel ( this );
+ MacroBox->setModel ( model );
+ Macrostodelete->setModel ( deleteList );
+ connect ( Add, SIGNAL ( clicked ( bool ) ), this, SLOT ( addtoList() ) );
+ connect ( Remove, SIGNAL ( clicked ( bool ) ), this, SLOT ( removefromList() ) );
+}
+
+DeleteMacro::~DeleteMacro()
+{
+ if ( model != 0 )
+ delete model;
+ delete deleteList;
+}
+
+
+void DeleteMacro::accept()
+{
+
+ QStringList d = deleteList->stringList();
+
+ if ( !d.isEmpty() )
+ {
+ QString s;
+ for ( int i = 0; i < d.size(); i++ )
+ {
+ s = d.at ( i );
+ for ( int k = 0;k < AllMacros->count();k++ )
+ {
+ if ( AllMacros->getMacroName ( k ) == s )
+ {
+ AllMacros->deleteMacro ( k );
+ break;
+ }
+ }
+
+ }
+// Store list to macros ??
+ }
+ QDialog::accept();
+}
+
+void DeleteMacro::addtoList()
+{
+ QStringList l = deleteList->stringList();
+ l << MacroBox->currentIndex().data().toString();
+ deleteList->setStringList ( l );
+}
+
+void DeleteMacro::removefromList()
+{
+ deleteList->removeRows ( Macrostodelete->currentIndex().row(), 1 );
+}
+
+
diff --git a/gui/deletemacro.h b/gui/deletemacro.h
new file mode 100644
index 0000000..c0e6a9b
--- /dev/null
+++ b/gui/deletemacro.h
@@ -0,0 +1,53 @@
+/***************************************************************************
+ * Copyright (C) 2007 by volker, DL1KSV *
+ * schroer at tux64 *
+ * *
+ * 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 DELETEMACRO_H
+#define DELETEMACRO_H
+
+#include <QDialog>
+#include "ui_deletemacro.h"
+class Macros;
+class ReadOnlyStringListModel;
+class DeleteMacro : public QDialog, private Ui::DeleteMacro
+{
+ Q_OBJECT
+
+public:
+ DeleteMacro(Macros *M,QWidget* parent = 0, Qt::WFlags fl = 0 );
+ ~DeleteMacro();
+ /*$PUBLIC_FUNCTIONS$*/
+
+public slots:
+ /*$PUBLIC_SLOTS$*/
+
+protected:
+Macros *AllMacros;
+ReadOnlyStringListModel *model;
+ReadOnlyStringListModel *deleteList;
+
+protected slots:
+ /*$PROTECTED_SLOTS$*/
+ virtual void accept();
+void removefromList();
+void addtoList();
+};
+
+#endif
+
diff --git a/gui/deletemacro.ui b/gui/deletemacro.ui
new file mode 100644
index 0000000..d305cb1
--- /dev/null
+++ b/gui/deletemacro.ui
@@ -0,0 +1,292 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>DeleteMacro</class>
+ <widget class="QDialog" name="DeleteMacro">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>600</width>
+ <height>291</height>
+ </rect>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>300</width>
+ <height>200</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>600</width>
+ <height>400</height>
+ </size>
+ </property>
+ <property name="baseSize">
+ <size>
+ <width>300</width>
+ <height>100</height>
+ </size>
+ </property>
+ <property name="windowTitle">
+ <string>Delete Macro</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0" colspan="2">
+ <widget class="QLabel" name="MLabel">
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>30</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Available Macros</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3">
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>117</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="0" column="4">
+ <widget class="QLabel" name="DMacros">
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>25</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Macros to be deleted</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" rowspan="4" colspan="3">
+ <widget class="QListView" name="MacroBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="baseSize">
+ <size>
+ <width>130</width>
+ <height>100</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3">
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>70</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="4" rowspan="4">
+ <widget class="QListView" name="Macrostodelete">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="3">
+ <widget class="QPushButton" name="Add">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>100</width>
+ <height>15</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>20</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Add to list -></string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="3">
+ <widget class="QPushButton" name="Remove">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>120</width>
+ <height>15</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>200</width>
+ <height>20</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Remove from list <-</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="3">
+ <spacer name="verticalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>69</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="5" column="0">
+ <widget class="QPushButton" name="Ok">
+ <property name="minimumSize">
+ <size>
+ <width>60</width>
+ <height>25</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Ok</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="1">
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>140</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="5" column="2">
+ <widget class="QPushButton" name="Cancel">
+ <property name="minimumSize">
+ <size>
+ <width>60</width>
+ <height>25</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="3">
+ <spacer name="horizontalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>117</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="5" column="4">
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>208</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <pixmapfunction>qPixmapFromMimeSource</pixmapfunction>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>Ok</sender>
+ <signal>clicked()</signal>
+ <receiver>DeleteMacro</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>Cancel</sender>
+ <signal>clicked()</signal>
+ <receiver>DeleteMacro</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/gui/editmacro.cpp b/gui/editmacro.cpp
new file mode 100644
index 0000000..5b478ff
--- /dev/null
+++ b/gui/editmacro.cpp
@@ -0,0 +1,72 @@
+/***************************************************************************
+ * Copyright (C) 2007 by volker, DL1KSV *
+ * schroer at tux64 *
+ * *
+ * 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 "editmacro.h"
+#include "macros.h"
+#include "readonlystringlistmodel.h"
+
+EditMacro::EditMacro(Macros *M,QWidget* parent, Qt::WFlags fl)
+: QDialog( parent, fl ), Ui::EditMacro()
+{
+ setupUi(this);
+AllMacros=M;
+model=new ReadOnlyStringListModel();
+model->setStringList(M->getKeyWordList());
+Keywords->setModel(model);
+int anzahl=AllMacros->count();
+
+Position->setMaximum(anzahl);
+SelectMacro->insertItem(0," ");
+connect(SelectMacro,SIGNAL(activated(int)),this,SLOT(setText(int)));
+connect(Keywords,SIGNAL(activated(const QModelIndex &)),this,SLOT(insertKeyword(const QModelIndex &)));
+ for(int i=0; i < anzahl; i++)
+ SelectMacro->insertItem(i+1,AllMacros->getMacroName(i));
+}
+
+EditMacro::~EditMacro()
+{
+}
+
+void EditMacro::accept()
+{
+int AktPosition;
+AktPosition=SelectMacro->currentIndex()-1;
+AllMacros->setDefinition(Definition->toPlainText(),AktPosition);
+AllMacros->setAccelerator(Accelerator->text(),AktPosition);
+ QDialog::accept();
+}
+
+void EditMacro::setText( int Number)
+{
+if( Number > 0)
+ {
+ Number--;
+ Position->setValue(Number);
+ Definition->setText(AllMacros->getDefinition(Number));
+ Accelerator->setText(AllMacros->getAccelerator(Number));
+ }
+}
+void EditMacro::insertKeyword(const QModelIndex &index)
+{
+ QString s=index.data().toString();
+ Definition->insertPlainText(s);
+ Definition->setFocus();
+}
diff --git a/gui/editmacro.h b/gui/editmacro.h
new file mode 100644
index 0000000..fdad2b0
--- /dev/null
+++ b/gui/editmacro.h
@@ -0,0 +1,55 @@
+/***************************************************************************
+ * Copyright (C) 2007 by volker, DL1KSV *
+ * schroer at tux64 *
+ * *
+ * 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 EDITMACRO_H
+#define EDITMACRO_H
+
+#include <QDialog>
+#include "ui_editmacro.h"
+
+class Macros;
+class ReadOnlyStringListModel;
+
+
+class EditMacro : public QDialog, private Ui::EditMacro
+{
+ Q_OBJECT
+
+public:
+ EditMacro(Macros *M,QWidget* parent = 0, Qt::WFlags fl = 0 );
+ ~EditMacro();
+
+
+public slots:
+ /*$PUBLIC_SLOTS$*/
+
+protected:
+Macros *AllMacros;
+ReadOnlyStringListModel *model;
+
+protected slots:
+ /*$PROTECTED_SLOTS$*/
+ virtual void accept();
+void setText( int Number);
+void insertKeyword(const QModelIndex &);
+};
+
+#endif
+
diff --git a/gui/editmacro.ui b/gui/editmacro.ui
new file mode 100644
index 0000000..c5122ed
--- /dev/null
+++ b/gui/editmacro.ui
@@ -0,0 +1,165 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>EditMacro</class>
+ <widget class="QDialog" name="EditMacro">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>578</width>
+ <height>293</height>
+ </rect>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>600</width>
+ <height>320</height>
+ </size>
+ </property>
+ <property name="windowTitle">
+ <string>EditMacro</string>
+ </property>
+ <property name="sizeGripEnabled">
+ <bool>true</bool>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0" colspan="2">
+ <widget class="QComboBox" name="SelectMacro"/>
+ </item>
+ <item row="0" column="2">
+ <widget class="QLabel" name="textLabel1_3">
+ <property name="text">
+ <string>Accelerator</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3">
+ <widget class="QLineEdit" name="Accelerator"/>
+ </item>
+ <item row="0" column="4">
+ <widget class="QLabel" name="textLabel1">
+ <property name="text">
+ <string>Position</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="5">
+ <widget class="QSpinBox" name="Position"/>
+ </item>
+ <item row="1" column="0" colspan="2">
+ <widget class="QLabel" name="textLabel2">
+ <property name="text">
+ <string>Definition</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="4">
+ <widget class="QLabel" name="textLabel1_2">
+ <property name="text">
+ <string>Keywords</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" colspan="4">
+ <widget class="QTextEdit" name="Definition"/>
+ </item>
+ <item row="2" column="4" colspan="2">
+ <widget class="QListView" name="Keywords"/>
+ </item>
+ <item row="3" column="0">
+ <widget class="QPushButton" name="buttonOk">
+ <property name="text">
+ <string>&OK</string>
+ </property>
+ <property name="shortcut">
+ <string/>
+ </property>
+ <property name="autoDefault">
+ <bool>true</bool>
+ </property>
+ <property name="default">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1" colspan="2">
+ <widget class="QPushButton" name="buttonCancel">
+ <property name="text">
+ <string>&Cancel</string>
+ </property>
+ <property name="shortcut">
+ <string/>
+ </property>
+ <property name="autoDefault">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="5" margin="10"/>
+ <pixmapfunction>qPixmapFromMimeSource</pixmapfunction>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonOk</sender>
+ <signal>clicked()</signal>
+ <receiver>EditMacro</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>buttonCancel</sender>
+ <signal>clicked()</signal>
+ <receiver>EditMacro</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>
+ <connection>
+ <sender>SelectMacro</sender>
+ <signal>activated(int)</signal>
+ <receiver>EditMacro</receiver>
+ <slot>setText(int)</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/gui/generalsettings.cpp b/gui/generalsettings.cpp
new file mode 100644
index 0000000..84ecf76
--- /dev/null
+++ b/gui/generalsettings.cpp
@@ -0,0 +1,180 @@
+/***************************************************************************
+ * Copyright (C) 2007 by volker, DL1KSV *
+ * schroer at tux64 *
+ * *
+ * 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 "generalsettings.h"
+#include <QString>
+#include <QDir>
+#include <QButtonGroup>
+#include "readonlystringlistmodel.h"
+#include <QModelIndex>
+
+extern Parameter settings;
+GeneralSettings::GeneralSettings ( QWidget* parent, Qt::WFlags fl )
+ : QDialog ( parent, fl ), Ui::GeneralSettings()
+{
+ setupUi ( this );
+ QString DirectoryName;
+ QDir dir;
+
+ LocalSettings = settings;
+ FileFormat = new QButtonGroup ( FileFormatLayout );
+ FileFormat->setExclusive ( true );
+ FileFormat->addButton ( Wav, 0 );
+ FileFormat->addButton ( Text, 1 );
+
+ if ( LocalSettings.DemoTypeNumber == 0 )
+ Wav->setChecked ( true );
+ else
+ Text->setChecked ( true );
+ Callsign->setText ( LocalSettings.callsign );
+ myLocator->setText ( LocalSettings.myLocator );
+ UTC->setValue ( LocalSettings.timeoffset );
+ SlashedZero->setAutoExclusive(false);
+ SlashedZero->setChecked ( LocalSettings.slashed0 );
+ autoCrLf->setAutoExclusive(false);
+ autoCrLf->setChecked(LocalSettings.autoCrLf);
+ QRegExp rx ( "^[A-R][A-R][0-9][0-9][A-X][A-X]$" );
+ QValidator *validator = new QRegExpValidator ( rx, this );
+ myLocator->setValidator ( validator );
+ myLocator->setText ( LocalSettings.myLocator );
+ Demomode->setChecked ( LocalSettings.DemoMode );
+ connect ( Demomode, SIGNAL ( clicked ( bool ) ), this, SLOT ( selectDemomode ( bool ) ) );
+ connect ( AvailableDevices, SIGNAL ( clicked ( const QModelIndex & ) ), this, SLOT ( setPTTDevice ( const QModelIndex & ) ) );
+
+ if ( Demomode->isChecked() )
+ FileFormatLayout->show();
+ else
+ FileFormatLayout->hide();
+
+//PTT
+ SelectedDevice->setText ( LocalSettings.SerialDevice );
+// First look in the /dev Directory
+ DirectoryName = "/dev/";
+
+ dir.setPath ( DirectoryName );
+ QStringList filenames;
+ filenames << "ttyS*";
+ QStringList Files = dir.entryList ( filenames, QDir::System | QDir::CaseSensitive, QDir::Name );
+
+ for ( int kk = 0; kk < Files.size(); kk++ )
+ Files.replace ( kk, DirectoryName + Files.at ( kk ) );
+ ReadOnlyStringListModel *m = new ReadOnlyStringListModel ( this );
+ m->setStringList ( Files );
+ AvailableDevices->setModel ( m );
+ AvailableDevices->show();
+// Now check for usb devices
+ /**
+ Directory="/dev/usb/tts/";
+ dir.setPath(Directory);
+ Files=dir.entryList(QDir::Files|QDir::System,QDir::Name);
+
+ for(QStringList::iterator Name=Files.begin();Name !=Files.end(); Name++)
+ AvailableDevices->insertItem(Directory + *Name);
+ **/
+//Logging
+ Directory->setText ( LocalSettings.Directory );
+ QsoFile->setText ( LocalSettings.QSOFileName );
+ fileLog->setChecked ( LocalSettings.fileLog );
+connect(fileLog,SIGNAL(clicked(bool)),this,SLOT(selectFileLogging(bool)));
+ Directory->setDisabled ( !LocalSettings.fileLog );
+ QsoFile->setDisabled ( !LocalSettings.fileLog );
+ LinLog->setChecked ( LocalSettings.LinLog );
+connect(LinLog,SIGNAL(clicked(bool)),this,SLOT(selectLinLogLogging(bool)));
+ Port->setDisabled ( !LocalSettings.LinLog );
+ Host->setDisabled ( !LocalSettings.LinLog );
+
+}
+
+
+GeneralSettings::~GeneralSettings()
+{}
+
+/*$SPECIALIZATION$*/
+
+
+Parameter GeneralSettings::getSettings()
+{
+ LocalSettings.callsign = Callsign->text();
+ LocalSettings.myLocator = myLocator->text();
+ if ( Demomode->isChecked() )
+ {
+ LocalSettings.DemoMode = true;
+ LocalSettings.DemoTypeNumber = FileFormat->checkedId();
+ LocalSettings.inputFilename = "";
+ }
+ else
+ LocalSettings.DemoMode = false;
+
+ LocalSettings.timeoffset = UTC->value();
+ if ( SlashedZero->isChecked() )
+ LocalSettings.slashed0 = true;
+ else
+ LocalSettings.slashed0 = false;
+ if ( autoCrLf->isChecked() )
+ LocalSettings.autoCrLf = true;
+ else
+ LocalSettings.autoCrLf = false;
+ LocalSettings.SerialDevice = SelectedDevice->text();
+ LocalSettings.fileLog = fileLog->isChecked();
+ if ( LocalSettings.fileLog )
+ {
+ LocalSettings.Directory = Directory->text();
+ LocalSettings.QSOFileName = QsoFile->text();
+ }
+
+ LocalSettings.LinLog = LinLog->isChecked();
+ if ( LocalSettings.LinLog )
+ {
+ LocalSettings.Host = Host->text();
+ LocalSettings.Port = Port->value();
+ }
+LocalSettings.dateFormat=dateFormat->currentText();
+ return LocalSettings;
+}
+
+void GeneralSettings::selectDemomode ( bool mode )
+{
+ if ( mode )
+ FileFormatLayout->show();
+ else
+ FileFormatLayout->hide();
+}
+
+void GeneralSettings::setPTTDevice ( const QModelIndex &index )
+{
+ QString s = index.data().toString();
+
+ SelectedDevice->clear();
+ SelectedDevice->setText ( s );
+ LocalSettings.SerialDevice = s;
+}
+
+void GeneralSettings::selectFileLogging ( bool b)
+{
+Directory->setDisabled ( !b);
+ QsoFile->setDisabled ( !b );
+}
+void GeneralSettings::selectLinLogLogging ( bool b )
+{
+ Port->setDisabled ( !b );
+ Host->setDisabled ( !b );
+}
+
diff --git a/gui/generalsettings.h b/gui/generalsettings.h
new file mode 100644
index 0000000..7344c4b
--- /dev/null
+++ b/gui/generalsettings.h
@@ -0,0 +1,53 @@
+/***************************************************************************
+ * Copyright (C) 2007 by volker, DL1KSV *
+ * schroer at tux64 *
+ * *
+ * 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 GENERALSETTINGS_H
+#define GENERALSETTINGS_H
+
+#include <QDialog>
+#include "ui_generalsettings.h"
+class Parameter;
+class QButtonGroup;
+class QModelIndex;
+class GeneralSettings : public QDialog, private Ui::GeneralSettings
+{
+ Q_OBJECT
+
+public:
+ GeneralSettings(QWidget* parent = 0, Qt::WFlags fl = 0 );
+ ~GeneralSettings();
+Parameter getSettings();
+
+public slots:
+ /*$PUBLIC_SLOTS$*/
+
+protected:
+QButtonGroup *FileFormat;
+ /*$PROTECTED_FUNCTIONS$*/
+Parameter LocalSettings;
+protected slots:
+void selectDemomode(bool);
+void setPTTDevice(const QModelIndex &);
+void selectFileLogging(bool);
+void selectLinLogLogging(bool);
+};
+
+#endif
+
diff --git a/gui/generalsettings.ui b/gui/generalsettings.ui
new file mode 100644
index 0000000..a442d09
--- /dev/null
+++ b/gui/generalsettings.ui
@@ -0,0 +1,512 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>GeneralSettings</class>
+ <widget class="QDialog" name="GeneralSettings">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>650</width>
+ <height>392</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>650</width>
+ <height>300</height>
+ </size>
+ </property>
+ <property name="baseSize">
+ <size>
+ <width>650</width>
+ <height>300</height>
+ </size>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::ClickFocus</enum>
+ </property>
+ <property name="windowTitle">
+ <string>LinPSK General Settings</string>
+ </property>
+ <property name="sizeGripEnabled">
+ <bool>true</bool>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="CallsignL">
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Plain</enum>
+ </property>
+ <property name="text">
+ <string>Callsign</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" colspan="2">
+ <widget class="QLineEdit" name="Callsign"/>
+ </item>
+ <item row="0" column="3">
+ <widget class="QLabel" name="UTCL">
+ <property name="text">
+ <string>Time Offset to UTC</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="4">
+ <widget class="QSpinBox" name="UTC">
+ <property name="minimum">
+ <number>-12</number>
+ </property>
+ <property name="maximum">
+ <number>12</number>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="5">
+ <spacer name="horizontalSpacer_6">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>178</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Locator</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" colspan="2">
+ <widget class="QLineEdit" name="myLocator"/>
+ </item>
+ <item row="1" column="3">
+ <widget class="QLabel" name="label_6">
+ <property name="text">
+ <string>Date Format</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="4">
+ <widget class="QComboBox" name="dateFormat">
+ <property name="whatsThis">
+ <string>describes the format displaying the date within qsodata </string>
+ </property>
+ <item>
+ <property name="text">
+ <string>dd.MM.yyyy</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>yyyy-MM-dd</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="1" column="5">
+ <spacer name="horizontalSpacer_7">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>178</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="2" column="4" colspan="2">
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>115</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="2" column="0" colspan="3">
+ <widget class="QRadioButton" name="SlashedZero">
+ <property name="font">
+ <font/>
+ </property>
+ <property name="text">
+ <string>Display Zero as Slashed Zero</string>
+ </property>
+ <property name="autoExclusive">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="3">
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>115</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="3" column="0" colspan="3">
+ <widget class="QRadioButton" name="autoCrLf">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Send CR LF on enter</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="3">
+ <spacer name="horizontalSpacer_4">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>129</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="3" column="4" colspan="2">
+ <spacer name="horizontalSpacer_5">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>283</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="4" column="0" colspan="2">
+ <widget class="QFrame" name="frame">
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QRadioButton" name="Demomode">
+ <property name="text">
+ <string>Demomode</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="FileFormatLayout">
+ <property name="title">
+ <string>Fileformat</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QRadioButton" name="Wav">
+ <property name="text">
+ <string>Wav</string>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="Text">
+ <property name="text">
+ <string>Text</string>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="4" column="2" colspan="2">
+ <widget class="QGroupBox" name="groupBox_2">
+ <property name="title">
+ <string>PTT Device</string>
+ </property>
+ <widget class="QListView" name="AvailableDevices">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>20</y>
+ <width>131</width>
+ <height>94</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="QLineEdit" name="SelectedDevice">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>120</y>
+ <width>131</width>
+ <height>21</height>
+ </rect>
+ </property>
+ </widget>
+ </widget>
+ </item>
+ <item row="4" column="4" colspan="2">
+ <widget class="QGroupBox" name="groupBox_3">
+ <property name="title">
+ <string>Logging</string>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <widget class="QRadioButton" name="fileLog">
+ <property name="text">
+ <string>Log to File</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <property name="autoExclusive">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Working Directory</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="Directory"/>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Filename</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="QsoFile">
+ <property name="text">
+ <string>QSO.adif</string>
+ </property>
+ <property name="cursorPosition">
+ <number>0</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <item>
+ <widget class="QRadioButton" name="LinLog">
+ <property name="text">
+ <string>Log to LinLog</string>
+ </property>
+ <property name="autoExclusive">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>LinLog Host Name</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="Host">
+ <property name="text">
+ <string>localhost</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>Port</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="Port">
+ <property name="minimum">
+ <number>1024</number>
+ </property>
+ <property name="maximum">
+ <number>64000</number>
+ </property>
+ <property name="value">
+ <number>8080</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="5" column="0" colspan="2">
+ <widget class="QPushButton" name="buttonOk">
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>20</height>
+ </size>
+ </property>
+ <property name="font">
+ <font/>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::ClickFocus</enum>
+ </property>
+ <property name="text">
+ <string>&Ok</string>
+ </property>
+ <property name="shortcut">
+ <string>Alt+O</string>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ <property name="default">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="2" colspan="2">
+ <widget class="QPushButton" name="buttonCancel">
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>20</height>
+ </size>
+ </property>
+ <property name="font">
+ <font/>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::ClickFocus</enum>
+ </property>
+ <property name="text">
+ <string>&Cancel</string>
+ </property>
+ <property name="shortcut">
+ <string/>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ <property name="default">
+ <bool>false</bool>
+ </property>
+ <property name="flat">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="4" colspan="2">
+ <spacer name="horizontalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>115</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <pixmapfunction>qPixmapFromMimeSource</pixmapfunction>
+ <tabstops>
+ <tabstop>Callsign</tabstop>
+ <tabstop>Demomode</tabstop>
+ <tabstop>Text</tabstop>
+ <tabstop>buttonOk</tabstop>
+ <tabstop>buttonCancel</tabstop>
+ </tabstops>
+ <includes>
+ <include location="local">parameter.h</include>
+ </includes>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonOk</sender>
+ <signal>clicked()</signal>
+ <receiver>GeneralSettings</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>buttonCancel</sender>
+ <signal>clicked()</signal>
+ <receiver>GeneralSettings</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/gui/gui.pro b/gui/gui.pro
new file mode 100644
index 0000000..3ba1598
--- /dev/null
+++ b/gui/gui.pro
@@ -0,0 +1,48 @@
+FORMS += addmacro.ui \
+addrxwindow.ui \
+deletemacro.ui \
+editmacro.ui \
+generalsettings.ui \
+modemenu.ui \
+qsodata.ui \
+renamemacro.ui
+
+CONFIG += build_all \
+ staticlib \
+ debug
+
+DESTDIR = .
+
+SOURCES += generalsettings.cpp \
+ addmacro.cpp \
+ addrxwindow.cpp \
+ deletemacro.cpp \
+ modemenu.cpp \
+ qsodata.cpp \
+ renamemacro.cpp \
+ editmacro.cpp
+
+HEADERS += generalsettings.h \
+ addmacro.h \
+ addrxwindow.h \
+ deletemacro.h \
+ modemenu.h \
+ qsodata.h \
+ renamemacro.h \
+ editmacro.h
+
+
+TEMPLATE = lib
+
+QMAKE_CXXFLAGS_DEBUG += -g3 \
+-O0
+QMAKE_CXXFLAGS_RELEASE += -O2
+
+
+CONFIG -= debug
+
+
+QT += network
+
+INCLUDEPATH += ../src
+
diff --git a/gui/modemenu.cpp b/gui/modemenu.cpp
new file mode 100644
index 0000000..83ee5e0
--- /dev/null
+++ b/gui/modemenu.cpp
@@ -0,0 +1,104 @@
+/***************************************************************************
+ * Copyright (C) 2007 by volker, DL1KSV *
+ * schroer at tux64 *
+ * *
+ * 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 "modemenu.h"
+#include "parameter.h"
+#include "crxchannel.h"
+
+extern Parameter settings;
+
+ModeMenu::ModeMenu(QWidget* parent, Qt::WFlags fl)
+: QDialog( parent, fl ), Ui::ModeMenu()
+{
+ setupUi(this);
+RxMode->insertItem(0,"BPSK");
+RxMode->insertItem(1,"QPSK");
+RxMode->insertItem(2,"RTTY");
+RxMode->insertItem(3,"MFSK16");
+
+RxMode->setCurrentRow(settings.ActChannel->getModulationType() );
+connect(RxMode,SIGNAL(itemSelectionChanged ()),this,SLOT(changeView()));
+Stopbits=new QButtonGroup(this);
+Stopbits->addButton(One,0);
+Stopbits->addButton(Onepoint5,1);
+Stopbits->addButton(Two,2);
+
+Parity=new QButtonGroup(this);
+Parity->addButton(None,0);
+Parity->addButton(Odd,1);
+Parity->addButton(Even,2);
+
+if ( settings.ActChannel->getModulationType() != RTTY)
+ {
+ ParityLayout->hide();
+ Spacing->hide();
+ Reverse->hide();
+ StopbitsLayout->hide();
+ }
+}
+
+ModeMenu::~ModeMenu()
+{
+}
+void ModeMenu::changeView()
+{
+int index=RxMode->currentRow();
+if ( index == RTTY )
+ {
+ ParityLayout->show();
+ Spacing->show();
+ Reverse->show();
+ StopbitsLayout->show();
+ }
+else
+ {
+ ParityLayout->hide();
+ Spacing->hide();
+ Reverse->hide();
+ StopbitsLayout->hide();
+
+ }
+}
+void ModeMenu::setParameter(ExtraParameter Param)
+{
+RTTYSpacing->setValue(Param.offset);
+/** FIXME
+Parity->setChecked(Param.parity);
+Stopbits->setChecked(Param.stopbits);
+**/
+Reverse->setChecked(Param.reverse);
+}
+ExtraParameter ModeMenu::getParameter()
+{
+ExtraParameter Param;
+
+Param.offset=RTTYSpacing->value();
+Param.reverse=Reverse->isChecked();
+Param.parity=(Paritaet) Parity->checkedId();
+Param.stopbits=(StopBits) Stopbits->checkedId();
+return Param;
+}
+Mode ModeMenu::selectedMode()
+{
+ return (Mode) RxMode->currentRow();
+}
+
+
diff --git a/gui/modemenu.h b/gui/modemenu.h
new file mode 100644
index 0000000..3f17b22
--- /dev/null
+++ b/gui/modemenu.h
@@ -0,0 +1,54 @@
+/***************************************************************************
+ * Copyright (C) 2007 by volker, DL1KSV *
+ * schroer at tux64 *
+ * *
+ * 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 MODEMENU_H
+#define MODEMENU_H
+
+#include <QDialog>
+#include "ui_modemenu.h"
+#include "constants.h"
+
+class QButtonGroup;
+
+class ModeMenu : public QDialog, private Ui::ModeMenu
+{
+ Q_OBJECT
+
+public:
+ ModeMenu(QWidget* parent = 0, Qt::WFlags fl = 0 );
+ ~ModeMenu();
+ /*$PUBLIC_FUNCTIONS$*/
+void setParameter(ExtraParameter Param);
+ExtraParameter getParameter();
+Mode selectedMode();
+public slots:
+ /*$PUBLIC_SLOTS$*/
+
+protected:
+
+QButtonGroup *Stopbits;
+QButtonGroup *Parity;
+protected slots:
+
+void changeView();
+};
+
+#endif
+
diff --git a/gui/modemenu.ui b/gui/modemenu.ui
new file mode 100644
index 0000000..36c41a0
--- /dev/null
+++ b/gui/modemenu.ui
@@ -0,0 +1,344 @@
+<ui version="4.0" >
+ <class>ModeMenu</class>
+ <widget class="QDialog" name="ModeMenu" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>350</width>
+ <height>250</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize" >
+ <size>
+ <width>350</width>
+ <height>250</height>
+ </size>
+ </property>
+ <property name="baseSize" >
+ <size>
+ <width>350</width>
+ <height>150</height>
+ </size>
+ </property>
+ <property name="windowTitle" >
+ <string>Change Rx Mode</string>
+ </property>
+ <property name="sizeGripEnabled" >
+ <bool>true</bool>
+ </property>
+ <widget class="QWidget" name="layout3" >
+ <property name="geometry" >
+ <rect>
+ <x>30</x>
+ <y>190</y>
+ <width>300</width>
+ <height>50</height>
+ </rect>
+ </property>
+ <layout class="QHBoxLayout" >
+ <item>
+ <widget class="QPushButton" name="buttonOk" >
+ <property name="minimumSize" >
+ <size>
+ <width>60</width>
+ <height>20</height>
+ </size>
+ </property>
+ <property name="text" >
+ <string>&OK</string>
+ </property>
+ <property name="shortcut" >
+ <string/>
+ </property>
+ <property name="autoDefault" >
+ <bool>true</bool>
+ </property>
+ <property name="default" >
+ <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" >
+ <size>
+ <width>110</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonCancel" >
+ <property name="minimumSize" >
+ <size>
+ <width>60</width>
+ <height>20</height>
+ </size>
+ </property>
+ <property name="text" >
+ <string>&Cancel</string>
+ </property>
+ <property name="shortcut" >
+ <string/>
+ </property>
+ <property name="autoDefault" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QRadioButton" name="Reverse" >
+ <property name="geometry" >
+ <rect>
+ <x>260</x>
+ <y>30</y>
+ <width>80</width>
+ <height>31</height>
+ </rect>
+ </property>
+ <property name="text" >
+ <string>Reverse</string>
+ </property>
+ <property name="checked" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QGroupBox" name="ParityLayout" >
+ <property name="geometry" >
+ <rect>
+ <x>250</x>
+ <y>90</y>
+ <width>91</width>
+ <height>91</height>
+ </rect>
+ </property>
+ <property name="title" >
+ <string>Parity</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignHCenter</set>
+ </property>
+ <widget class="QRadioButton" name="Odd" >
+ <property name="geometry" >
+ <rect>
+ <x>20</x>
+ <y>40</y>
+ <width>61</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text" >
+ <string>Odd</string>
+ </property>
+ <property name="buttonGroupId" stdset="0" >
+ <number>1</number>
+ </property>
+ </widget>
+ <widget class="QRadioButton" name="Even" >
+ <property name="geometry" >
+ <rect>
+ <x>20</x>
+ <y>60</y>
+ <width>60</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text" >
+ <string>Even</string>
+ </property>
+ <property name="buttonGroupId" stdset="0" >
+ <number>2</number>
+ </property>
+ </widget>
+ <widget class="QRadioButton" name="None" >
+ <property name="geometry" >
+ <rect>
+ <x>20</x>
+ <y>20</y>
+ <width>60</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text" >
+ <string>None</string>
+ </property>
+ <property name="checked" >
+ <bool>true</bool>
+ </property>
+ <property name="buttonGroupId" stdset="0" >
+ <number>0</number>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QListWidget" name="RxMode" >
+ <property name="geometry" >
+ <rect>
+ <x>10</x>
+ <y>30</y>
+ <width>121</width>
+ <height>151</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="QGroupBox" name="Spacing" >
+ <property name="geometry" >
+ <rect>
+ <x>140</x>
+ <y>19</y>
+ <width>91</width>
+ <height>61</height>
+ </rect>
+ </property>
+ <property name="title" >
+ <string>RTTY Spacing</string>
+ </property>
+ <widget class="QSpinBox" name="RTTYSpacing" >
+ <property name="enabled" >
+ <bool>true</bool>
+ </property>
+ <property name="geometry" >
+ <rect>
+ <x>10</x>
+ <y>20</y>
+ <width>80</width>
+ <height>30</height>
+ </rect>
+ </property>
+ <property name="suffix" >
+ <string> Hz</string>
+ </property>
+ <property name="minimum" >
+ <number>0</number>
+ </property>
+ <property name="maximum" >
+ <number>999</number>
+ </property>
+ <property name="value" >
+ <number>170</number>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QGroupBox" name="StopbitsLayout" >
+ <property name="geometry" >
+ <rect>
+ <x>140</x>
+ <y>90</y>
+ <width>101</width>
+ <height>91</height>
+ </rect>
+ </property>
+ <property name="title" >
+ <string>Stopbits</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignHCenter</set>
+ </property>
+ <widget class="QRadioButton" name="One" >
+ <property name="geometry" >
+ <rect>
+ <x>10</x>
+ <y>20</y>
+ <width>80</width>
+ <height>22</height>
+ </rect>
+ </property>
+ <property name="text" >
+ <string>1</string>
+ </property>
+ <property name="buttonGroupId" stdset="0" >
+ <number>0</number>
+ </property>
+ </widget>
+ <widget class="QRadioButton" name="Onepoint5" >
+ <property name="geometry" >
+ <rect>
+ <x>10</x>
+ <y>40</y>
+ <width>81</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text" >
+ <string>1.5</string>
+ </property>
+ <property name="checked" >
+ <bool>true</bool>
+ </property>
+ <property name="buttonGroupId" stdset="0" >
+ <number>1</number>
+ </property>
+ </widget>
+ <widget class="QRadioButton" name="Two" >
+ <property name="geometry" >
+ <rect>
+ <x>10</x>
+ <y>60</y>
+ <width>80</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text" >
+ <string>2</string>
+ </property>
+ <property name="buttonGroupId" stdset="0" >
+ <number>2</number>
+ </property>
+ </widget>
+ </widget>
+ </widget>
+ <layoutdefault spacing="6" margin="11" />
+ <pixmapfunction>qPixmapFromMimeSource</pixmapfunction>
+ <includes>
+ <include location="local" >constants.h</include>
+ </includes>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonOk</sender>
+ <signal>clicked()</signal>
+ <receiver>ModeMenu</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>buttonCancel</sender>
+ <signal>clicked()</signal>
+ <receiver>ModeMenu</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/gui/qsodata.cpp b/gui/qsodata.cpp
new file mode 100644
index 0000000..ae058f1
--- /dev/null
+++ b/gui/qsodata.cpp
@@ -0,0 +1,425 @@
+/***************************************************************************
+ * Copyright (C) 2007 by volker, DL1KSV *
+ * schroer at tux64 *
+ * *
+ * 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 "qsodata.h"
+#include "parameter.h"
+#include "crxchannel.h"
+#include "processlogdata.h"
+
+#include <QDateTime>
+#include <QFile>
+#include <QDir>
+#include <QTextStream>
+#include <QValidator>
+#include <QMessageBox>
+#include <QTcpSocket>
+
+extern Parameter settings;
+
+QSOData::QSOData ( QWidget* parent )
+ : QGroupBox ( parent ), Ui::QSOData()
+{
+ setupUi ( this );
+ QRegExp rx ( "^[A-R][A-R][0-9][0-9][A-X][A-X]$" );
+ validator = new QRegExpValidator ( rx, this );
+ Loc->setValidator ( validator );
+ Loc->setStyleSheet ( "QLineEdit{color: black ; }" );
+ Distance->setAlignment ( Qt::AlignRight );
+ QsoDate->setDisplayFormat ( settings.dateFormat );
+ refreshDateTime();
+ if ( settings.QslData )
+ {
+ RemoteCallsign->setText ( settings.QslData->RemoteCallsign );
+ OpName->setText ( settings.QslData->OpName );
+ Qth->setText ( settings.QslData->Qth );
+ Loc->setText ( settings.QslData->Locator );
+ QsoFrequency->setText ( settings.QslData->QsoFrequency );
+ HisRST->setText ( settings.QslData->HisRST );
+ MyRST->setText ( settings.QslData->MyRST );
+ }
+ if ( ! ( settings.fileLog || settings.LinLog ) )
+ Save->setDisabled ( true );
+ logBookCommunication = new ProcessLogData();
+ connectionError = false;
+ connect ( Clear, SIGNAL ( clicked() ), this, SLOT ( clear() ) );
+ connect ( Refresh, SIGNAL ( clicked() ), this, SLOT ( refreshDateTime() ) );
+ connect ( Qth, SIGNAL ( editingFinished () ), this, SLOT ( QTHchanged() ) );
+ connect ( QsoFrequency, SIGNAL ( editingFinished () ), this, SLOT ( Frequencychanged() ) );
+ connect ( MyRST, SIGNAL ( editingFinished () ), this, SLOT ( MyRSTchanged() ) );
+ connect ( OpName, SIGNAL ( editingFinished () ), this, SLOT ( Namechanged() ) );
+ connect ( Save, SIGNAL ( clicked() ), this, SLOT ( save() ) );
+ connect ( Loc, SIGNAL ( editingFinished () ), this, SLOT ( Locatorchanged() ) );
+ connect ( HisRST, SIGNAL ( editingFinished () ), this, SLOT ( HisRSTchanged() ) );
+ connect ( QsoDate, SIGNAL ( dateChanged ( const QDate & ) ), this, SLOT ( Datechanged() ) );
+ connect ( QsoTime, SIGNAL ( timeChanged ( const QTime & ) ), this, SLOT ( Timechanged() ) );
+
+
+ connect ( RemoteCallsign, SIGNAL ( editingFinished ( ) ), this, SLOT ( sendRequest() ) );
+ connect ( logBookCommunication, SIGNAL ( unabletoConnect() ), this , SLOT ( stopTrial() ) );
+ connect ( logBookCommunication, SIGNAL ( answerAvailable() ), this, SLOT ( copyAnswer() ) );
+}
+
+QSOData::~QSOData()
+{}
+
+
+void QSOData::clear()
+{
+ RemoteCallsign->setText ( "" );
+ settings.QslData->RemoteCallsign = RemoteCallsign->text();
+ OpName->setText ( "" );
+ settings.QslData->OpName = OpName->text();
+ Qth->setText ( "" );
+ settings.QslData->Qth = Qth->text();
+ Loc->setText ( "" );
+ settings.QslData->Locator = Loc->text();
+ QsoFrequency->setText ( "" );
+ settings.QslData->Locator = Loc->text();
+ HisRST->setText ( "" );
+ settings.QslData->HisRST = HisRST->text();
+ MyRST->setText ( "" );
+ settings.QslData->MyRST = MyRST->text();
+ Distance->setText ( "" );
+ continent->setText ( "" );
+ settings.QslData->continent = continent->text();
+ wazZone->setText ( "" );
+ settings.QslData->wazZone = wazZone->text();
+ ituZone->setText ( "" );
+ settings.QslData->ituZone = ituZone->text();
+ countryName->setText ( "" );
+ settings.QslData->countryName = countryName->text();
+ worked->setText ( "" );
+ settings.QslData->worked = worked->text();
+ mainPrefix->setText ( "" );
+ settings.QslData->mainPrefix = mainPrefix->text();
+ refreshDateTime();
+}
+
+void QSOData::Callsignchanged()
+{
+ settings.QslData->RemoteCallsign = RemoteCallsign->text();
+ RemoteCallsign->setModified ( true );
+ sendRequest();
+}
+
+void QSOData::Namechanged()
+{
+ settings.QslData->OpName = OpName->text();
+}
+
+void QSOData::QTHchanged()
+{
+ settings.QslData->Qth = Qth->text();
+
+}
+
+void QSOData::Locatorchanged()
+{
+ int i=0;
+ QString toCheck= Loc->text();
+ QValidator::State status=validator->validate(toCheck,i);
+ if(status==QValidator::Invalid)
+ Loc->setStyleSheet ( "QLineEdit{color: red ; }" );
+ else
+ {
+ Loc->setStyleSheet ( "QLineEdit{color: black ; }" );
+ settings.QslData->Locator = toCheck;
+ calculateDistance ( toCheck );
+ }
+}
+
+void QSOData::Frequencychanged()
+{
+ settings.QslData->QsoFrequency = QsoFrequency->text();
+}
+
+void QSOData::HisRSTchanged()
+{
+ settings.QslData->HisRST = HisRST->text();
+}
+
+void QSOData::MyRSTchanged()
+{
+ settings.QslData->MyRST = MyRST->text();
+}
+
+void QSOData::Datechanged()
+{
+ settings.QslData->QsoDate = QsoDate->date();
+}
+
+void QSOData::Timechanged()
+{
+ settings.QslData->QsoTime = QsoTime->time();
+}
+void QSOData::refreshDateTime()
+{
+ QDateTime t1;
+ QDateTime t;
+ t = QDateTime::currentDateTime();
+
+ t1 = t.addSecs ( settings.timeoffset * 3600 );
+
+ QsoDate->setDate ( t.date() );
+ QsoTime->setTime ( t1.time() );
+ if ( settings.QslData )
+ {
+ settings.QslData->QsoTime = QsoTime->time();
+ settings.QslData->QsoDate = QsoDate->date();
+ }
+}
+void QSOData::save()
+{
+ if ( ( ( settings.QSOFileName == "" ) && ( !settings.LinLog ) ) || connectionError )
+ return ; // No Filename specified, and no LinLog logging required
+// Get the most recent values
+ settings.QslData->RemoteCallsign = RemoteCallsign->text();
+ Namechanged(); // Later ?, not saved at the moment
+ QTHchanged();
+ Locatorchanged();
+ Frequencychanged();
+ HisRSTchanged();
+ MyRSTchanged();
+ Datechanged();
+ Timechanged();
+ QString saveString, s;
+
+ if ( RemoteCallsign->text().length() > 0 )
+ saveString = QString ( "<CALL:%1>%2\n" ).arg ( RemoteCallsign->text().length() ).arg ( RemoteCallsign->text() );
+
+ if ( settings.callsign != "" )
+ {
+ s = QString ( "<OPERATOR:%1>%2\n" ).arg ( settings.callsign.length() ).arg ( settings.callsign );
+ saveString.append ( s );
+ }
+ if ( !OpName->text().isEmpty() )
+ {
+ s = QString ( "<NAME:%1>%2\n" ).arg ( OpName->text().length() ).arg ( OpName->text() );
+ saveString.append ( s );
+ }
+ if ( Qth->text() != "" )
+ {
+ s = QString ( "<QTH:%1>%2\n" ).arg ( Qth->text().length() ).arg ( Qth->text() );
+ saveString.append ( s );
+ }
+ if ( Loc->text() != "" )
+ {
+ s = QString ( "<GRIDSQUARE:%1>%2\n" ).arg ( Loc->text().length() ).arg ( Loc->text() );
+ saveString.append ( s );
+ }
+ if ( QsoFrequency->text() != "" )
+ {
+ s = QString ( "<BAND:%1>%2\n" ).arg ( QsoFrequency->text().length() ).arg ( QsoFrequency->text() );
+ saveString.append ( s );
+ }
+ if ( QsoDate->text() == "" )
+ {
+ s = QString ( "<QSO_DATE:8:d>%1\n" ).arg ( QDateTime::currentDateTime().toString ( "yyyyMMdd" ) );
+ saveString.append ( s );
+ }
+ else
+ {
+ s = QString ( "<QSO_DATE:8:d>%1\n" ).arg ( QsoDate->date().toString ( "yyyyMMdd" ) );
+ saveString.append ( s );
+ }
+ if ( QsoTime->text() != "" )
+ {
+ s = QString ( "<TIME_ON:%1>%2\n" ).arg ( QsoTime->text().length() ).arg ( QsoTime->text().remove ( ':' ) );
+ saveString.append ( s );
+ }
+
+ if ( HisRST->text() != "" )
+ {
+ s = QString ( "<RST_RCVD:%1>%2\n" ).arg ( HisRST->text().length() ).arg ( HisRST->text() );
+ saveString.append ( s );
+ }
+ if ( MyRST->text() != "" )
+ {
+ s = QString ( "<RST_SENT:%1>%2\n" ).arg ( MyRST->text().length() ).arg ( MyRST->text() );
+ saveString.append ( s );
+ }
+ if ( settings.ActChannel != 0 )
+ {
+ s = QString ( "<MODE:" );
+ switch ( settings.ActChannel->getModulationType() )
+ {
+ case QPSK:
+ case BPSK:
+ s.append ( "5>PSK31\n" );
+ break;
+
+ case RTTY:
+ s.append ( "4>RTTY\n" );
+ break;
+
+ case MFSK16:
+ s.append ( "6>MFSK16\n" );
+ break;
+
+ default:
+ s.append ( "5>PSK31\n" );
+ }
+ saveString.append ( s );
+ }
+ saveString.append ( "<eor>\n" );
+ if ( settings.fileLog )
+ {
+ QDir d;
+ if ( !d.cd ( settings.Directory ) )
+ d.mkdir ( settings.Directory );
+ QFile f ( settings.Directory + "/" + settings.QSOFileName );
+ if ( !f.open ( QIODevice::WriteOnly | QIODevice::Append ) )
+ {
+ QMessageBox::information ( 0, "Saving to adif File", "Could not open file " + settings.QSOFileName );
+ return;
+ }
+
+ QTextStream stream ( &f );
+ stream << saveString ;
+ f.close();
+ }
+ if ( settings.LinLog )
+ {
+ if ( !logBookCommunication->isRunning() )
+ logBookCommunication->start();
+ qDebug ( "Written to Logbook\n%s", qPrintable ( saveString ) );
+ logBookCommunication->saveQsoData ( saveString );
+ }
+}
+
+void QSOData::calculateDistance ( QString loc )
+{
+ coordinates mine, his;
+ double dist;
+ if ( settings.myLocator.isEmpty() )
+ {
+ Distance->setText ( "" );
+ return;
+ }
+ if ( loc.length() != 6 )
+ return;
+ QString s ( "%1 km" );
+ mine = loc2coordinates ( settings.myLocator.constData() );
+ his = loc2coordinates ( loc.constData() );
+ dist = 6371. * acos ( sin ( mine.breite ) * sin ( his.breite ) + cos ( mine.breite ) * cos ( his.breite ) * cos ( mine.laenge - his.laenge ) );
+ Distance->setText ( s.arg ( ( int ) dist, 6 ) );
+}
+QSOData::coordinates QSOData::loc2coordinates ( const QChar *l )
+{
+ coordinates c;
+ c.laenge = ( 20. * ( l[0].toAscii() - 'A' ) + 2. * ( l[2].toAscii() - '0' ) + ( 1. / 12. ) * ( l[4].toAscii() - 'A' ) + 1. / 24. );
+ c.laenge *= M_PI / 180.;
+ c.breite = 90. - ( 10. * ( l[1].toAscii() - 'A' ) + 1. * ( l[3].toAscii() - '0' ) + ( 1. / 24. ) * ( l[5].toAscii() - 'A' ) + 1. / 48. );
+ c.breite *= M_PI / 180.;
+ return c;
+}
+
+void QSOData::copyCallSign ( QString s )
+{
+ RemoteCallsign->setText ( s );
+ Callsignchanged();
+}
+void QSOData::copyQTH ( QString s )
+{
+ Qth->setText ( s );
+ QTHchanged();
+}
+void QSOData::copyName ( QString s )
+{
+ OpName->setText ( s );
+ Namechanged();
+}
+void QSOData::copyLocator ( QString s )
+{
+ Loc->setText ( s.left(6).toUpper());
+ Locatorchanged();
+}
+void QSOData::copyRST ( QString s )
+{
+ HisRST->setText ( s );
+ HisRSTchanged();
+}
+void QSOData::newChannel()
+{
+ Distance->setText ( "" );
+ if ( settings.QslData )
+ {
+ RemoteCallsign->setText ( settings.QslData->RemoteCallsign );
+ OpName->setText ( settings.QslData->OpName );
+ Qth->setText ( settings.QslData->Qth );
+ Loc->setText ( settings.QslData->Locator );
+ Locatorchanged(); // Check Locator and set Color
+ QsoFrequency->setText ( settings.QslData->QsoFrequency );
+ HisRST->setText ( settings.QslData->HisRST );
+ MyRST->setText ( settings.QslData->MyRST );
+ QsoDate->setDate ( settings.QslData->QsoDate );
+ QsoTime->setTime ( settings.QslData->QsoTime );
+ mainPrefix->setText ( settings.QslData->mainPrefix );
+ continent->setText ( settings.QslData->continent );
+ wazZone->setText ( settings.QslData->wazZone );
+ ituZone->setText ( settings.QslData->ituZone );
+ countryName->setText ( settings.QslData->countryName );
+ worked->setText ( settings.QslData->worked );
+ }
+ else
+ clear();
+}
+
+void QSOData::sendRequest()
+{
+ bool test;
+ test = RemoteCallsign->isModified();
+ if ( test )
+ {
+ RemoteCallsign->setModified ( false ); //To avoid calling twice
+ settings.QslData->RemoteCallsign = RemoteCallsign->text();
+ }
+ if ( !settings.LinLog || connectionError || !test ) // No request to LinLogbook if disabled in the settings
+ return;
+ qDebug ( "Trying to request %s", qPrintable ( RemoteCallsign->text().toUpper() ) );
+ QLabel *results[6];
+ results[0] = mainPrefix;
+ results[1] = wazZone;
+ results[2] = ituZone;
+ results[3] = countryName;
+ results[4] = continent;
+ results[5] = worked;
+ if ( !logBookCommunication->isRunning() )
+ {
+ logBookCommunication->start();
+// qApp->processEvents ( QEventLoop::AllEvents, 100 );
+ }
+ logBookCommunication->requestCallSign ( results, RemoteCallsign->text().toUpper() );
+ qDebug ( "Request send" );
+}
+void QSOData::stopTrial()
+{
+ connectionError = true;
+}
+void QSOData::copyAnswer()
+{
+ settings.QslData->mainPrefix = mainPrefix->text();
+ settings.QslData->wazZone = wazZone->text();
+ settings.QslData->ituZone = ituZone->text();
+ settings.QslData->countryName = countryName->text();
+ settings.QslData->continent = continent->text();
+ settings.QslData->worked = worked->text();
+}
diff --git a/gui/qsodata.h b/gui/qsodata.h
new file mode 100644
index 0000000..b01abec
--- /dev/null
+++ b/gui/qsodata.h
@@ -0,0 +1,80 @@
+/***************************************************************************
+ * Copyright (C) 2007 by volker, DL1KSV *
+ * schroer at tux64 *
+ * *
+ * 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 QSODATA_H
+#define QSODATA_H
+
+#include <QGroupBox>
+#include "ui_qsodata.h"
+
+class QChar;
+class ProcessLogData;
+class QValidator;
+class QSOData : public QGroupBox, private Ui::QSOData
+{
+ Q_OBJECT
+struct coordinates
+{
+ double laenge;
+ double breite;
+};
+
+public:
+ QSOData(QWidget* parent = 0);
+ ~QSOData();
+ /*$PUBLIC_FUNCTIONS$*/
+
+public slots:
+ /*$PUBLIC_SLOTS$*/
+void Timechanged();
+void Datechanged();
+void MyRSTchanged();
+void HisRSTchanged();
+void Frequencychanged();
+void Locatorchanged();
+void QTHchanged();
+void Namechanged();
+void Callsignchanged();
+void clear();
+void refreshDateTime();
+void save();
+void calculateDistance(QString);
+
+void copyCallSign(QString);
+void copyQTH(QString);
+void copyName(QString);
+void copyLocator(QString);
+void copyRST(QString);
+void newChannel();
+protected:
+
+coordinates loc2coordinates ( const QChar *l );
+protected slots:
+void sendRequest();
+void stopTrial();
+void copyAnswer();
+private:
+ProcessLogData *logBookCommunication;
+bool connectionError;
+QValidator *validator;
+};
+
+#endif
+
diff --git a/gui/qsodata.ui b/gui/qsodata.ui
new file mode 100644
index 0000000..1f294e2
--- /dev/null
+++ b/gui/qsodata.ui
@@ -0,0 +1,1883 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>QSOData</class>
+ <widget class="QGroupBox" name="QSOData">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>420</width>
+ <height>264</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
+ <horstretch>2</horstretch>
+ <verstretch>1</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>240</width>
+ <height>200</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>600</width>
+ <height>800</height>
+ </size>
+ </property>
+ <property name="baseSize">
+ <size>
+ <width>190</width>
+ <height>180</height>
+ </size>
+ </property>
+ <property name="windowTitle">
+ <string>QSOData</string>
+ </property>
+ <property name="title">
+ <string>QsoData</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignHCenter</set>
+ </property>
+ <property name="flat">
+ <bool>false</bool>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <property name="leftMargin">
+ <number>7</number>
+ </property>
+ <property name="topMargin">
+ <number>3</number>
+ </property>
+ <property name="rightMargin">
+ <number>7</number>
+ </property>
+ <property name="bottomMargin">
+ <number>3</number>
+ </property>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Callsign</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="RemoteCallsign"/>
+ </item>
+ <item row="0" column="2">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Frequency</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3">
+ <widget class="QLineEdit" name="QsoFrequency"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Name</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="OpName"/>
+ </item>
+ <item row="1" column="2">
+ <widget class="QLabel" name="label_10">
+ <property name="text">
+ <string>QTH</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3">
+ <widget class="QLineEdit" name="Qth"/>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>RST received</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLineEdit" name="HisRST"/>
+ </item>
+ <item row="2" column="2">
+ <widget class="QLabel" name="label_11">
+ <property name="text">
+ <string>RST given</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="3">
+ <widget class="QLineEdit" name="MyRST"/>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>Date</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QDateEdit" name="QsoDate"/>
+ </item>
+ <item row="3" column="2">
+ <widget class="QLabel" name="label_12">
+ <property name="text">
+ <string>Time</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="3">
+ <widget class="QTimeEdit" name="QsoTime"/>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="label_6">
+ <property name="text">
+ <string>Locator</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QLineEdit" name="Loc">
+ <property name="sizeIncrement">
+ <size>
+ <width>0</width>
+ <height>1</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="2">
+ <widget class="QLabel" name="label_13">
+ <property name="text">
+ <string>Dist.</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="3">
+ <widget class="QLabel" name="Distance">
+ <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>255</red>
+ <green>255</green>
+ <blue>255</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>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </inactive>
+ <disabled>
+ <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>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </disabled>
+ </palette>
+ </property>
+ <property name="autoFillBackground">
+ <bool>true</bool>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Sunken</enum>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::NoTextInteraction</set>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0">
+ <widget class="QLabel" name="label_7">
+ <property name="text">
+ <string>Main Prefix</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="1">
+ <widget class="QLabel" name="mainPrefix">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</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>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="AlternateBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</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>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="AlternateBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </inactive>
+ <disabled>
+ <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>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="AlternateBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </disabled>
+ </palette>
+ </property>
+ <property name="autoFillBackground">
+ <bool>true</bool>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Sunken</enum>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::NoTextInteraction</set>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="2">
+ <widget class="QLabel" name="label_14">
+ <property name="text">
+ <string>Continent</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="0">
+ <widget class="QLabel" name="label_8">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Waz Zone</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="2">
+ <widget class="QLabel" name="label_15">
+ <property name="text">
+ <string>Itu Zone</string>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="0">
+ <widget class="QLabel" name="label_9">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Country</string>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="2">
+ <widget class="QLabel" name="label_16">
+ <property name="text">
+ <string>Worked</string>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="0">
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>72</width>
+ <height>22</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="8" column="1">
+ <widget class="QPushButton" name="Save">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Save</string>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="2">
+ <widget class="QPushButton" name="Refresh">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Refresh</string>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="3">
+ <widget class="QPushButton" name="Clear">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Clear</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="3">
+ <widget class="QLabel" name="continent">
+ <property name="palette">
+ <palette>
+ <active>
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </active>
+ <inactive>
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </inactive>
+ <disabled>
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>233</red>
+ <green>232</green>
+ <blue>232</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </disabled>
+ </palette>
+ </property>
+ <property name="autoFillBackground">
+ <bool>true</bool>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Sunken</enum>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::NoTextInteraction</set>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="1">
+ <widget class="QLabel" name="wazZone">
+ <property name="palette">
+ <palette>
+ <active>
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </active>
+ <inactive>
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </inactive>
+ <disabled>
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </disabled>
+ </palette>
+ </property>
+ <property name="autoFillBackground">
+ <bool>true</bool>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Sunken</enum>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::NoTextInteraction</set>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="3">
+ <widget class="QLabel" name="ituZone">
+ <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>255</red>
+ <green>255</green>
+ <blue>255</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>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>127</red>
+ <green>127</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>170</red>
+ <green>170</green>
+ <blue>170</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>255</red>
+ <green>255</green>
+ <blue>255</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>255</red>
+ <green>255</green>
+ <blue>255</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>255</red>
+ <green>255</green>
+ <blue>255</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>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>127</red>
+ <green>127</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>170</red>
+ <green>170</green>
+ <blue>170</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>255</red>
+ <green>255</green>
+ <blue>255</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>255</red>
+ <green>255</green>
+ <blue>255</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>127</red>
+ <green>127</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Button">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</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>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>127</red>
+ <green>127</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>170</red>
+ <green>170</green>
+ <blue>170</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>127</red>
+ <green>127</green>
+ <blue>127</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>127</red>
+ <green>127</green>
+ <blue>127</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>255</red>
+ <green>255</green>
+ <blue>255</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>255</red>
+ <green>255</green>
+ <blue>255</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="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Sunken</enum>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::NoTextInteraction</set>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="1">
+ <widget class="QLabel" name="countryName">
+ <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>255</red>
+ <green>255</green>
+ <blue>255</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>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>127</red>
+ <green>127</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>170</red>
+ <green>170</green>
+ <blue>170</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>255</red>
+ <green>255</green>
+ <blue>255</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>255</red>
+ <green>255</green>
+ <blue>255</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>255</red>
+ <green>255</green>
+ <blue>255</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>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>127</red>
+ <green>127</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>170</red>
+ <green>170</green>
+ <blue>170</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>255</red>
+ <green>255</green>
+ <blue>255</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>255</red>
+ <green>255</green>
+ <blue>255</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>127</red>
+ <green>127</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Button">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</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>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>127</red>
+ <green>127</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>170</red>
+ <green>170</green>
+ <blue>170</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>127</red>
+ <green>127</green>
+ <blue>127</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>127</red>
+ <green>127</green>
+ <blue>127</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>255</red>
+ <green>255</green>
+ <blue>255</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>255</red>
+ <green>255</green>
+ <blue>255</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="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Sunken</enum>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="3">
+ <widget class="QLabel" name="worked">
+ <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>255</red>
+ <green>255</green>
+ <blue>255</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>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>127</red>
+ <green>127</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>170</red>
+ <green>170</green>
+ <blue>170</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>255</red>
+ <green>255</green>
+ <blue>255</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>255</red>
+ <green>255</green>
+ <blue>255</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>255</red>
+ <green>255</green>
+ <blue>255</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>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>127</red>
+ <green>127</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>170</red>
+ <green>170</green>
+ <blue>170</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>255</red>
+ <green>255</green>
+ <blue>255</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>255</red>
+ <green>255</green>
+ <blue>255</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>127</red>
+ <green>127</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Button">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</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>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>127</red>
+ <green>127</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>170</red>
+ <green>170</green>
+ <blue>170</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>127</red>
+ <green>127</green>
+ <blue>127</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>127</red>
+ <green>127</green>
+ <blue>127</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>255</red>
+ <green>255</green>
+ <blue>255</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>255</red>
+ <green>255</green>
+ <blue>255</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="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Sunken</enum>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/gui/renamemacro.cpp b/gui/renamemacro.cpp
new file mode 100644
index 0000000..0dbd007
--- /dev/null
+++ b/gui/renamemacro.cpp
@@ -0,0 +1,61 @@
+/***************************************************************************
+ * Copyright (C) 2007 by volker, DL1KSV *
+ * schroer at tux64 *
+ * *
+ * 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 "renamemacro.h"
+#include "macros.h"
+#include "readonlystringlistmodel.h"
+#include <QMessageBox>
+
+RenameMacro::RenameMacro(Macros *M,QWidget* parent, Qt::WFlags fl)
+: QDialog( parent, fl ), Ui::RenameMacro()
+{
+ setupUi(this);
+model=new ReadOnlyStringListModel();
+model->setStringList(M->getMacroList());
+AllMacros=M;
+MacroBox->setModel(model);
+connect(MacroBox,SIGNAL(clicked(const QModelIndex &)),this,SLOT(selectMacro(const QModelIndex &)));
+}
+
+RenameMacro::~RenameMacro()
+{
+}
+
+
+void RenameMacro::accept()
+{
+if (NewName->text().length() ==0 )
+ {
+ QMessageBox::warning(this,
+ "Error", "New Name of Macro is missing. \n Enter new Name of Macro",QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
+ return;
+ }
+else
+ AllMacros->setMacroName(NewName->text(),MacroNumber);
+ QDialog::accept();
+}
+
+void RenameMacro::selectMacro(const QModelIndex &index)
+{
+MacroNumber=index.row();
+OldName->setText(index.data().toString());
+}
+
diff --git a/gui/renamemacro.h b/gui/renamemacro.h
new file mode 100644
index 0000000..1cbe6d3
--- /dev/null
+++ b/gui/renamemacro.h
@@ -0,0 +1,53 @@
+/***************************************************************************
+ * Copyright (C) 2007 by volker, DL1KSV *
+ * schroer at tux64 *
+ * *
+ * 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 RENAMEMACRO_H
+#define RENAMEMACRO_H
+
+#include <QDialog>
+#include "ui_renamemacro.h"
+
+class Macros;
+class ReadOnlyStringListModel;
+
+class RenameMacro : public QDialog, private Ui::RenameMacro
+{
+ Q_OBJECT
+
+public:
+ RenameMacro(Macros *M,QWidget* parent = 0, Qt::WFlags fl = 0 );
+ ~RenameMacro();
+ /*$PUBLIC_FUNCTIONS$*/
+
+public slots:
+ /*$PUBLIC_SLOTS$*/
+
+protected:
+ReadOnlyStringListModel *model;
+Macros *AllMacros;
+int MacroNumber;
+protected slots:
+ /*$PROTECTED_SLOTS$*/
+ virtual void accept();
+void selectMacro(const QModelIndex &);
+};
+
+#endif
+
diff --git a/gui/renamemacro.ui b/gui/renamemacro.ui
new file mode 100644
index 0000000..56b2c12
--- /dev/null
+++ b/gui/renamemacro.ui
@@ -0,0 +1,227 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>RenameMacro</class>
+ <widget class="QDialog" name="RenameMacro">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>460</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>400</width>
+ <height>200</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>500</width>
+ <height>400</height>
+ </size>
+ </property>
+ <property name="windowTitle">
+ <string>Rename Macro</string>
+ </property>
+ <property name="sizeGripEnabled">
+ <bool>true</bool>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="MHeader">
+ <property name="minimumSize">
+ <size>
+ <width>160</width>
+ <height>30</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Select Macro</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" colspan="2">
+ <widget class="QLabel" name="OName">
+ <property name="minimumSize">
+ <size>
+ <width>150</width>
+ <height>30</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Old Name</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" rowspan="4">
+ <widget class="QListView" name="MacroBox">
+ <property name="minimumSize">
+ <size>
+ <width>160</width>
+ <height>130</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" colspan="2">
+ <widget class="QLineEdit" name="OldName">
+ <property name="minimumSize">
+ <size>
+ <width>150</width>
+ <height>30</height>
+ </size>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2">
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>102</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="3" column="1" colspan="2">
+ <widget class="QLabel" name="NName">
+ <property name="minimumSize">
+ <size>
+ <width>150</width>
+ <height>30</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>New Name</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1" colspan="2">
+ <widget class="QLineEdit" name="NewName">
+ <property name="minimumSize">
+ <size>
+ <width>150</width>
+ <height>30</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0" colspan="2">
+ <layout class="QHBoxLayout">
+ <item>
+ <widget class="QPushButton" name="buttonOk">
+ <property name="text">
+ <string>&OK</string>
+ </property>
+ <property name="shortcut">
+ <string/>
+ </property>
+ <property name="autoDefault">
+ <bool>true</bool>
+ </property>
+ <property name="default">
+ <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>120</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonCancel">
+ <property name="text">
+ <string>&Cancel</string>
+ </property>
+ <property name="shortcut">
+ <string/>
+ </property>
+ <property name="autoDefault">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="5" column="2">
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>141</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <pixmapfunction>qPixmapFromMimeSource</pixmapfunction>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonOk</sender>
+ <signal>clicked()</signal>
+ <receiver>RenameMacro</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>buttonCancel</sender>
+ <signal>clicked()</signal>
+ <receiver>RenameMacro</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/images/linpsk.png b/images/linpsk.png
new file mode 100644
index 0000000..c37fa0c
Binary files /dev/null and b/images/linpsk.png differ
diff --git a/linpsk.pro b/linpsk.pro
new file mode 100644
index 0000000..067e769
--- /dev/null
+++ b/linpsk.pro
@@ -0,0 +1,23 @@
+CONFIG += warn_on \
+ qt \
+ thread \
+ ordered \
+ debug
+DESTDIR = .
+
+SUBDIRS += gui \
+ src
+
+
+
+CONFIG -= debug
+
+QT += network
+
+
+TEMPLATE = subdirs
+
+LIBS += gui/libgui.a
+
+TARGETDEPS += gui/libgui.a \
+src/../bin/linpsk
diff --git a/src/application.qrc b/src/application.qrc
new file mode 100644
index 0000000..32def66
--- /dev/null
+++ b/src/application.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+<file>../images/linpsk.png</file>
+</qresource>
+</RCC>
diff --git a/src/bpskdemodulator.cpp b/src/bpskdemodulator.cpp
new file mode 100644
index 0000000..82a67c7
--- /dev/null
+++ b/src/bpskdemodulator.cpp
@@ -0,0 +1,118 @@
+/***************************************************************************
+ bpskdemodulator.cpp - description
+ -------------------
+ begin : Sat Jun 2 2001
+ copyright : (C) 2001 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * based on the work of Moe Wheatly, AE4JY *
+ ***************************************************************************/
+
+#include "bpskdemodulator.h"
+
+BPskDemodulator::BPskDemodulator():CPskDemodulator()
+{
+ave1=1.0;
+ave2=1.0;
+
+}
+BPskDemodulator::~BPskDemodulator(){
+}
+void BPskDemodulator::DecodeSymbol(double angle)
+
+{
+
+bool bit;
+
+char ch =0;
+ CalcQuality(angle);
+ bit = GetBPSKSymb();
+
+ if( (bit==0) && m_LastBitZero ) //if character delimiter
+ {
+ if(m_BitAcc != 0 )
+ {
+ m_BitAcc >>= 2; //get rid of last zero and one
+ m_BitAcc &= 0x07FF;
+ ch = m_VaricodeDecTbl[m_BitAcc];
+ m_BitAcc = 0;
+ if( (ch!=0) &&
+ ( !Squelch || (Squelch && (fastSquelch || ( ( unsigned int ) m_DevAve > Threshold ))))) // Squelch Part
+ {
+ emit newSymbol(ch);
+ if (fastSquelch && (( unsigned int ) m_DevAve < Threshold) )
+ fastSquelch = false;
+ }
+ }
+ }
+ else
+ {
+ m_BitAcc <<= 1;
+ m_BitAcc |= bit;
+ if(bit==0)
+ m_LastBitZero = true;
+ else
+ m_LastBitZero = false;
+ }
+
+ if (bit)
+ {
+ m_OffCount=0;
+ if (m_OnCount++ >20)
+ fastSquelch=true;
+
+ }
+ else
+ {
+ m_OnCount=0;
+ if (m_OffCount++ > 20)
+ fastSquelch=false;
+ }
+
+
+}
+bool BPskDemodulator::GetBPSKSymb()
+{
+return (Phase_Vector.real()> 0.0);
+}
+
+//////////////////////////////////////////////////////////////////////
+// Calculate signal quality based on the statistics of the phase
+// difference angle. The more dispersion of the "0" and "180" degree
+// phase shifts, the worse the signal quality. This information is used
+// to activate the squelch control. If 20 consecutive "180" degree shifts
+// occur, the squelch is forced on, and if 20 consecutive "0" degree
+// shifts occur, the squelch is forced off quickly.
+//////////////////////////////////////////////////////////////////////
+
+void BPskDemodulator::CalcQuality( double angle )
+{
+
+double temp;
+
+
+if ( fabs(angle) < M_PI_2)
+ temp= angle;
+else
+ {
+ if ( angle > 0.0)
+ temp=angle-M_PI;
+ else
+ temp = M_PI+ angle;
+ }
+ m_QFreqError = -temp;
+ temp = fabs(temp);
+ m_DevAve =0.5 * ave1 + 0.45 * ave2 + 0.05 *temp;
+ave2=ave1;
+ave1=m_DevAve;
+// And now norm m_DevAve for use in Squelch
+m_DevAve = 100. -m_DevAve *63.67;
+
+}
diff --git a/src/bpskdemodulator.h b/src/bpskdemodulator.h
new file mode 100644
index 0000000..969c30e
--- /dev/null
+++ b/src/bpskdemodulator.h
@@ -0,0 +1,46 @@
+/***************************************************************************
+ bpskdemodulator.h - description
+ -------------------
+ begin : Sat Jun 2 2001
+ copyright : (C) 2001 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * based on the work of Moe Wheatley, AE4JY *
+ ***************************************************************************/
+
+#ifndef BPSKDEMODULATOR_H
+#define BPSKDEMODULATOR_H
+
+#include <complex>
+#include "cpskdemodulator.h"
+
+
+/**Implementation of the BPSK Demodulator
+ *@author Volker Schroer
+ */
+
+class BPskDemodulator : public CPskDemodulator {
+public:
+ BPskDemodulator();
+ ~BPskDemodulator();
+protected:
+/** Decodes a BPSK Symbol */
+void DecodeSymbol( double);
+
+void CalcQuality(double);
+private:
+ bool GetBPSKSymb();
+ double ave1;
+ double ave2;
+
+
+};
+
+#endif
diff --git a/src/bpskmodulator.cpp b/src/bpskmodulator.cpp
new file mode 100644
index 0000000..1863479
--- /dev/null
+++ b/src/bpskmodulator.cpp
@@ -0,0 +1,83 @@
+/***************************************************************************
+ bpskmodulator.cpp - description
+ -------------------
+ begin : Mon Feb 24 2003
+ copyright : (C) 2003 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * The PSK part is based on WinPSK 1.0 by Moe Wheatly, AE4JY *
+ ***************************************************************************/
+
+#include "bpskmodulator.h"
+#include "constants.h"
+
+#define SYM_NOCHANGE 0 //Stay the same phase
+#define SYM_P180 2 //Plus 180 deg
+#define SYM_OFF 4 //No output
+#define SYM_ON 5 //constant output
+
+BPSKModulator::BPSKModulator ( int FS, double freq, CTxBuffer *TxBuffer ) : PSKModulator ( FS, freq, TxBuffer )
+{
+}
+BPSKModulator::~BPSKModulator()
+{
+}
+char BPSKModulator::GetNextSymbol ( void )
+{
+ char symb;
+ int ch;
+ symb = m_Lastsymb;
+ if ( m_TxShiftReg == 0 )
+ {
+ if ( m_AddEndingZero ) // if is end of code
+ {
+ symb = SYM_P180; // end with a zero
+ m_AddEndingZero = false;
+ }
+ else
+ {
+ ch = GetChar(); //get next character to xmit
+ if ( ch >= 0 ) //if is not a control code
+ {
+ //get next VARICODE codeword to send
+ m_TxShiftReg = VARICODE_TABLE[ ch&0xFF ];
+ symb = SYM_P180; //Start with a zero
+ }
+ else // is a control code
+ {
+ switch ( ch )
+ {
+ case TXON_CODE:
+ symb = SYM_ON;
+ break;
+ case TXTOG_CODE:
+ symb = SYM_P180;
+ break;
+ case TXOFF_CODE:
+ symb = SYM_OFF;
+ break;
+ }
+ }
+ }
+ }
+ else // is not end of code word so send next bit
+ {
+ if ( m_TxShiftReg&0x8000 )
+ symb = SYM_NOCHANGE;
+ else
+ symb = SYM_P180;
+ m_TxShiftReg = m_TxShiftReg << 1; //point to next bit
+ if ( m_TxShiftReg == 0 ) // if at end of codeword
+ m_AddEndingZero = true; // need to send a zero nextime
+ }
+ m_Lastsymb = symb;
+ return symb;
+
+}
diff --git a/src/bpskmodulator.h b/src/bpskmodulator.h
new file mode 100644
index 0000000..9d52714
--- /dev/null
+++ b/src/bpskmodulator.h
@@ -0,0 +1,36 @@
+/***************************************************************************
+ bpskmodulator.h - description
+ -------------------
+ begin : Mon Feb 24 2003
+ copyright : (C) 2003 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * The PSK part is based on WinPSK 1.0 by Moe Wheatley, AE4JY *
+ ***************************************************************************/
+
+#ifndef BPSKMODULATOR_H
+#define BPSKMODULATOR_H
+
+#include "pskmodulator.h"
+
+class CTxBuffer;
+/**
+ *@author Volker Schroer
+ */
+
+class BPSKModulator : public PSKModulator
+ {
+public:
+ BPSKModulator(int, double, CTxBuffer *);
+ ~BPSKModulator();
+char GetNextSymbol(void);
+};
+
+#endif
diff --git a/src/cdemodulator.cpp b/src/cdemodulator.cpp
new file mode 100644
index 0000000..ecafe91
--- /dev/null
+++ b/src/cdemodulator.cpp
@@ -0,0 +1,101 @@
+/***************************************************************************
+ cdemodulator.cpp - description
+ -------------------
+ begin : Sat Jun 2 2001
+ copyright : (C) 2001 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#include "cdemodulator.h"
+
+CDemodulator::CDemodulator()
+{
+UseAfc = Off;
+Squelch = true;
+Threshold= 50;
+}
+
+CDemodulator::~CDemodulator()
+{
+}
+
+void CDemodulator::setAfcMode(AfcMode afc) { UseAfc=afc; }
+
+void CDemodulator::setRxFrequency(double freq)
+{
+ if ( (freq > 200 ) && (freq < 3000 ) )
+ RxFrequency = freq;
+ else
+ {
+ printf("Invalid Frequency %f\n",freq);
+ return;
+ }
+}
+
+double CDemodulator::getRxFrequency(void)
+{
+return RxFrequency;
+}
+
+void CDemodulator::setThreshold(int value)
+{
+Threshold= value;
+}
+
+void CDemodulator::setSquelch(bool OnOff)
+{
+Squelch=OnOff;
+}
+
+AfcMode CDemodulator::getAfcMode()
+{
+return UseAfc;
+}
+bool CDemodulator::getSquelchState()
+{
+return Squelch;
+}
+std::complex<float> * CDemodulator::getPhasePointer()
+{
+return 0;
+}
+int CDemodulator::getThreshold()
+{
+return Threshold;
+}
+double CDemodulator::get2RxFrequency(void)
+{
+return 0.0;
+}
+float CDemodulator::getIMD()
+{
+return 0.0;
+}
+
+ void CDemodulator::setParameter(RxTxParameterType,void *)
+ {
+ /**
+ * At the moment only RTTY uses some extra Parameters
+ * So there is mostly nothing to do
+ * but that may change in the future
+ **/
+ return;
+ }
+ void *CDemodulator::getParameter(RxTxParameterType)
+ {
+ return 0;
+ }
+ void *CDemodulator::getBuffer()
+ {
+ return 0;
+ }
+
+
diff --git a/src/cdemodulator.h b/src/cdemodulator.h
new file mode 100644
index 0000000..fdc38ab
--- /dev/null
+++ b/src/cdemodulator.h
@@ -0,0 +1,85 @@
+/***************************************************************************
+ cdemodulator.h - description
+ -------------------
+ begin : Sat Jun 2 2001
+ copyright : (C) 2001 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifndef CDEMODULATOR_H
+#define CDEMODULATOR_H
+
+#include <qobject.h>
+#include <complex>
+#include <cstdio>
+#include "constants.h"
+/**Base class for all possible types of demodulators
+ *@author Volker Schroer
+ */
+class CDemodulator : public QObject
+ {
+ Q_OBJECT
+public:
+
+ CDemodulator();
+
+ virtual ~CDemodulator();
+ /** processes the input */
+ virtual void ProcessInput(double *input, double *spectrum) = 0;
+ /** gets the selected frequency */
+ virtual double getRxFrequency(void);
+ virtual double get2RxFrequency(void);
+ /** Initialises something */
+ virtual bool Init(double,int) = 0;
+ virtual std::complex<float> *getPhasePointer();
+ virtual int getSquelchValue() = 0;
+ virtual AfcMode getAfcMode();
+ virtual AfcMode AfcProperties() = 0;
+ void setAfcMode(AfcMode);
+ virtual bool getSquelchState();
+ virtual int getThreshold();
+ virtual float getIMD();
+ virtual void setParameter(RxTxParameterType,void *);
+ virtual void *getParameter(RxTxParameterType);
+ virtual void *getBuffer();
+protected:
+/** Status of AFC */
+ AfcMode UseAfc;
+ /** Status of Squelch **/
+ bool Squelch;
+ unsigned int Threshold;
+ /** Frequency to be received */
+ double RxFrequency;
+
+ /** Number of Samples **/
+ int NxSamples;
+ /** Oszilatorfrequency **/
+ double OszFrequency;
+ /** Increment of Oszilator Frequency **/
+ double OszFreqinc;
+ /** Sample Rate **/
+ double SampleRate;
+
+public slots: //Slots
+ /** enables/ disables the use of AFC */
+ /** sets the frequency for the demodulator */
+ virtual void setRxFrequency(double);
+ void setThreshold(int);
+ void setSquelch(bool);
+
+
+signals: // Signals
+ /** Signal will be emitted if a new character was detected */
+ void newSymbol(char);
+
+};
+
+#endif
diff --git a/src/cledbutton.cpp b/src/cledbutton.cpp
new file mode 100644
index 0000000..ce1f816
--- /dev/null
+++ b/src/cledbutton.cpp
@@ -0,0 +1,93 @@
+/***************************************************************************
+ cledbutton.cpp - description
+ -------------------
+ begin : Sun Jan 14 2001
+ copyright : (C) 2001 by Volker Schroer
+ email : DL1KSV at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#include "cledbutton.h"
+
+#include <qpainter.h>
+
+CLedButton::CLedButton(QWidget *parent) : QPushButton(parent)
+{
+status=UNDEF;
+setText("RX");
+setFlat(false);
+connect(this,SIGNAL ( clicked() ),this,SLOT(rxtx()));
+}
+CLedButton::~CLedButton(){
+}
+/** paint the button and the led in it */
+void CLedButton::paintEvent(QPaintEvent *e)
+{
+QPushButton::paintEvent(e);
+QPainter paint(this);
+
+
+//drawButton(&paint);
+switch (status)
+ {
+ case ON:
+ paint.setPen(Qt::black);
+ paint.setBrush(Qt::red);
+ paint.drawEllipse(4,4,14,14);
+ break;
+ case OFF:
+ paint.setPen(Qt::black);
+ paint.setBrush(Qt::green);
+ paint.drawEllipse(4,4,14,14);
+ break;
+ case UNDEF:
+ paint.setPen(Qt::black);
+ paint.setBrush(Qt::yellow);
+ paint.drawEllipse(4,4,14,14);
+ break;
+ }
+//paint.drawText(4,height()-5,text());
+}
+/** sets the buttonstatus */
+void CLedButton::setStatus(BUTTONSTATUS state)
+{
+status=state;
+switch(status)
+ {
+ case UNDEF:
+ case ON:
+ setText("RX");
+ break;
+ case OFF:
+ setText("TX");
+ break;
+ }
+repaint();
+}
+/** No descriptions */
+void CLedButton::rxtx()
+{
+switch(status)
+ {
+ case UNDEF:
+ case ON:
+// setStatus(OFF);
+ emit startRx();
+ break;
+ case OFF:
+// setStatus(ON);
+ emit startTx();
+ break;
+ }
+}
+BUTTONSTATUS CLedButton::getstatus()
+{
+return status;
+}
diff --git a/src/cledbutton.h b/src/cledbutton.h
new file mode 100644
index 0000000..9395783
--- /dev/null
+++ b/src/cledbutton.h
@@ -0,0 +1,51 @@
+/***************************************************************************
+ cledbutton.h - description
+ -------------------
+ begin : Sun Jan 14 2001
+ copyright : (C) 2001 by Volker Schroer
+ email : DL1KSV at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifndef CLEDBUTTON_H
+#define CLEDBUTTON_H
+
+#include <qpushbutton.h>
+/**Constucts a pushbutton with a led in it
+ *@author Volker Schroer
+ */
+enum BUTTONSTATUS
+{
+UNDEF, // undefined
+ON, // TX
+OFF // RX
+};
+class CLedButton : public QPushButton {
+ Q_OBJECT
+public:
+ CLedButton(QWidget *parent=0);
+ ~CLedButton();
+ /** paint the button and the led in it */
+ void paintEvent(QPaintEvent *e);
+ /** sets the buttonstatus */
+ void setStatus(BUTTONSTATUS state);
+BUTTONSTATUS getstatus();
+private:
+BUTTONSTATUS status;
+private slots: // Private slots
+ /** No descriptions */
+ void rxtx();
+
+signals:
+void startRx();
+void startTx();
+};
+
+#endif
diff --git a/src/cmodulator.cpp b/src/cmodulator.cpp
new file mode 100644
index 0000000..ff36f69
--- /dev/null
+++ b/src/cmodulator.cpp
@@ -0,0 +1,38 @@
+/***************************************************************************
+ cmodulator.cpp - description
+ -------------------
+ begin : Mon Aug 20 2001
+ copyright : (C) 2001 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ ****************************************************************************/
+
+#include "cmodulator.h"
+
+CModulator::CModulator(int FS,CTxBuffer *TxBuffer)
+{
+
+SampleRate=FS;
+Buffer=TxBuffer;
+
+}
+CModulator::~CModulator()
+{
+}
+
+void CModulator::setParameter(RxTxParameterType,void *)
+{
+ /**
+ * At the moment only RTTY uses some extra Parameters
+ * So there is mostly nothing to do
+ * but that may change in the future
+ **/
+ return;
+}
diff --git a/src/cmodulator.h b/src/cmodulator.h
new file mode 100644
index 0000000..4873b19
--- /dev/null
+++ b/src/cmodulator.h
@@ -0,0 +1,59 @@
+/***************************************************************************
+ cmodulator.h - description
+ -------------------
+ begin : Mon Aug 20 2001
+ copyright : (C) 2001 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifndef CMODULATOR_H
+#define CMODULATOR_H
+
+#include <qobject.h>
+#include "parameter.h"
+#include "constants.h"
+
+
+/**Base Class for all possible transmit types
+ *@author Volker Schroer
+ */
+
+class CTxBuffer;
+
+class CModulator : public QObject
+{
+Q_OBJECT
+public:
+ CModulator(int FS,CTxBuffer *);
+ ~CModulator();
+ virtual void setParameter(RxTxParameterType,void *);
+
+/** Calculate the Signal to be fed into the soundcard */
+ virtual int CalcSignal(double *data,int BufferSize) = 0;
+/** data Pointer to the computed signal values
+ Size of Buffer for the computed signal
+ returns Number of computed signal values and -Number at the end of Transmission
+ **/
+
+protected: // Protected attributes
+ /** Samplerate of Soundcard */
+ unsigned int SampleRate;
+ CTxBuffer *Buffer;
+
+
+public slots:
+
+signals:
+void charSend(char);
+
+};
+
+#endif
diff --git a/src/color.h b/src/color.h
new file mode 100644
index 0000000..40ba811
--- /dev/null
+++ b/src/color.h
@@ -0,0 +1,289 @@
+/***************************************************************************
+ color.h - description
+ -------------------
+ begin : Sun Mar 26 2000
+ copyright : (C) 2000 by Volker Schroer
+ email : DL1KSV at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * based on the work of Moe Wheatley, AE4JY *
+ ***************************************************************************/
+
+/** Define Colors for waterfall Display */
+
+#ifndef COLOR_H
+#define COLOR_H
+
+#include <qcolor.h>
+
+const QColor color[256] =
+
+{
+ QColor( 0, 0, 0), // 0 Black
+ QColor( 0, 0, 4),
+ QColor( 0, 0, 8),
+ QColor( 0, 0, 12),
+ QColor( 0, 0, 16),
+ QColor( 0, 0, 20),
+ QColor( 0, 0, 24),
+ QColor( 0, 0, 28),
+ QColor( 0, 0, 32),
+ QColor( 0, 0, 36),
+ QColor( 0, 0, 40),
+ QColor( 0, 0, 44),
+ QColor( 0, 0, 48),
+ QColor( 0, 0, 52),
+ QColor( 0, 0, 56),
+ QColor( 0, 0, 60),
+ QColor( 0, 0, 64),
+ QColor( 0, 0, 68),
+ QColor( 0, 0, 72),
+ QColor( 0, 0, 76),
+ QColor( 0, 0, 80),
+ QColor( 0, 0, 84),
+ QColor( 0, 0, 88),
+ QColor( 0, 0, 92),
+ QColor( 0, 0, 96),
+ QColor( 0, 0,100),
+ QColor( 0, 0,104),
+ QColor( 0, 0,108),
+ QColor( 0, 0,112),
+ QColor( 0, 0,116),
+ QColor( 0, 0,120),
+ QColor( 0, 0,124),
+ QColor( 0, 0,128),
+ QColor( 0, 0,132),
+ QColor( 0, 0,136),
+ QColor( 0, 0,140),
+ QColor( 0, 0,144),
+ QColor( 0, 0,148),
+ QColor( 0, 0,152),
+ QColor( 0, 0,156),
+ QColor( 0, 0,160),
+ QColor( 0, 0,164),
+ QColor( 0, 0,168),
+ QColor( 0, 0,172),
+ QColor( 0, 0,176),
+ QColor( 0, 0,180),
+ QColor( 0, 0,184),
+ QColor( 0, 0,188),
+ QColor( 0, 0,192),
+ QColor( 0, 0,196),
+ QColor( 0, 0,200),
+ QColor( 0, 0,204),
+ QColor( 0, 0,208),
+ QColor( 0, 0,212),
+ QColor( 0, 0,216),
+ QColor( 0, 0,220),
+ QColor( 0, 0,224),
+ QColor( 0, 0,228),
+ QColor( 0, 0,232),
+ QColor( 0, 0,236),
+ QColor( 0, 0,240),
+ QColor( 0, 0,244),
+ QColor( 0, 0,248),
+ QColor( 0, 0,255), // 63 Blue
+//
+ QColor( 0, 0,255), // 64
+ QColor( 0, 4,255),
+ QColor( 0, 8,255),
+ QColor( 0, 12,255),
+ QColor( 0, 16,255),
+ QColor( 0, 20,255),
+ QColor( 0, 24,255),
+ QColor( 0, 28,255),
+ QColor( 0, 32,255),
+ QColor( 0, 36,255),
+ QColor( 0, 40,255),
+ QColor( 0, 44,255),
+ QColor( 0, 48,255),
+ QColor( 0, 52,255),
+ QColor( 0, 56,255),
+ QColor( 0, 60,255),
+ QColor( 0, 64,255),
+ QColor( 0, 68,255),
+ QColor( 0, 72,255),
+ QColor( 0, 76,255),
+ QColor( 0, 80,255),
+ QColor( 0, 84,255),
+ QColor( 0, 88,255),
+ QColor( 0, 92,255),
+ QColor( 0, 96,255),
+ QColor( 0,100,255),
+ QColor( 0,104,255),
+ QColor( 0,108,255),
+ QColor( 0,112,255),
+ QColor( 0,116,255),
+ QColor( 0,120,255),
+ QColor( 0,124,255),
+ QColor( 0,128,255),
+ QColor( 0,132,255),
+ QColor( 0,136,255),
+ QColor( 0,140,255),
+ QColor( 0,144,255),
+ QColor( 0,148,255),
+ QColor( 0,152,255),
+ QColor( 0,156,255),
+ QColor( 0,160,255),
+ QColor( 0,164,255),
+ QColor( 0,168,255),
+ QColor( 0,172,255),
+ QColor( 0,176,255),
+ QColor( 0,180,255),
+ QColor( 0,184,255),
+ QColor( 0,188,255),
+ QColor( 0,192,255),
+ QColor( 0,196,255),
+ QColor( 0,200,255),
+ QColor( 0,204,255),
+ QColor( 0,208,255),
+ QColor( 0,212,255),
+ QColor( 0,216,255),
+ QColor( 0,220,255),
+ QColor( 0,224,255),
+ QColor( 0,228,255),
+ QColor( 0,232,255),
+ QColor( 0,236,255),
+ QColor( 0,240,255),
+ QColor( 0,244,255),
+ QColor( 0,248,255),
+ QColor( 0,255,255), //127 cyan
+//
+ QColor( 0,255,255), // 128
+ QColor( 4,255,252),
+ QColor( 8,255,248),
+ QColor( 12,255,244),
+ QColor( 16,255,240),
+ QColor( 20,255,236),
+ QColor( 24,255,232),
+ QColor( 28,255,228),
+ QColor( 32,255,224),
+ QColor( 36,255,220),
+ QColor( 40,255,216),
+ QColor( 44,255,212),
+ QColor( 48,255,208),
+ QColor( 52,255,204),
+ QColor( 56,255,200),
+ QColor( 60,255,196),
+ QColor( 64,255,192),
+ QColor( 68,255,188),
+ QColor( 72,255,184),
+ QColor( 76,255,180),
+ QColor( 80,255,176),
+ QColor( 84,255,172),
+ QColor( 88,255,168),
+ QColor( 92,255,164),
+ QColor( 96,255,160),
+ QColor(100,255,156),
+ QColor(104,255,152),
+ QColor(108,255,148),
+ QColor(112,255,144),
+ QColor(116,255,140),
+ QColor(120,255,136),
+ QColor(124,255,132),
+ QColor(128,255,128),
+ QColor(132,255,124),
+ QColor(136,255,120),
+ QColor(140,255,116),
+ QColor(144,255,112),
+ QColor(148,255,108),
+ QColor(152,255,104),
+ QColor(156,255,100),
+ QColor(160,255, 96),
+ QColor(164,255, 92),
+ QColor(168,255, 88),
+ QColor(172,255, 84),
+ QColor(176,255, 80),
+ QColor(180,255, 76),
+ QColor(184,255, 72),
+ QColor(188,255, 68),
+ QColor(192,255, 64),
+ QColor(196,255, 60),
+ QColor(200,255, 56),
+ QColor(204,255, 52),
+ QColor(208,255, 48),
+ QColor(212,255, 44),
+ QColor(216,255, 40),
+ QColor(220,255, 36),
+ QColor(224,255, 32),
+ QColor(228,255, 28),
+ QColor(232,255, 24),
+ QColor(236,255, 20),
+ QColor(240,255, 16),
+ QColor(244,255, 12),
+ QColor(248,255, 8),
+ QColor(255,255, 0), //191 yellow
+//
+ QColor(255,255, 0), // 192
+ QColor(255,255, 4),
+ QColor(255,255, 8),
+ QColor(255,255, 12),
+ QColor(255,255, 16),
+ QColor(255,255, 20),
+ QColor(255,255, 24),
+ QColor(255,255, 28),
+ QColor(255,255, 32),
+ QColor(255,255, 36),
+ QColor(255,255, 40),
+ QColor(255,255, 44),
+ QColor(255,255, 48),
+ QColor(255,255, 52),
+ QColor(255,255, 56),
+ QColor(255,255, 60),
+ QColor(255,255, 64),
+ QColor(255,255, 68),
+ QColor(255,255, 72),
+ QColor(255,255, 76),
+ QColor(255,255, 80),
+ QColor(255,255, 84),
+ QColor(255,255, 88),
+ QColor(255,255, 92),
+ QColor(255,255, 96),
+ QColor(255,255,100),
+ QColor(255,255,104),
+ QColor(255,255,108),
+ QColor(255,255,112),
+ QColor(255,255,116),
+ QColor(255,255,120),
+ QColor(255,255,124),
+ QColor(255,255,128),
+ QColor(255,255,132),
+ QColor(255,255,136),
+ QColor(255,255,140),
+ QColor(255,255,144),
+ QColor(255,255,148),
+ QColor(255,255,152),
+ QColor(255,255,156),
+ QColor(255,255,160),
+ QColor(255,255,164),
+ QColor(255,255,168),
+ QColor(255,255,172),
+ QColor(255,255,176),
+ QColor(255,255,180),
+ QColor(255,255,184),
+ QColor(255,255,188),
+ QColor(255,255,192),
+ QColor(255,255,196),
+ QColor(255,255,200),
+ QColor(255,255,204),
+ QColor(255,255,208),
+ QColor(255,255,212),
+ QColor(255,255,216),
+ QColor(255,255,220),
+ QColor(255,255,224),
+ QColor(255,255,228),
+ QColor(255,255,232),
+ QColor(255,255,236),
+ QColor(255,255,240),
+ QColor(255,255,244),
+ QColor(255,255,255) // 255 white
+};
+
+#endif
+
diff --git a/src/constants.h b/src/constants.h
new file mode 100644
index 0000000..7a5d87e
--- /dev/null
+++ b/src/constants.h
@@ -0,0 +1,96 @@
+/***************************************************************************
+ constants.h - description
+ -------------------
+ begin : Fri Apr 21 2000
+ copyright : (C) 2000 by Volker Schroer
+ email : DL1KSV at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * based on the work of Moe Wheatley, AE4JY *
+ ***************************************************************************/
+
+#ifndef CONSTANTS_H
+#define CONSTANTS_H
+
+#include <math.h> // for some constants like PI
+#include <QString>
+#include <QDate>
+#include <QTime>
+
+#define TXOFF_CODE -1 // control codes that can be placed in the input
+#define TXON_CODE -2 // queue for various control functions
+#define TXTOG_CODE -3
+
+#define FFT_SIZE 2048
+#define FFT_SAMPLERATEX2 11025 // 2 x the fft sample rate(so is an integer)
+
+#define TXBUFFER_LENGTH 1000
+#define BUF_SIZE 4096 //size of data chunks to process at a time from
+ // the soundcard
+#define RXWINDOWBUFFER 50 // Max Number of Lines in the RX ScrollBuffer
+
+// define some constants
+#define PI2 ( M_PI + M_PI ) // 2 Pi
+
+#define Ts (.032+.000000) // Ts == symbol period(correct for +/- .23%error)
+#define M_PI_3_2 (M_PI_2+M_PI) // 3Pi/2
+#define M_PI_3_4 (M_PI_2+M_PI_4) // 3Pi/4
+#define M_PI_5_4 (M_PI + M_PI_4) // 5Pi/4
+#define M_PI_7_4 (M_PI + M_PI_2 + M_PI_4) // 7Pi/4
+
+enum Mode {BPSK=0,QPSK,RTTY,MFSK16};
+enum AfcMode {Off,Narrow,Wide};
+
+enum Paritaet {None,Even,Odd};
+
+enum StopBits {One,Onepoint5,Two};
+
+enum RxTxParameterType{Reverse,Offset,Parity,Extra,Standard};
+enum StateOfReception { WaitingForMark,WaitingForSpace, CheckingStartBit,SkipRestOfStartBit,CollectingByte,
+ CheckingParity, WaitingForStopBits,ThrowHalfBit};
+
+
+typedef struct
+{
+bool reverse;
+Paritaet parity;
+int offset;
+StopBits stopbits;
+} ExtraParameter;
+
+typedef struct
+{
+AfcMode afc;
+bool Squelch;
+int Threshold;
+
+} Controls;
+
+typedef struct
+{
+ QString RemoteCallsign;
+ QString OpName;
+ QString Qth;
+ QString Locator;
+ QString QsoFrequency;
+ QString HisRST;
+ QString MyRST;
+ QDate QsoDate;
+ QTime QsoTime;
+QString mainPrefix;
+QString continent;
+QString wazZone;
+QString ituZone;
+QString countryName;
+QString worked;
+} QsoInfo;
+
+#define HilbertFilterLength 37
+
+#endif
diff --git a/src/controlpanel.cpp b/src/controlpanel.cpp
new file mode 100644
index 0000000..0c60e26
--- /dev/null
+++ b/src/controlpanel.cpp
@@ -0,0 +1,76 @@
+
+#include "controlpanel.h"
+
+#include <qvariant.h>
+#include <qlayout.h>
+#include <qtooltip.h>
+#include <qwhatsthis.h>
+#include <qimage.h>
+#include <qpixmap.h>
+
+#include "spectrumdisplay.h"
+#include "qsodata.h"
+#include "macrowindow.h"
+
+/*
+ * Constructs a ControlPanel which is a child of 'parent', with the
+ * name 'name'.'
+ */
+ControlPanel::ControlPanel(Macros *Macro, QWidget* parent)
+ : QFrame( parent )
+{
+ setFrameShape( QFrame::StyledPanel );
+ setFrameShadow( QFrame::Sunken );
+
+ Display = new SpectrumDisplay( this );
+ QSO = new QSOData(this);
+ MacroBox = new MacroWindow(Macro,this);
+
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+ControlPanel::~ControlPanel()
+{
+ if(QSO)
+ delete QSO;
+ QSO=0;
+ // no need to delete child widgets, Qt does it all for us
+}
+
+/*
+ * Sets the strings of the subwidgets using the current
+ * language.
+ */
+
+void ControlPanel::calculateSizeofComponents()
+{
+#define TOPMARGIN 2
+#define LEFTMARGIN 1
+#define SPECTRUMWIDTH 35
+#define SPECTRUMHEIGHT 85
+#define QSODATAWIDTH 45
+#define MACROBOXWIDTH 17
+int xpos,ypos,width,height,innerheight,innerwidth,innerwidthqso,innerwidthmacros;
+width=this->width();
+height=this->height();
+xpos=width*LEFTMARGIN/100;
+ypos=height*TOPMARGIN/100;
+innerwidth=(width-xpos)*SPECTRUMWIDTH/100;
+innerwidthqso=(width-xpos)*QSODATAWIDTH/100;
+innerwidthmacros=(width-xpos)*MACROBOXWIDTH/100;
+innerheight=((height-2*ypos)*SPECTRUMHEIGHT)/100;
+Display->setGeometry(xpos,ypos,innerwidth,innerheight);
+xpos=xpos+innerwidth+10;
+innerheight=(height*(100-2*TOPMARGIN))/100;
+QSO->setGeometry(xpos,ypos,innerwidthqso,innerheight);
+xpos = xpos+innerwidthqso+10;
+MacroBox->setGeometry(xpos,ypos,innerwidthmacros,innerheight);
+MacroBox->show();
+}
+
+void ControlPanel::resizeEvent( QResizeEvent * )
+{
+calculateSizeofComponents();
+}
diff --git a/src/controlpanel.h b/src/controlpanel.h
new file mode 100644
index 0000000..f0f50f0
--- /dev/null
+++ b/src/controlpanel.h
@@ -0,0 +1,43 @@
+
+#ifndef CONTROLPANEL_H
+#define CONTROLPANEL_H
+
+#include <qvariant.h>
+#include <qpixmap.h>
+#include <qframe.h>
+#include <vector>
+
+using namespace std;
+
+
+class SpectrumDisplay;
+class QSOData;
+class MacroWindow;
+class Macros;
+
+class ControlPanel : public QFrame
+{
+ Q_OBJECT
+
+public:
+ ControlPanel(Macros *M, QWidget* parent = 0);
+ ~ControlPanel();
+
+ SpectrumDisplay* Display;
+ QSOData *QSO;
+ MacroWindow *MacroBox;
+
+
+protected:
+ void resizeEvent( QResizeEvent * );
+public slots:
+
+protected slots:
+
+private:
+
+ void calculateSizeofComponents();
+
+};
+
+#endif // CONTROLPANEL_H
diff --git a/src/cpskdemodulator.cpp b/src/cpskdemodulator.cpp
new file mode 100644
index 0000000..34cfb14
--- /dev/null
+++ b/src/cpskdemodulator.cpp
@@ -0,0 +1,719 @@
+/***************************************************************************
+ cpskdemodulator.cpp - description
+ -------------------
+ begin : Sat Jun 2 2001
+ copyright : (C) 2001 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * based on the work of Moe Wheatly, AE4JY *
+ ***************************************************************************/
+
+
+
+
+#include "cpskdemodulator.h"
+#include "fircoeffs.h"
+#include "parameter.h"
+
+extern Parameter settings;
+
+
+static const unsigned short int VARICODE_TABLE[] = {
+ 0xAAC0, // ASCII = 0 1010101011
+ 0xB6C0, // ASCII = 1 1011011011
+ 0xBB40, // ASCII = 2 1011101101
+ 0xDDC0, // ASCII = 3 1101110111
+ 0xBAC0, // ASCII = 4 1011101011
+ 0xD7C0, // ASCII = 5 1101011111
+ 0xBBC0, // ASCII = 6 1011101111
+ 0xBF40, // ASCII = 7 1011111101
+ 0xBFC0, // ASCII = 8 1011111111
+ 0xEF00, // ASCII = 9 11101111
+ 0xE800, // ASCII = 10 11101
+ 0xDBC0, // ASCII = 11 1101101111
+ 0xB740, // ASCII = 12 1011011101
+ 0xF800, // ASCII = 13 11111
+ 0xDD40, // ASCII = 14 1101110101
+ 0xEAC0, // ASCII = 15 1110101011
+ 0xBDC0, // ASCII = 16 1011110111
+ 0xBD40, // ASCII = 17 1011110101
+ 0xEB40, // ASCII = 18 1110101101
+ 0xEBC0, // ASCII = 19 1110101111
+ 0xD6C0, // ASCII = 20 1101011011
+ 0xDAC0, // ASCII = 21 1101101011
+ 0xDB40, // ASCII = 22 1101101101
+ 0xD5C0, // ASCII = 23 1101010111
+ 0xDEC0, // ASCII = 24 1101111011
+ 0xDF40, // ASCII = 25 1101111101
+ 0xEDC0, // ASCII = 26 1110110111
+ 0xD540, // ASCII = 27 1101010101
+ 0xD740, // ASCII = 28 1101011101
+ 0xEEC0, // ASCII = 29 1110111011
+ 0xBEC0, // ASCII = 30 1011111011
+ 0xDFC0, // ASCII = 31 1101111111
+ 0x8000, // ASCII = ' ' 1
+ 0xFF80, // ASCII = '!' 111111111
+ 0xAF80, // ASCII = '"' 101011111
+ 0xFA80, // ASCII = '#' 111110101
+ 0xED80, // ASCII = '$' 111011011
+ 0xB540, // ASCII = '%' 1011010101
+ 0xAEC0, // ASCII = '&' 1010111011
+ 0xBF80, // ASCII = ''' 101111111
+ 0xFB00, // ASCII = '(' 11111011
+ 0xF700, // ASCII = ')' 11110111
+ 0xB780, // ASCII = '*' 101101111
+ 0xEF80, // ASCII = '+' 111011111
+ 0xEA00, // ASCII = ',' 1110101
+ 0xD400, // ASCII = '-' 110101
+ 0xAE00, // ASCII = '.' 1010111
+ 0xD780, // ASCII = '/' 110101111
+ 0xB700, // ASCII = '0' 10110111
+ 0xBD00, // ASCII = '1' 10111101
+ 0xED00, // ASCII = '2' 11101101
+ 0xFF00, // ASCII = '3' 11111111
+ 0xBB80, // ASCII = '4' 101110111
+ 0xAD80, // ASCII = '5' 101011011
+ 0xB580, // ASCII = '6' 101101011
+ 0xD680, // ASCII = '7' 110101101
+ 0xD580, // ASCII = '8' 110101011
+ 0xDB80, // ASCII = '9' 110110111
+ 0xF500, // ASCII = ':' 11110101
+ 0xDE80, // ASCII = ';' 110111101
+ 0xF680, // ASCII = '<' 111101101
+ 0xAA00, // ASCII = '=' 1010101
+ 0xEB80, // ASCII = '>' 111010111
+ 0xABC0, // ASCII = '?' 1010101111
+ 0xAF40, // ASCII = '@' 1010111101
+ 0xFA00, // ASCII = 'A' 1111101
+ 0xEB00, // ASCII = 'B' 11101011
+ 0xAD00, // ASCII = 'C' 10101101
+ 0xB500, // ASCII = 'D' 10110101
+ 0xEE00, // ASCII = 'E' 1110111
+ 0xDB00, // ASCII = 'F' 11011011
+ 0xFD00, // ASCII = 'G' 11111101
+ 0xAA80, // ASCII = 'H' 101010101
+ 0xFE00, // ASCII = 'I' 1111111
+ 0xFE80, // ASCII = 'J' 111111101
+ 0xBE80, // ASCII = 'K' 101111101
+ 0xD700, // ASCII = 'L' 11010111
+ 0xBB00, // ASCII = 'M' 10111011
+ 0xDD00, // ASCII = 'N' 11011101
+ 0xAB00, // ASCII = 'O' 10101011
+ 0xD500, // ASCII = 'P' 11010101
+ 0xEE80, // ASCII = 'Q' 111011101
+ 0xAF00, // ASCII = 'R' 10101111
+ 0xDE00, // ASCII = 'S' 1101111
+ 0xDA00, // ASCII = 'T' 1101101
+ 0xAB80, // ASCII = 'U' 101010111
+ 0xDA80, // ASCII = 'V' 110110101
+ 0xAE80, // ASCII = 'W' 101011101
+ 0xBA80, // ASCII = 'X' 101110101
+ 0xBD80, // ASCII = 'Y' 101111011
+ 0xAB40, // ASCII = 'Z' 1010101101
+ 0xFB80, // ASCII = '[' 111110111
+ 0xF780, // ASCII = '\' 111101111
+ 0xFD80, // ASCII = ']' 111111011
+ 0xAFC0, // ASCII = '^' 1010111111
+ 0xB680, // ASCII = '_' 101101101
+ 0xB7C0, // ASCII = '`' 1011011111
+ 0xB000, // ASCII = 'a' 1011
+ 0xBE00, // ASCII = 'b' 1011111
+ 0xBC00, // ASCII = 'c' 101111
+ 0xB400, // ASCII = 'd' 101101
+ 0xC000, // ASCII = 'e' 11
+ 0xF400, // ASCII = 'f' 111101
+ 0xB600, // ASCII = 'g' 1011011
+ 0xAC00, // ASCII = 'h' 101011
+ 0xD000, // ASCII = 'i' 1101
+ 0xF580, // ASCII = 'j' 111101011
+ 0xBF00, // ASCII = 'k' 10111111
+ 0xD800, // ASCII = 'l' 11011
+ 0xEC00, // ASCII = 'm' 111011
+ 0xF000, // ASCII = 'n' 1111
+ 0xE000, // ASCII = 'o' 111
+ 0xFC00, // ASCII = 'p' 111111
+ 0xDF80, // ASCII = 'q' 110111111
+ 0xA800, // ASCII = 'r' 10101
+ 0xB800, // ASCII = 's' 10111
+ 0xA000, // ASCII = 't' 101
+ 0xDC00, // ASCII = 'u' 110111
+ 0xF600, // ASCII = 'v' 1111011
+ 0xD600, // ASCII = 'w' 1101011
+ 0xDF00, // ASCII = 'x' 11011111
+ 0xBA00, // ASCII = 'y' 1011101
+ 0xEA80, // ASCII = 'z' 111010101
+ 0xADC0, // ASCII = '{' 1010110111
+ 0xDD80, // ASCII = '|' 110111011
+ 0xAD40, // ASCII = '}' 1010110101
+ 0xB5C0, // ASCII = '~' 1011010111
+ 0xED40, // ASCII = 127 1110110101
+ 0xEF40, // ASCII = 128 1110111101
+ 0xEFC0, // ASCII = 129 1110111111
+ 0xF540, // ASCII = 130 1111010101
+ 0xF5C0, // ASCII = 131 1111010111
+ 0xF6C0, // ASCII = 132 1111011011
+ 0xF740, // ASCII = 133 1111011101
+ 0xF7C0, // ASCII = 134 1111011111
+ 0xFAC0, // ASCII = 135 1111101011
+ 0xFB40, // ASCII = 136 1111101101
+ 0xFBC0, // ASCII = 137 1111101111
+ 0xFD40, // ASCII = 138 1111110101
+ 0xFDC0, // ASCII = 139 1111110111
+ 0xFEC0, // ASCII = 140 1111111011
+ 0xFF40, // ASCII = 141 1111111101
+ 0xFFC0, // ASCII = 142 1111111111
+ 0xAAA0, // ASCII = 143 10101010101
+ 0xAAE0, // ASCII = 144 10101010111
+ 0xAB60, // ASCII = 145 10101011011
+ 0xABA0, // ASCII = 146 10101011101
+ 0xABE0, // ASCII = 147 10101011111
+ 0xAD60, // ASCII = 148 10101101011
+ 0xADA0, // ASCII = 149 10101101101
+ 0xADE0, // ASCII = 150 10101101111
+ 0xAEA0, // ASCII = 151 10101110101
+ 0xAEE0, // ASCII = 152 10101110111
+ 0xAF60, // ASCII = 153 10101111011
+ 0xAFA0, // ASCII = 154 10101111101
+ 0xAFE0, // ASCII = 155 10101111111
+ 0xB560, // ASCII = 156 10110101011
+ 0xB5A0, // ASCII = 157 10110101101
+ 0xB5E0, // ASCII = 158 10110101111
+ 0xB6A0, // ASCII = 159 10110110101
+ 0xB6E0, // ASCII = 160 10110110111
+ 0xB760, // ASCII = 161 10110111011
+ 0xB7A0, // ASCII = 162 10110111101
+ 0xB7E0, // ASCII = 163 10110111111
+ 0xBAA0, // ASCII = 164 10111010101
+ 0xBAE0, // ASCII = 165 10111010111
+ 0xBB60, // ASCII = 166 10111011011
+ 0xBBA0, // ASCII = 167 10111011101
+ 0xBBE0, // ASCII = 168 10111011111
+ 0xBD60, // ASCII = 169 10111101011
+ 0xBDA0, // ASCII = 170 10111101101
+ 0xBDE0, // ASCII = 171 10111101111
+ 0xBEA0, // ASCII = 172 10111110101
+ 0xBEE0, // ASCII = 173 10111110111
+ 0xBF60, // ASCII = 174 10111111011
+ 0xBFA0, // ASCII = 175 10111111101
+ 0xBFE0, // ASCII = 176 10111111111
+ 0xD560, // ASCII = 177 11010101011
+ 0xD5A0, // ASCII = 178 11010101101
+ 0xD5E0, // ASCII = 179 11010101111
+ 0xD6A0, // ASCII = 180 11010110101
+ 0xD6E0, // ASCII = 181 11010110111
+ 0xD760, // ASCII = 182 11010111011
+ 0xD7A0, // ASCII = 183 11010111101
+ 0xD7E0, // ASCII = 184 11010111111
+ 0xDAA0, // ASCII = 185 11011010101
+ 0xDAE0, // ASCII = 186 11011010111
+ 0xDB60, // ASCII = 187 11011011011
+ 0xDBA0, // ASCII = 188 11011011101
+ 0xDBE0, // ASCII = 189 11011011111
+ 0xDD60, // ASCII = 190 11011101011
+ 0xDDA0, // ASCII = 191 11011101101
+ 0xDDE0, // ASCII = 192 11011101111
+ 0xDEA0, // ASCII = 193 11011110101
+ 0xDEE0, // ASCII = 194 11011110111
+ 0xDF60, // ASCII = 195 11011111011
+ 0xDFA0, // ASCII = 196 11011111101
+ 0xDFE0, // ASCII = 197 11011111111
+ 0xEAA0, // ASCII = 198 11101010101
+ 0xEAE0, // ASCII = 199 11101010111
+ 0xEB60, // ASCII = 200 11101011011
+ 0xEBA0, // ASCII = 201 11101011101
+ 0xEBE0, // ASCII = 202 11101011111
+ 0xED60, // ASCII = 203 11101101011
+ 0xEDA0, // ASCII = 204 11101101101
+ 0xEDE0, // ASCII = 205 11101101111
+ 0xEEA0, // ASCII = 206 11101110101
+ 0xEEE0, // ASCII = 207 11101110111
+ 0xEF60, // ASCII = 208 11101111011
+ 0xEFA0, // ASCII = 209 11101111101
+ 0xEFE0, // ASCII = 210 11101111111
+ 0xF560, // ASCII = 211 11110101011
+ 0xF5A0, // ASCII = 212 11110101101
+ 0xF5E0, // ASCII = 213 11110101111
+ 0xF6A0, // ASCII = 214 11110110101
+ 0xF6E0, // ASCII = 215 11110110111
+ 0xF760, // ASCII = 216 11110111011
+ 0xF7A0, // ASCII = 217 11110111101
+ 0xF7E0, // ASCII = 218 11110111111
+ 0xFAA0, // ASCII = 219 11111010101
+ 0xFAE0, // ASCII = 220 11111010111
+ 0xFB60, // ASCII = 221 11111011011
+ 0xFBA0, // ASCII = 222 11111011101
+ 0xFBE0, // ASCII = 223 11111011111
+ 0xFD60, // ASCII = 224 11111101011
+ 0xFDA0, // ASCII = 225 11111101101
+ 0xFDE0, // ASCII = 226 11111101111
+ 0xFEA0, // ASCII = 227 11111110101
+ 0xFEE0, // ASCII = 228 11111110111
+ 0xFF60, // ASCII = 229 11111111011
+ 0xFFA0, // ASCII = 230 11111111101
+ 0xFFE0, // ASCII = 231 11111111111
+ 0xAAB0, // ASCII = 232 101010101011
+ 0xAAD0, // ASCII = 233 101010101101
+ 0xAAF0, // ASCII = 234 101010101111
+ 0xAB50, // ASCII = 235 101010110101
+ 0xAB70, // ASCII = 236 101010110111
+ 0xABB0, // ASCII = 237 101010111011
+ 0xABD0, // ASCII = 238 101010111101
+ 0xABF0, // ASCII = 239 101010111111
+ 0xAD50, // ASCII = 240 101011010101
+ 0xAD70, // ASCII = 241 101011010111
+ 0xADB0, // ASCII = 242 101011011011
+ 0xADD0, // ASCII = 243 101011011101
+ 0xADF0, // ASCII = 244 101011011111
+ 0xAEB0, // ASCII = 245 101011101011
+ 0xAED0, // ASCII = 246 101011101101
+ 0xAEF0, // ASCII = 247 101011101111
+ 0xAF50, // ASCII = 248 101011110101
+ 0xAF70, // ASCII = 249 101011110111
+ 0xAFB0, // ASCII = 250 101011111011
+ 0xAFD0, // ASCII = 251 101011111101
+ 0xAFF0, // ASCII = 252 101011111111
+ 0xB550, // ASCII = 253 101101010101
+ 0xB570, // ASCII = 254 101101010111
+ 0xB5B0 // ASCII = 255 101101011011
+};
+
+
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CPskDemodulator::CPskDemodulator(): CDemodulator()
+{
+ m_pQue1 = NULL;
+ m_pQue2 = NULL;
+ m_pQue3 = NULL;
+ m_VaricodeDecTbl = NULL;
+ Phase= NULL;
+}
+
+CPskDemodulator::~CPskDemodulator()
+{
+ if(m_pQue1)
+ delete m_pQue1;
+ if(m_pQue2)
+ delete m_pQue2;
+ if(m_pQue3)
+ delete m_pQue3;
+ if(m_VaricodeDecTbl)
+ delete m_VaricodeDecTbl;
+ if(Phase )
+ delete Phase;
+
+}
+
+/////////////////////////////////////////////////////////////////
+// Initialize PskDet buffers and pointers
+/////////////////////////////////////////////////////////////////
+bool CPskDemodulator::Init( double Fs, int BlockSize )
+{
+unsigned short int wTemp;
+int i;
+//circular delay lines.(data stays put and the pointers move)
+
+ if( (m_pQue1 = new complex<double>[DEC3_LPFIR_LENGTH] ) == NULL)
+ return false;
+ if( (m_pQue2 = new complex<double>[DEC3_LPFIR_LENGTH] ) == NULL)
+ return false;
+ if( (m_pQue3 = new complex<double>[BITFIR_LENGTH] ) == NULL)
+ return false;
+ if( ( m_VaricodeDecTbl = new unsigned char[2048] )== NULL)
+ return false;
+
+ if ( ( Phase = new complex<float>[228] ) == NULL )
+ return false;
+ for(int i=0; i<DEC3_LPFIR_LENGTH; i++)
+ {
+ // fill delay buffer with zero
+ m_pQue1[i] = complex<double>(0.0,0.0);
+ }
+ for(i=0; i<DEC3_LPFIR_LENGTH; i++)
+ {
+ // fill delay buffer with zero
+ m_pQue2[i] = complex<double>(0.0,0.0);
+
+ }
+ for( i=0; i<BITFIR_LENGTH; i++)
+ {
+ // fill delay buffer with zero
+ m_pQue3[i] = complex<double>(0.0,0.0);
+ }
+
+ for( int j=0; j<2048; j++) //init inverse varicode lookup decoder table
+ {
+ m_VaricodeDecTbl[j] = 0;
+ for(int i=0; i<256;i++)
+
+ {
+ wTemp = VARICODE_TABLE[i];
+ wTemp >>= 4;
+ while( !(wTemp&1) )
+ wTemp >>= 1;
+ wTemp >>= 1;
+ if( wTemp == j)
+ m_VaricodeDecTbl[j] = (unsigned char)i;
+ }
+ }
+ m_pInPtr1 = m_pQue1; //initialize que ptrs
+ m_pInPtr2 = m_pQue2;
+ m_pInPtr3 = m_pQue3;
+ SampleRate = Fs; //sample rate
+ NxSamples = BlockSize; //size data input buffer
+ OszFreqinc = 1000.0*PI2/SampleRate;
+ m_BitPhaseInc = 9.0/SampleRate; //bit oversampling period
+ m_SignalLevel = 1.0;
+ m_BitPhasePos = 0.0;
+ m_BitAcc = 0;
+ m_LastBitZero = false;
+ m_SampCnt = 0;
+ m_OnCount = 0;
+ m_OffCount = 0;
+
+ for (i=0;i< 228; i++)
+ Phase[i]=0.0;
+ for( i=0; i<40; i++)
+ DelayLine[i] = 0.0; // initialize the array
+
+
+// Init a bunch of "static" variables used in various member fuctions
+ m_AGCave = 0.0;
+ m_FreqError = 0.0;
+ OszFrequency = 0.0;
+ m_LastFreq = 1000.0;
+ m_PkPos = 0;
+ m_BitPos = 0;
+ Prev_Sample=complex<double>(0.0,0.0) ;
+ Phase_Vector = Prev_Sample;
+ m_DevAve = 0.78;
+ m_QFreqError = 0.0;
+ m_LastPkPos = 0;
+ m_ClkErrCounter = 0;
+ m_ClkErrTimer = 0;
+ m_ClkError = 0;
+// Initializing Variables for AFC
+fe0=0.0;
+fe1=0.0;
+fe2=0.0;
+// FastSquelch
+fastSquelch=false;
+// IMD
+IMD=0.0; // Means Unkonown
+ x_loop_1=0;
+ y_loop_1=0;
+return true;
+}
+
+//////////////////////////////////////////////////////////////////////
+// Main routine called to process the next block of data 'pIn'.
+// The center frequency is specified by 'Freq'.
+// 'UseAFC' specifies whether to automatically lock to the frequency.
+// 30mSec for BPSK, 38mSec for QPSK( 133MHz Pentium )
+//////////////////////////////////////////////////////////////////////
+
+void CPskDemodulator::ProcessInput( double* pIn, double *Spectrum)
+{
+double vcophz = OszFrequency;
+int i,j;
+complex<double> acc;
+const double* Kptr;
+complex<double>* Firptr;
+complex<double>* Inptr1; //decimation FIR #1 variables
+complex<double>* Qptr1;
+complex<double>* Inptr2; //decimation FIR #2 variables
+complex<double>* Qptr2;
+
+if ( UseAfc == Wide )
+ {
+// Check if we are near the center frequency in Spectrum
+ int index;
+ index=(int) (RxFrequency/2.69165);
+ double smooth[15],xx;
+// First we smooth the spectrum
+ for(int i=0; i<15; i++)
+ {
+ smooth[i]=0.0;
+ for (int k=0; k <15; k++)
+ smooth[i] +=Spectrum[index-14+k+i]/7;
+ }
+ int maxspect=0;
+ xx=0.0;
+ for(int i=0;i <15; i++)
+ {
+ if (smooth[i] >xx )
+ {
+ xx=smooth[i];
+ maxspect=i;
+ }
+ }
+ if ( maxspect < 5 ) // We are far above the Frequency
+ RxFrequency -=1.5;
+ else if (maxspect > 9 )
+ RxFrequency += 1.5;
+ }
+
+ m_DispTrig = false;
+ j=0;
+ if( RxFrequency != m_LastFreq ) //caller is changing center frequency
+ {
+ OszFreqinc = (PI2/SampleRate)*RxFrequency; //new center freq inc
+ m_LastFreq = RxFrequency;
+ }
+ Inptr1 = m_pInPtr1; //use local copies of member variables
+ Qptr1 = m_pQue1; // for better speed.
+ Inptr2 = m_pInPtr2;
+ Qptr2 = m_pQue2;
+ for( i = 0; i<NxSamples; i++ ) // put new samples into Queue
+ {
+ if( --Inptr1 < Qptr1 ) //deal with FIR pointer wrap around
+ Inptr1 = Qptr1+DEC3_LPFIR_LENGTH-1;
+//Generate complex sample by mixing input sample with NCO's sin/cos
+ vcophz = vcophz + OszFreqinc;
+ if(vcophz > PI2) //handle 2 Pi wrap around
+ vcophz -= PI2;
+ *Inptr1=pIn[i]*complex<double>(cos(vcophz),sin(vcophz));
+//decimate by 3 filter
+ if( ( (++m_SampCnt)%3 ) == 0 ) //calc first decimation filter every 3 samples
+ {
+ acc=complex<double>(0.0,0.0);
+ Firptr = Inptr1;
+ Kptr = Dec3LPCoef;
+ while( Kptr < (Dec3LPCoef + DEC3_LPFIR_LENGTH) ) //do the MAC's
+ {
+ acc +=(*Firptr)*(*Kptr++);
+ if( (++Firptr) >= Qptr1+DEC3_LPFIR_LENGTH ) //deal with wraparound
+ Firptr = Qptr1;
+ }
+ if( --Inptr2 < Qptr2 ) //deal with FIR pointer wrap around
+ Inptr2 = Qptr2+DEC3_LPFIR_LENGTH-1;
+ *Inptr2=acc;
+//decimate by 3 filter
+ if( (m_SampCnt%9) == 0 ) //calc second decimation filter every 9 samples
+ {
+ acc=complex<double>(0.0,0.0);
+ Firptr = Inptr2;
+ Kptr = Dec3LPCoef;
+ while( Kptr < (Dec3LPCoef + DEC3_LPFIR_LENGTH) ) //do the MAC's
+ {
+ acc +=(*Firptr)*(*Kptr);
+ Kptr++;
+ if( (++Firptr) >= Qptr2+DEC3_LPFIR_LENGTH ) //deal with wraparound
+ Firptr = Qptr2;
+ }
+// here at Fs/9 = 612.5 Hz rate with latest sample in acc.
+// Matched Filter the I and Q data and also a frequency error filter
+// filter puts filtered signals in m_FreqSignal and m_BitSignal.
+ CalcBitFilter( acc );
+ if( SymbSync(m_BitSignal) )
+ {
+ Phase_Vector=m_BitSignal*conj(Prev_Sample);
+ Prev_Sample = m_BitSignal;
+ Phase[j++]=Phase_Vector;
+ double angle = atan2(Phase_Vector.imag(),Phase_Vector.real());
+ DecodeSymbol( angle);
+ if ( (unsigned int) m_DevAve > Threshold)
+ {
+ if (m_OffCount > 10)
+ calcIMD(Spectrum); // We got enough Idles to calc the IMD
+ }
+ else
+ IMD =0.0;
+ if( UseAfc != Off )
+ OszFreqinc +=CalcFreqError(Phase_Vector);
+ }
+ }
+ }
+ }
+ m_SampCnt = m_SampCnt%9;
+ m_pInPtr1 = Inptr1; // save position in circular delay line
+ m_pInPtr2 = Inptr2; // save position in circular delay line
+ OszFrequency = vcophz;
+
+ if (UseAfc != Off) // Change RxFrequency, but slowly
+ {
+ RxFrequency=OszFreqinc*SampleRate/PI2;
+ m_LastFreq=RxFrequency;
+ }
+
+}
+
+
+//////////////////////////////////////////////////////////////////////
+// Called at Fs/9 rate to calculate the symbol sync position
+// Returns true if at center of symbol.
+// Sums up the energy at each sample time, averages it, and picks the
+// sample time with the highest energy content.
+//////////////////////////////////////////////////////////////////////
+
+bool CPskDemodulator::SymbSync(complex<double> sample)
+
+{
+ bool Trigger;
+ int BitPos = m_BitPos;
+ Trigger=false;
+ DelayLine[BitPos]=sample;
+ m_BitPhasePos += m_BitPhaseInc;
+ if( m_BitPhasePos >= Ts )
+ { // here every symbol time
+ m_BitPhasePos -= Ts;
+ float x,y,maxsample;
+ int kk;
+ x=0;
+ maxsample=-1;
+ for(int i=0; i <10;i++)
+ {
+ kk= BitPos-i-10;
+ if (kk < 0)
+ kk += 40;
+ y= abs(DelayLine[kk]);
+ maxsample=max(maxsample,y);
+ x += y;
+ kk = BitPos-i;
+ if (kk < 0)
+ kk += 40;
+ y = abs(DelayLine[kk]);
+ maxsample=max(maxsample,y);
+ x -= y;
+ }
+ maxsample = 3.* maxsample;
+ if ( x < -maxsample )
+ m_BitPhasePos += m_BitPhaseInc;
+ else if ( x > maxsample)
+ m_BitPhasePos -= m_BitPhaseInc;
+
+ Trigger=true;
+ }
+ BitPos++;
+ if ( BitPos >= 40 )
+ BitPos=0;
+ m_BitPos=BitPos;
+ return Trigger;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+// Frequency error calculator
+//////////////////////////////////////////////////////////////////////
+double CPskDemodulator::CalcFreqError(complex<double> s)
+{
+ double x,y;
+ complex<double> z;
+ if (abs(s) >1 )
+ z=s/abs(s);
+ else z=s;
+ x= z.real()*z.imag();
+ x /=10000.; // Adopt deviation to samplerate
+// x /=2.8016548; //Gain
+ y=x_loop_1+x +0.2861361823*y_loop_1;
+ x_loop_1=x;
+ y_loop_1=y;
+ return -y;
+
+}
+
+//////////////////////////////////////////////////////////////////////
+// Automatic gain control calculator
+//////////////////////////////////////////////////////////////////////
+double CPskDemodulator::CalcAGC( complex<double> Samp)
+{
+double mag;
+
+ mag = abs(Samp);
+ if( mag > m_AGCave )
+
+ m_AGCave = (1.0-1.0/250.0)*m_AGCave + (1.0/250.0)*mag;
+ else
+ m_AGCave = (1.0-1.0/1000.0)*m_AGCave + (1.0/1000.0)*mag;
+ if( m_AGCave >= 1.0 ) // divide signal by ave if not almost zero
+ {
+ m_BitSignal /= m_AGCave;
+// m_BitSignal.y /= m_AGCave;
+ m_FreqSignal /= m_AGCave;
+// m_FreqSignal.y /= m_AGCave;
+ }
+ return(m_AGCave);
+}
+
+
+//////////////////////////////////////////////////////////////////////
+// BIT FIR filters. A narrow matched(?) data filter for data
+// and wider filter for the AFC/AGC functions
+//////////////////////////////////////////////////////////////////////
+void CPskDemodulator::CalcBitFilter(complex<double> Samp)
+{
+complex<double> acc1;
+complex<double> acc2;
+const double* Kptr1;
+const double* Kptr2;
+complex<double>* Firptr;
+complex<double>* Qptr;
+complex<double>* Inptr;
+ Inptr = m_pInPtr3; //use local copies of member variables
+ Qptr = m_pQue3; // for better speed.
+ if( --Inptr < Qptr ) //deal with LPFIR pointer wrap around
+ Inptr = Qptr+BITFIR_LENGTH-1;
+// Inptr->x = Samp.x; //place in circular Queue
+ *Inptr = Samp;
+// acc1.x = 0.0;
+ acc1 = complex<double>(0.0,0.0);
+// acc2.x = 0.0;
+ acc2 = complex<double>(0.0,0.0);
+ Firptr = Inptr;
+ Kptr1 = FreqFirCoef; //frequency error filter
+ Kptr2 = BitFirCoef; //bit data filter
+ while( Kptr2 < (BitFirCoef + BITFIR_LENGTH) ) //do the MAC's
+ {
+// acc1.x += ( (Firptr->x)*(*Kptr1) );
+ acc1 += ( (*Firptr)*(*Kptr1++) );
+
+// acc2.x += ( (Firptr->x)*(*Kptr2) );
+ acc2 += ( (*Firptr)*(*Kptr2++) );
+
+ if( (++Firptr) >= (Qptr+BITFIR_LENGTH) ) //deal with wraparound
+ Firptr = Qptr;
+ }
+ m_pInPtr3 = Inptr; // save position in circular delay line
+ m_FreqSignal = acc1;
+ m_BitSignal = acc2;
+}
+
+complex<float> * CPskDemodulator::getPhasePointer()
+{
+return Phase;
+}
+
+int CPskDemodulator::getSquelchValue()
+{
+return (int) m_DevAve;
+}
+void CPskDemodulator::calcIMD(double *Spectrum)
+{
+int freq1,freq2;
+
+freq1 = (int) ((RxFrequency+15.625)/2.69165);
+freq2 = (int) ((RxFrequency+46.875)/2.69165);
+IMD=(Spectrum[freq2-1]+Spectrum[freq2]+Spectrum[freq2+1])/(Spectrum[freq1-1]+Spectrum[freq1]+Spectrum[freq1+1]);
+freq1=(int) ( (RxFrequency- 15.625)/2.69165);
+freq2=(int) ( (RxFrequency- 46.875)/2.69165);
+IMD = 10.*log10( (IMD + (Spectrum[freq2-1]+Spectrum[freq2]+Spectrum[freq2+1])/(Spectrum[freq1-1]+Spectrum[freq1]+Spectrum[freq1+1]))/2);
+
+}
+float CPskDemodulator::getIMD()
+{
+return IMD;
+}
+AfcMode CPskDemodulator::AfcProperties()
+{
+return Wide;
+}
diff --git a/src/cpskdemodulator.h b/src/cpskdemodulator.h
new file mode 100644
index 0000000..516d8e4
--- /dev/null
+++ b/src/cpskdemodulator.h
@@ -0,0 +1,118 @@
+/***************************************************************************
+ cpskdemodulator.h - description
+ -------------------
+ begin : Sat Jun 2 2001
+ copyright : (C) 2001 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * based on the work of Moe Wheatley, AE4JY *
+ ***************************************************************************/
+
+
+#ifndef CPSKDEMODULATOR_H
+#define CPSKDEMODULATOR_H
+
+using namespace std;
+#include "constants.h"
+#include <math.h>
+#include <complex>
+#include <stdlib.h>
+
+#include "cdemodulator.h"
+
+
+class CPskDemodulator : public CDemodulator
+{
+ Q_OBJECT
+public:
+ CPskDemodulator();
+ virtual ~CPskDemodulator();
+ bool Init(double Fs ,int BlockSize);
+ int getSquelchValue();
+ void ProcessInput( double *pIn, double *Spectrum);
+ complex<float> * getPhasePointer();
+ virtual float getIMD();
+ AfcMode AfcProperties();
+
+protected:
+
+// Methods
+/** Decodes the symbol depending on the PskModes */
+ virtual void DecodeSymbol( double) = 0;
+/** Calculates the Cuality of the signal -- depends on the mode */
+ virtual void CalcQuality( double angle ) = 0;
+
+// Variables
+ complex<double> Prev_Sample;
+ complex<double> Phase_Vector;
+ int m_BitAcc;
+ bool m_LastBitZero;
+ unsigned char* m_VaricodeDecTbl;
+ int m_OnCount;
+ int m_OffCount;
+ double m_FreqError;
+ double m_QFreqError;
+
+ double m_DevAve;
+
+ bool fastSquelch;
+private:
+ int m_ClkErrTimer;
+ int m_ClkErrCounter;
+ int m_ClkError;
+
+//methods
+
+
+ bool SymbSync(complex<double> );
+ void CalcBitFilter( complex<double>);
+ double CalcAGC( complex<double> );
+ double CalcFreqError(complex<double>);
+ void calcIMD(double *Spectrum);
+//variables
+ double m_QPSKprob[4];
+ int m_LastPkPos;
+ int m_SampCnt;
+ bool m_DispTrig;
+ float m_BitPhaseInc;
+ float m_BitPhasePos;
+// float m_SyncAve[21];
+ complex<float> DelayLine[40];
+ float m_SignalLevel;
+
+ complex<double>* m_pQue1;
+ complex<double>* m_pQue2;
+ complex<double>* m_pQue3;
+ complex<double>* m_pInPtr1;
+ complex<double>* m_pInPtr2;
+ complex<double>* m_pInPtr3;
+
+ complex<double> m_FreqSignal;
+ complex<double> m_BitSignal;
+// Phase Values
+ complex<float> * Phase;
+// Local variables for various functions that need to be saved between calls
+ double m_AGCave;
+ double m_LastFreq;
+ int m_PkPos;
+ int m_BitPos;
+float IMD;
+
+/** Some Variable for CalcQuality */
+
+double fe0,fe1,fe2;
+double x_loop_1,y_loop_1;
+
+public slots:
+signals: // Signals
+
+};
+
+#endif
diff --git a/src/crecording.cpp b/src/crecording.cpp
new file mode 100644
index 0000000..b433daf
--- /dev/null
+++ b/src/crecording.cpp
@@ -0,0 +1,76 @@
+/***************************************************************************
+ |FILENAME| - description
+ -------------------
+ begin : |DATE|
+ copyright : (C) |YEAR| by |AUTHOR|
+ email : |EMAIL|
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#include "crecording.h"
+
+#include <qvariant.h>
+#include <qradiobutton.h>
+#include <qlayout.h>
+#include <qtooltip.h>
+#include <qwhatsthis.h>
+
+
+/*
+ * Constructs a CRecording which is a child of 'parent', with the
+ * name 'name'.'
+ */
+CRecording::CRecording( QWidget* parent )
+ : QGroupBox( parent )
+{
+
+ Record = new QRadioButton( this);
+ languageChange();
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+CRecording::~CRecording()
+{
+ // no need to delete child widgets, Qt does it all for us
+}
+
+/*
+ * Sets the strings of the subwidgets using the current
+ * language.
+ */
+void CRecording::languageChange()
+{
+
+ Record->setText( tr( "Record QSO" ) );
+}
+void CRecording::resizeEvent( QResizeEvent * )
+{
+calculateSizeofComponents();
+
+}
+
+void CRecording::calculateSizeofComponents()
+{
+/** Margins **/
+#define LEFTMARGIN 5
+#define TOPMARGIN 30
+int innerwidth,innerheight,xpos,ypos,width,height;
+
+width=this->width();
+height=this->height();
+xpos=width*LEFTMARGIN/100;
+ypos=height*TOPMARGIN/100;
+
+innerwidth=width-2*xpos;
+innerheight=height-3*ypos/2;
+Record->setGeometry(xpos,ypos,innerwidth,innerheight);
+}
diff --git a/src/crecording.h b/src/crecording.h
new file mode 100644
index 0000000..640b640
--- /dev/null
+++ b/src/crecording.h
@@ -0,0 +1,46 @@
+/***************************************************************************
+ |FILENAME| - description
+ -------------------
+ begin : |DATE|
+ copyright : (C) |YEAR| by |AUTHOR|
+ email : |EMAIL|
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * The PSK part is based on WinPSK 1.0 by Moe Wheatley, AE4JY *
+ ***************************************************************************/
+
+#ifndef CRECORDING_H
+#define CRECORDING_H
+
+#include <QGroupBox>
+class QRadioButton;
+class CRecording : public QGroupBox
+{
+ Q_OBJECT
+
+public:
+ CRecording( QWidget* parent = 0);
+ ~CRecording();
+
+ QRadioButton* Record;
+
+public slots:
+
+protected:
+ void resizeEvent( QResizeEvent * );
+
+
+protected slots:
+ virtual void languageChange();
+private:
+ void calculateSizeofComponents();
+
+};
+
+#endif // CRECORDING_H
diff --git a/src/crxchannel.cpp b/src/crxchannel.cpp
new file mode 100644
index 0000000..fb5e009
--- /dev/null
+++ b/src/crxchannel.cpp
@@ -0,0 +1,322 @@
+/***************************************************************************
+ crxchannel.cpp - description
+ -------------------
+ begin : Sam Jan 4 2003
+ copyright : (C) 2003 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ ***************************************************************************/
+#include <qwidget.h>
+#include <qapplication.h>
+
+#include "crxchannel.h"
+#include "cdemodulator.h"
+#include "crxwindow.h"
+#include "qpskdemodulator.h"
+#include "bpskdemodulator.h"
+#include "rttydemodulator.h"
+#include "mfskdemodulator.h"
+#include "parameter.h"
+
+extern Parameter settings;
+
+CRxChannel::CRxChannel ( int ID, QWidget *parent, Mode DemodulatorType, unsigned int Freq )
+{
+
+
+ nextChannel = 0;
+ prevChannel = 0;
+ RxMode = DemodulatorType;
+ WindowsID = ID;
+
+ double SampleRate = 5512.5;
+ int BufferLength;
+ BufferLength = BUF_SIZE / 2;
+ switch ( DemodulatorType )
+ {
+ case QPSK:
+ Demodulator = new QPskDemodulator();
+ break;
+ case RTTY:
+ Demodulator = new RTTYDemodulator();
+ SampleRate = 11025;
+ BufferLength = BUF_SIZE;
+ break;
+ case MFSK16:
+ Demodulator = new MFSKDemodulator();
+ SampleRate = 11025;
+ BufferLength = BUF_SIZE;
+ break;
+
+ default:
+ Demodulator = new BPskDemodulator();
+ break;
+ }
+ Demodulator->Init ( SampleRate, BufferLength ); // Should changed later to
+ // adjusted Samplerate
+ Demodulator->setRxFrequency ( double ( Freq ) );
+ Demodulator->setAfcMode ( Demodulator->AfcProperties() );
+ RxWindow = new CRxWindow ( parent );
+ connect ( Demodulator, SIGNAL ( newSymbol ( char ) ), RxWindow, SLOT ( updateRx ( char ) ) );
+ connect ( RxWindow, SIGNAL ( Triggered() ), this, SLOT ( triggered() ) );
+ QDateTime t1;
+ QDateTime t;
+ t = QDateTime::currentDateTime();
+
+ t1 = t.addSecs ( settings.timeoffset * 3600 );
+
+
+ QsoData.QsoDate= t.date() ;
+ QsoData.QsoTime= t1.time();
+}
+CRxChannel::~CRxChannel()
+{
+ if ( Demodulator != 0 )
+ delete Demodulator;
+ if ( RxWindow != 0 )
+ delete RxWindow;
+ if ( prevChannel != 0 )
+ prevChannel->changeChain ( nextChannel );
+}
+
+void CRxChannel::insertChannel ( CRxChannel *nChannel )
+{
+ CRxChannel *p;
+// Find last Channel in Chain
+ p = this;
+ while ( p->getNextChannel() != 0 )
+ p = p->getNextChannel();
+ if ( p == this )
+ {
+ nextChannel = nChannel;
+ nChannel->setPrevChannel ( p );
+ }
+ else
+ p->insertChannel ( nChannel );
+}
+void CRxChannel::changeChain ( CRxChannel *nChannel )
+{
+ nextChannel = nChannel;
+}
+
+void CRxChannel::setGeometry ( int x, int y, int width, int height )
+{
+ if ( RxWindow != 0 )
+ RxWindow->setGeometry ( x, y, width, height );
+}
+
+void CRxChannel::processInput ( double *Input, double *Spectrum )
+{
+ Demodulator->ProcessInput ( Input, Spectrum );
+}
+
+CRxChannel * CRxChannel::getNextChannel()
+{
+ return nextChannel;
+}
+
+void CRxChannel::setRxFrequency ( double Freq )
+{
+ Demodulator->setRxFrequency ( Freq );
+}
+
+Mode CRxChannel::getModulationType()
+{
+ return RxMode;
+}
+
+void CRxChannel::hide()
+{
+ RxWindow->hide();
+}
+
+void CRxChannel::show()
+{
+ RxWindow->show();
+}
+
+CRxChannel* CRxChannel::getChannel ( int ID )
+{
+ CRxChannel *p;
+ if ( ID > WindowsID )
+ for ( p = this; p != 0; p = p->getNextChannel() )
+ {
+ if ( p->getID() == ID )
+ return p;
+ }
+ if ( ID < WindowsID )
+ for ( p = this; p != 0; p = p->prevChannel )
+ {
+ if ( p->getID() == ID )
+ return p;
+ }
+
+ return this;
+}
+
+void CRxChannel::setPrevChannel ( CRxChannel *p )
+{
+ prevChannel = p;
+}
+
+complex<float>* CRxChannel::getPhasePointer()
+{
+ if ( ( RxMode == BPSK ) || ( RxMode == QPSK ) )
+ return Demodulator->getPhasePointer();
+ else
+ return 0;
+}
+
+int CRxChannel::getID()
+{
+ return WindowsID;
+}
+
+void CRxChannel::setAfcMode ( AfcMode mode )
+{
+ Demodulator->setAfcMode ( mode );
+}
+
+AfcMode CRxChannel::getAfcMode()
+{
+ return Demodulator->getAfcMode();
+}
+int CRxChannel::getSquelchValue()
+{
+ return Demodulator->getSquelchValue();
+}
+void CRxChannel::setThreshold ( int value )
+{
+ Demodulator->setThreshold ( value );
+}
+void CRxChannel::setSquelch ( bool OnOff )
+{
+ Demodulator->setSquelch ( OnOff );
+}
+bool CRxChannel::getSquelchState()
+{
+ return Demodulator->getSquelchState();
+}
+double CRxChannel::getRxFrequency()
+{
+ if ( Demodulator != 0 )
+ return Demodulator->getRxFrequency();
+ else
+ return 0;
+}
+int CRxChannel::getThreshold()
+{
+ return Demodulator->getThreshold();
+}
+void CRxChannel::updateRx ( char c )
+{
+ RxWindow->updateRx ( c );
+}
+void CRxChannel::setWindowColor ( QColor c )
+{
+ RxWindow->setColor ( c );
+}
+void CRxChannel::clearRxWindow()
+{
+ RxWindow->clearRxWindow();
+}
+void CRxChannel::setMode ( Mode DemodulatorType )
+{
+ if ( RxMode != DemodulatorType )
+ {
+ Demodulator->disconnect();
+ double SampleRate = 5512.5;
+ double Freq = Demodulator->getRxFrequency();
+ bool Squelch = Demodulator->getSquelchState();
+ int Threshold = Demodulator->getThreshold();
+ delete Demodulator;
+
+ int BufferLength = BUF_SIZE / 2;
+ switch ( DemodulatorType )
+ {
+ case QPSK:
+ Demodulator = new QPskDemodulator();
+ break;
+ case RTTY:
+ Demodulator = new RTTYDemodulator();
+ SampleRate = 11025;
+ BufferLength = BUF_SIZE;
+ break;
+
+ case MFSK16:
+ Demodulator = new MFSKDemodulator();
+ SampleRate = 11025;
+ BufferLength = BUF_SIZE;
+ break;
+
+ default:
+ Demodulator = new BPskDemodulator();
+ break;
+ }
+ RxMode = DemodulatorType;
+ Demodulator->Init ( SampleRate, BufferLength ); // Should changed later to
+ // adjusted Samplerate
+ Demodulator->setRxFrequency ( Freq );
+ Demodulator->setThreshold ( Threshold );
+ Demodulator->setSquelch ( Squelch );
+ connect ( Demodulator, SIGNAL ( newSymbol ( char ) ), RxWindow, SLOT ( updateRx ( char ) ) );
+
+ }
+}
+void CRxChannel::setQsoData ( QsoInfo *Data )
+{
+ if ( Data )
+ QsoData = *Data;
+}
+QsoInfo *CRxChannel::getQsoData()
+{
+ return &QsoData;
+}
+void CRxChannel::triggered()
+{
+ int i = WindowsID;
+ emit Triggered ( i );
+ QApplication::beep();
+}
+void CRxChannel::record ( bool recording )
+{
+ if ( recording )
+ {
+ QString s;
+ s.setNum ( WindowsID );
+ RxWindow->startRecording ( QString ( "Window_" ) + s + QString ( ".txt" ) );
+ }
+ else
+ RxWindow->stopRecording();
+}
+int CRxChannel::get2RxFrequency()
+{
+ return ( int ) Demodulator->get2RxFrequency();
+}
+float CRxChannel::getIMD()
+{
+ return Demodulator->getIMD();
+}
+void CRxChannel::setParameter ( RxTxParameterType Type, void *Value )
+{
+ Demodulator->setParameter ( Type, Value );
+}
+void *CRxChannel::getParameter ( RxTxParameterType Type )
+{
+ return Demodulator->getParameter ( Type );
+}
+void * CRxChannel::getBuffer()
+{
+ return Demodulator->getBuffer();
+}
+AfcMode CRxChannel::AfcProperties()
+{
+ return Demodulator->AfcProperties();
+}
diff --git a/src/crxchannel.h b/src/crxchannel.h
new file mode 100644
index 0000000..4f8e292
--- /dev/null
+++ b/src/crxchannel.h
@@ -0,0 +1,92 @@
+/***************************************************************************
+ crxchannel.h - description
+ -------------------
+ begin : Sam Jan 4 2003
+ copyright : (C) 2003 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifndef CRXCHANNEL_H
+#define CRXCHANNEL_H
+
+#include "constants.h"
+#include <QObject>
+#include <complex>
+
+#include "cdemodulator.h"
+/**Class to administrate the different RX Channels
+ *@author Volker Schroer
+ */
+class CRxWindow;
+class QWidget;
+#include <qcolor.h>
+
+class CRxChannel : public QObject
+ {
+ Q_OBJECT
+public:
+ CRxChannel(int ID,QWidget* parent=0,Mode DemodulatorType= BPSK,unsigned int Freq=1000);
+virtual ~CRxChannel();
+ void insertChannel(CRxChannel * );
+ void setPrevChannel(CRxChannel *);
+ void changeChain(CRxChannel *);
+ void setGeometry(int,int,int,int);
+ void processInput(double *, double *);
+ AfcMode getAfcMode();
+ AfcMode AfcProperties();
+ CRxChannel *getNextChannel();
+ double getRxFrequency();
+ int get2RxFrequency();
+ Mode getModulationType();
+ int getID();
+ bool getSquelchState();
+ int getSquelchValue();
+ void setThreshold(int);
+ int getThreshold();
+ QColor getWindowColor();
+ void setWindowColor(QColor);
+ void setParameter(RxTxParameterType,void *);
+ void *getParameter(RxTxParameterType);
+ CRxWindow *RxWindow;
+ float getIMD();
+ virtual void *getBuffer();
+public slots:
+ void setRxFrequency(double);
+ void hide();
+ void show();
+ class CRxChannel *getChannel(int);
+ void setAfcMode(AfcMode);
+ std::complex<float>* getPhasePointer();
+ void setSquelch(bool);
+ void updateRx(char);
+ void clearRxWindow();
+ void setMode(Mode);
+ void setQsoData(QsoInfo *);
+ QsoInfo *getQsoData();
+ void record(bool);
+protected:
+
+CDemodulator *Demodulator;
+
+private:
+CRxChannel *nextChannel;
+CRxChannel *prevChannel;
+Mode RxMode;
+int WindowsID;
+QsoInfo QsoData;
+private slots:
+void triggered();
+signals:
+void Triggered(int);
+
+};
+
+#endif
diff --git a/src/crxdisplay.cpp b/src/crxdisplay.cpp
new file mode 100644
index 0000000..0f3dbec
--- /dev/null
+++ b/src/crxdisplay.cpp
@@ -0,0 +1,416 @@
+/***************************************************************************
+ |FILENAME| - description
+ -------------------
+ begin : |DATE|
+ copyright : (C) |YEAR| by |AUTHOR|
+ email : |EMAIL|
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#include "crxdisplay.h"
+
+
+
+#include <QTimer>
+#include <QMessageBox>
+#include <QRadioButton>
+#include <QLineEdit>
+
+#include "crecording.h"
+#include "crxchannel.h"
+#include "crxwindow.h"
+#include "csquelch.h"
+#include "ctrigger.h"
+#include "frequencyselect.h"
+#include "input.h"
+#include "textinput.h"
+#include "waveinput.h"
+#include "csound.h"
+#include "fircoeffs.h"
+#include "parameter.h"
+
+
+extern Parameter settings;
+/*
+ * Constructs a CRxDisplay which is a child of 'parent', with the
+ * name 'name'.'
+ */
+
+
+
+CRxDisplay::CRxDisplay ( QWidget* parent )
+ : QFrame ( parent )
+{
+ setFrameShape ( QFrame::WinPanel );
+ setFrameShadow ( QFrame::Sunken );
+
+ RxFreq = new FrequencySelect ( this, Wide );
+ RxFreq->setTitle ( "Rx Freq / AFC" );
+ RxFreq->setFunctionText ( "Narrow" );
+
+ Recording = new CRecording ( this );
+
+ Trigger = new CTrigger ( "Trigger", this );
+
+ Squelch = new CSquelch ( "Squelch", this );
+
+ RxHeader = new QTabBar ( this );
+ RxHeader->setShape ( QTabBar::RoundedNorth );
+
+ Clear = new QPushButton ( this );
+ Clear->setText ( "Clear" );
+
+// QTab *Tab = new QTab("Rx 1");
+ RxHeader->insertTab ( 0, "Rx 1" );
+ Sound = 0;
+
+ dec2fir = new double[DEC2_LPFIR_LENGTH];
+
+ RxChannel = new CRxChannel ( 0, this );
+ connect ( RxChannel->RxWindow, SIGNAL ( copyCallSign ( QString ) ), this, SIGNAL ( copyCallSign ( QString ) ) );
+ connect ( RxChannel->RxWindow, SIGNAL ( copyQTH ( QString ) ), this, SIGNAL ( copyQTH ( QString ) ) );
+ connect ( RxChannel->RxWindow, SIGNAL ( copyName ( QString ) ), this, SIGNAL ( copyName ( QString ) ) );
+ connect ( RxChannel->RxWindow, SIGNAL ( copyLocator ( QString ) ), this, SIGNAL ( copyLocator ( QString ) ) );
+ connect ( RxChannel->RxWindow, SIGNAL ( copyRST ( QString ) ), this, SIGNAL ( copyRST ( QString ) ) );
+
+ settings.ChannelChain = RxChannel;
+ settings.ActChannel = RxChannel;
+ Squelch->setSquelchState ( RxChannel->getSquelchState() );
+ languageChange();
+// Connect Signals and Slots
+// RxTimer = new QTimer ( this );
+// connect ( RxTimer, SIGNAL ( timeout() ), this, SLOT ( process_rxdata() ) );
+ connect ( RxFreq, SIGNAL ( FrequencyChanged ( double ) ), this, SLOT ( setRxFrequency ( double ) ) );
+ connect ( RxHeader, SIGNAL ( currentChanged ( int ) ), this, SLOT ( changeActiveRxWindow ( int ) ) );
+// connect(RxFreq,SIGNAL(toggleAFC(bool)),this,SLOT(setAFC(bool)));
+ connect ( Trigger->Activate, SIGNAL ( clicked() ), this, SLOT ( trigger() ) );
+ connect ( Trigger->TriggerText, SIGNAL ( returnPressed() ), this, SLOT ( trigger() ) );
+ connect ( RxChannel, SIGNAL ( Triggered ( int ) ), RxHeader, SLOT ( setCurrentTab ( int ) ) );
+
+ connect ( Clear, SIGNAL ( clicked() ), this, SLOT ( clearRxWindow() ) );
+ trigger(); // We should ensure that the triggertext is stored;
+
+// Creating Variables for the fft
+
+// plan=rfftw_create_plan(BUF_SIZE/2,FFTW_REAL_TO_COMPLEX,FFTW_ESTIMATE);
+ plan = fftw_plan_r2r_1d ( BUF_SIZE / 2, outbuf, output, FFTW_R2HC , FFTW_PATIENT );
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+CRxDisplay::~CRxDisplay()
+{
+ // no need to delete child widgets, Qt does it all for us
+}
+
+/*
+ * Sets the strings of the subwidgets using the current
+ * language.
+ */
+void CRxDisplay::languageChange()
+{
+// setCaption( tr( "RxDisplay" ) );
+}
+
+void CRxDisplay::calculateSizeofComponents()
+{
+ /** in percent of whole widget **/
+ /** RX Part **/
+#define RXPARTWIDTH 64
+ /** Squelch **/
+#define SQUELCHWIDTH 10
+ /** General Width **/
+#define GENERALWIDTH 18
+ /** Recording **/
+#define RECORDHEIGHT 25
+ /** Trigger **/
+#define TRIGGERHEIGHT 33
+ /** RxFrequency (Height) **/
+#define RXFREQHEIGHT 70
+ /** Left and Right Margin **/
+#define LEFTANDRIGHTMARGIN 1
+ /** Top and Bottom Margin **/
+#define TOPANDBOTTOMMARGIN 5
+ /** Inner distance **/
+#define DISTANCE 1
+ /** Tab height **/
+#define TABHEIGHT 10
+#define TABWIDTH 30
+ int xpos, ypos, width, height, innerheight, innerwidth;
+ width = this->width();
+ height = this->height();
+ xpos = width * LEFTANDRIGHTMARGIN / 100;
+
+ /**Recording **/
+
+ ypos = height * TOPANDBOTTOMMARGIN / 100;
+ innerwidth = width * GENERALWIDTH / 100;
+ innerheight = height * RECORDHEIGHT / 100;
+ Recording->setGeometry ( xpos, ypos, innerwidth, innerheight );
+ ypos = ypos + innerheight + height * DISTANCE / 100;
+
+ /** Trigger **/
+
+ innerheight = height * TRIGGERHEIGHT / 100;
+ Trigger->setGeometry ( xpos, ypos, innerwidth, innerheight );
+ /** RXFrequency **/
+ ypos = ypos + innerheight + height * DISTANCE / 100;
+ RxFreq->setGeometry ( xpos, ypos, innerwidth, innerheight );
+
+ /**SQuelch **/
+ xpos = xpos + innerwidth + width * DISTANCE / 100;
+ ypos = height * TOPANDBOTTOMMARGIN / 100;;
+ innerheight = height - 2 * ypos;
+ innerwidth = width * SQUELCHWIDTH / 100;
+ Squelch->setGeometry ( xpos, ypos, innerwidth, innerheight );
+
+ /** RxWindowTabBar **/
+ xpos = xpos + innerwidth + width * DISTANCE / 100;
+ innerwidth = ( width - xpos - width * LEFTANDRIGHTMARGIN / 100 ) * TABWIDTH / 100;;
+ innerheight = height * TABHEIGHT / 100;
+ RxHeader->setGeometry ( xpos, ypos, innerwidth, innerheight );
+
+ Clear->setGeometry ( width - width*LEFTANDRIGHTMARGIN / 100 - 100, ypos, 100, innerheight );
+
+ ypos = ypos + innerheight;
+ innerheight = height - innerheight - height * TOPANDBOTTOMMARGIN / 100;
+ innerwidth = width - xpos - width * LEFTANDRIGHTMARGIN / 100;
+ settings.ActChannel->setGeometry ( xpos, ypos, innerwidth, innerheight );
+}
+
+void CRxDisplay::resizeEvent ( QResizeEvent * )
+{
+ calculateSizeofComponents();
+}
+
+bool CRxDisplay::start_process_loop()
+{
+ QString errorstring;
+
+
+ if ( Sound == 0 )
+ {
+ if ( settings.DemoMode )
+ {
+ if ( settings.DemoTypeNumber == 0 )
+ Sound = new WaveInput ( -1 );
+ else
+ Sound = new TextInput ( -1 );
+ }
+ else
+ Sound = new CSound ( settings.serial );
+ if ( Sound <= 0 )
+ return false;
+
+ connect ( Sound, SIGNAL ( samplesAvailable() ), this, SLOT ( process_rxdata() ) );
+ }
+ m_pDec2InPtr = dec2fir;
+
+ for ( int i = 0; i < DEC2_LPFIR_LENGTH;i++ )
+ dec2fir[i] = 0.0; // fill delay buffer with zero
+
+ if ( ! Sound->open_Device_read ( &errorstring ) ) //Something went wrong in Opening Input File
+ {
+ if ( settings.DemoMode )
+ QMessageBox::information ( 0, "LinPsk", errorstring );
+ else
+ QMessageBox::critical ( 0, "LinPsk", errorstring );
+ if ( Sound != 0 )
+ delete Sound;
+ Sound = 0;
+ return false;
+ }
+ Sound->start();
+ return true;
+}
+
+void CRxDisplay::ProcDec2Fir ( double *pIn, double *pOut, int BlockSize )
+{
+ /**
+ Decimate by 2 FIR filter on 'BlockSize' samples.
+ pIn == pointer to input array of double's (can be same buffer as pOut )
+ pOut == pointer to output array of double's
+ Blocksize == number of samples to process
+ This Procdeure is taken from WinPSK by Moe Wheatley
+ **/
+ int i, j;
+ double acc;
+ const double* Kptr;
+ double* Firptr;
+ double* Qptr;
+ double* Inptr;
+ Inptr = m_pDec2InPtr; //use automatic copies of member variables
+ Qptr = dec2fir; // for better speed.
+ j = 0;
+ for ( i = 0; i < BlockSize; i++ ) // put new samples into Queue
+ {
+ if ( --Inptr < Qptr ) //deal with wraparound
+ Inptr = Qptr + DEC2_LPFIR_LENGTH - 1;
+ *Inptr = pIn[i];
+ if ( i&1 ) //calculate MAC's every other time for decimation by 2
+ {
+ acc = 0.0;
+ Firptr = Inptr;
+ Kptr = Dec2LPCoef;
+ while ( Kptr < ( Dec2LPCoef + DEC2_LPFIR_LENGTH ) ) //do the MAC's
+ {
+ acc += ( ( *Firptr++ ) * ( *Kptr++ ) );
+ if ( Firptr >= Qptr + DEC2_LPFIR_LENGTH ) //deal with wraparound
+ Firptr = Qptr;
+ }
+ pOut[j++] = acc; //save output sample
+ }
+ }
+ m_pDec2InPtr = Inptr; // save position in circular delay line
+}
+
+void CRxDisplay::process_rxdata()
+
+{
+ bool overload;
+ if ( Sound->getSamples ( inbuf, BUF_SIZE ) == 0 )
+ return; // No sample available, try later
+
+ overload = false;
+ ProcDec2Fir ( inbuf, outbuf , BUF_SIZE ); // 2uS per sample
+
+
+ RxFreq->setFrequency ( settings.ActChannel->getRxFrequency() );
+ Squelch->setSquelchLevel ( settings.ActChannel->getSquelchValue() );
+ settings.ActChannel->setThreshold ( Squelch->getThreshold() );
+ settings.ActChannel->setSquelch ( Squelch->getSquelchState() );
+ settings.ActChannel->setAfcMode ( RxFreq->getAfcMode() );
+
+ for ( CRxChannel * p = RxChannel;p != 0;p = p->getNextChannel() )
+ if ( ( p->getModulationType() != RTTY ) && ( p->getModulationType() != MFSK16 ) )
+ {
+
+ p->processInput ( outbuf, output );
+ }
+ else
+ p->processInput ( inbuf, output );
+
+ /** Update RxFreq for the active Channel **/
+ emit new_IMD ( settings.ActChannel->getIMD() );
+
+
+// Calculate FFT and start Ploting
+
+// First look for overload
+ int N = BUF_SIZE / 2;
+ for ( int i = 0; i < N;i++ )
+ {
+ if ( outbuf[i] > 0.77 )
+ overload = true;
+// Apply Hamming to Data
+ outbuf[i] *= ( 0.54 - 0.46 * cos ( ( i * PI2 ) / N ) );
+ }
+ fftw_execute ( plan );
+
+//Calculate power spectrum
+ for ( int i = 1;i < BUF_SIZE / 4;i++ )
+ output[i] = output[i] * output[i] + output[BUF_SIZE/2-i] * output[BUF_SIZE/2-i];
+
+ emit startPlotting ( output, overload );
+
+
+}
+
+void CRxDisplay::addRxWindow ( int Frequency, Mode Modulation, QString Heading )
+{
+ CRxChannel *p;
+ int ID = RxHeader->count();
+ RxHeader->insertTab ( ID, Heading );
+ p = new CRxChannel ( ID, this, Modulation, Frequency );
+ connect ( p, SIGNAL ( Triggered ( int ) ), this, SLOT ( changeActiveRxWindow ( int ) ) );
+ connect ( p->RxWindow, SIGNAL ( copyCallSign ( QString ) ), this, SIGNAL ( copyCallSign ( QString ) ) );
+ connect ( p->RxWindow, SIGNAL ( copyQTH ( QString ) ), this, SIGNAL ( copyQTH ( QString ) ) );
+ connect ( p->RxWindow, SIGNAL ( copyName ( QString ) ), this, SIGNAL ( copyName ( QString ) ) );
+ connect ( p->RxWindow, SIGNAL ( copyLocator ( QString ) ), this, SIGNAL ( copyLocator ( QString ) ) );
+ connect ( p->RxWindow, SIGNAL ( copyRST ( QString ) ), this, SIGNAL ( copyRST ( QString ) ) );
+
+ RxChannel->insertChannel ( p );
+ RxHeader->setCurrentIndex ( ID );
+//RxHeader->repaint();
+ trigger(); // We should ensure that the triggertext is stored;
+ RxHeader->setTabTextColor ( ID, Farbe->at ( ID ) );
+}
+
+void CRxDisplay::setRxFrequency ( double freq )
+{
+ settings.ActChannel->setRxFrequency ( freq );
+}
+
+void CRxDisplay::changeActiveRxWindow ( int ID )
+{
+setFocus();
+ if ( settings.ActChannel != 0 )
+ {
+ settings.ActChannel->hide();
+ settings.ActChannel->setQsoData ( settings.QslData ); // Save actual Data to Channel
+ settings.ActChannel->setAfcMode ( RxFreq->getAfcMode() );
+ if ( settings.ActChannel->getChannel ( ID ) != 0 )
+ settings.ActChannel = settings.ActChannel->getChannel ( ID );
+ settings.QslData = settings.ActChannel->getQsoData();
+ RxFreq->setAfcDisplayMode ( settings.ActChannel->AfcProperties() );
+ RxFreq->setAfcMode ( settings.ActChannel->getAfcMode() );
+ RxFreq->setFrequency ( ( unsigned int ) settings.ActChannel->getRxFrequency() );
+ Squelch->setSquelchState ( settings.ActChannel->getSquelchState() );
+ Squelch->setThreshold ( settings.ActChannel->getThreshold() );
+ Trigger->Activate->setChecked ( settings.ActChannel->RxWindow->getTriggerStatus() );
+ Trigger->TriggerText->setText ( settings.ActChannel->RxWindow->getTriggerText() );
+ Recording->Record->setChecked ( settings.ActChannel->RxWindow->getRecordingState() );
+ calculateSizeofComponents();
+ settings.ActChannel->show();
+ emit newActiveChannel();
+ RxHeader->setCurrentIndex ( ID );
+ }
+}
+
+
+void CRxDisplay::stop_process_loop()
+{
+ if ( Sound != 0 )
+ {
+ Sound->stop();
+ Sound->wait();
+ Sound->close_Device();
+ delete Sound;
+ }
+ Sound = 0 ;
+}
+void CRxDisplay::trigger()
+{
+
+ settings.ActChannel->RxWindow->activateTrigger ( Trigger->TriggerText->text() );
+ if ( !Trigger->Activate->isChecked() )
+ settings.ActChannel->RxWindow->deactivateTrigger();
+}
+
+void CRxDisplay::setColorList ( QList<QColor> *c )
+{
+ Farbe = c;
+
+}
+
+void CRxDisplay::clearRxWindow()
+{
+ settings.ActChannel->clearRxWindow();
+}
+void CRxDisplay::newColor()
+{
+ int anzahl = Farbe->size();
+ if ( RxHeader->count() < anzahl )
+ anzahl = RxHeader->count();
+ for ( int i = 0; i < anzahl; i++ )
+ RxHeader->setTabTextColor ( i, Farbe->at ( i ) );
+}
+
diff --git a/src/crxdisplay.h b/src/crxdisplay.h
new file mode 100644
index 0000000..1e46479
--- /dev/null
+++ b/src/crxdisplay.h
@@ -0,0 +1,112 @@
+/***************************************************************************
+ |FILENAME| - description
+ -------------------
+ begin : |DATE|
+ copyright : (C) |YEAR| by |AUTHOR|
+ email : |EMAIL|
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * The PSK part is based on WinPSK 1.0 by Moe Wheatley, AE4JY *
+ ***************************************************************************/
+
+#ifndef CRXDISPLAY_H
+#define CRXDISPLAY_H
+
+#include "constants.h"
+#include <QList>
+#include <QFrame>
+
+#include <fftw3.h>
+#include "constants.h"
+class QTabBar;
+class CRecording;
+class CRxChannel;
+class CSquelch;
+class CTrigger;
+class FrequencySelect;
+class CRxWindow;
+class Input;
+class QTimer;
+class QPushButton;
+
+class CRxDisplay : public QFrame
+{
+ Q_OBJECT
+
+ public:
+ CRxDisplay ( QWidget* parent = 0 );
+ ~CRxDisplay();
+ /** Returns the pointer to the values for Calculating the Spectrum **/
+ double * FFTValues();
+ bool start_process_loop();
+ void stop_process_loop();
+ void newColor();
+
+ FrequencySelect* RxFreq;
+ CRecording* Recording;
+ CTrigger* Trigger;
+ CSquelch* Squelch;
+ void setColorList ( QList<QColor> * );
+ QTabBar* RxHeader;
+
+ public slots:
+ /** Starting receiving/transmitting */
+ void addRxWindow ( int Frequency, Mode Modulation, QString Heading );
+ void setRxFrequency ( double );
+
+
+ protected:
+ virtual void resizeEvent ( QResizeEvent * );
+
+
+ protected slots:
+ virtual void languageChange();
+ void process_rxdata();
+ void changeActiveRxWindow ( int );
+ void trigger();
+ void clearRxWindow();
+ private:
+ void calculateSizeofComponents();
+ QList<QColor> *Farbe;
+ /**
+ Sound is a pointer to the Input Source, may be a File with
+ Demo Samples (text or wav), or the soundcard ( /dev/audio )
+ **/
+ Input *Sound;
+ QPushButton *Clear;
+ /** Pointer to input Buffer **/
+// double *inbuf;
+ double inbuf[BUF_SIZE];
+ CRxChannel *RxChannel;
+ /** Decimation Filter to reduce samplerate */
+ void ProcDec2Fir ( double *pIn, double *pOut, int BlockSize );
+ double *dec2fir; // queue for decimation by 2 filter
+// double *outbuf; // outputbuffer
+ double outbuf[BUF_SIZE];
+ double *m_pDec2InPtr;
+ /** Timer ** for polling the soundcard **/
+ //QTimer *RxTimer;
+//fftw_real* output;
+ double output[BUF_SIZE/2];
+ fftw_plan plan;
+
+ signals:
+
+ void startPlotting ( double *, bool );
+ void newActiveChannel();
+ void new_IMD ( float );
+void copyCallSign(QString);
+void copyQTH(QString);
+void copyName(QString);
+void copyLocator(QString);
+void copyRST(QString);
+
+};
+
+#endif // CRXDISPLAY_H
diff --git a/src/crxwindow.cpp b/src/crxwindow.cpp
new file mode 100644
index 0000000..68a70b9
--- /dev/null
+++ b/src/crxwindow.cpp
@@ -0,0 +1,291 @@
+/***************************************************************************
+ crxwindow.cpp - description
+ -------------------
+ begin : Mon Mar 6 2000
+ copyright : (C) 2000 by Volker Schroer
+ email : DL1KSV at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#include "crxwindow.h"
+#include <QLineEdit>
+#include <QFontMetrics>
+#include <QMenu>
+
+#include "parameter.h"
+
+extern Parameter settings;
+/*
+ * Constructs a CRxWindow which is a child of 'parent', with the
+ * name 'name'.'
+ */
+CRxWindow::CRxWindow ( QWidget* parent )
+ : QScrollArea ( parent )
+{
+ QFontMetrics fm ( font() );
+ rowHeight = fm.height();
+ DisplayBox = new QWidget ( this );
+ DisplayBox->setFixedSize ( 642, RXWINDOWBUFFER*rowHeight );
+ DisplayBox->setContextMenuPolicy ( Qt::CustomContextMenu );
+ connect ( DisplayBox, SIGNAL ( customContextMenuRequested ( QPoint ) ), this, SLOT ( contextMenu ( QPoint ) ) );
+
+ setWidget ( DisplayBox );
+
+ setHorizontalScrollBarPolicy ( Qt::ScrollBarAlwaysOff );
+ setVerticalScrollBarPolicy ( Qt::ScrollBarAlwaysOn );
+
+ trigger = false;
+ TriggerText = "";
+ TexttoTrigger = "";
+ save = false;
+ stream = 0;
+ Row = 0;
+ Column = 0;
+ AutoScroll = true;
+ DisplayLineHeight = rowHeight - 2;
+ for ( int i = 0;i < RXWINDOWBUFFER;i++ )
+ {
+
+ ScrollBuffer[i] = new QLineEdit ( DisplayBox );
+ ScrollBuffer[i]->move ( 1, 1 + DisplayLineHeight*i );
+
+ ScrollBuffer[i]->setFrame ( false );
+ ScrollBuffer[i]->setReadOnly ( true );
+ ScrollBuffer[i]->setFixedHeight ( rowHeight );
+ ScrollBuffer[i]->setContextMenuPolicy ( Qt::NoContextMenu );
+ ScrollBuffer[i]->show();
+ }
+ setBackgroundRole ( ScrollBuffer[0]->backgroundRole() );
+ menu = new QMenu ( tr ( "Log value" ), DisplayBox );
+ QAction *A = menu->addAction ( tr ( "Callsign" ) );
+ connect ( A, SIGNAL ( triggered() ), this, SLOT ( copyCallSign() ) );
+ A = menu->addAction ( "QTH" );
+ connect ( A, SIGNAL ( triggered() ), this, SLOT ( copyQTH() ) );
+ A = menu->addAction ( "Name" );
+ connect ( A, SIGNAL ( triggered() ), this, SLOT ( copyName() ) );
+ A = menu->addAction ( tr ( "Locator" ) );
+ connect ( A, SIGNAL ( triggered() ), this, SLOT ( copyLocator() ) );
+ A = menu->addAction ( "Raport" );
+ connect ( A, SIGNAL ( triggered() ), this, SLOT ( copyRST() ) );
+
+ selectedString.clear();
+
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+CRxWindow::~CRxWindow()
+{
+ for ( int i = 0;i < RXWINDOWBUFFER;i++ )
+ {
+
+ if ( ScrollBuffer[i] )
+ delete ScrollBuffer[i];
+ ScrollBuffer[i] = 0;
+ }
+
+ // no need to delete child widgets, Qt does it all for us
+}
+void CRxWindow::updateRx ( char c )
+{
+ switch ( c )
+ {
+ case '\n':
+ case '\r':
+ NeueZeile();
+ break;
+
+ case '\b':
+ if ( Column > 0 )
+ {
+ Column--;
+ QString s = ScrollBuffer[Row]->text();
+ s.truncate ( Column );
+ ScrollBuffer[Row]->setText ( s );
+ if ( trigger && ( settings.Status == OFF ) )
+ {
+ if ( TriggerText.length() > 0 )
+ TriggerText.remove ( TriggerText.length(), 1 );
+ }
+ }
+ break;
+
+ case '0':
+ if ( settings.slashed0 )
+ c = 0xF8;
+ default:
+ if ( trigger && ( settings.Status == OFF ) )
+ {
+ TriggerText.append ( c );
+ if ( TriggerText.length() > TexttoTrigger.length() )
+ {
+ TriggerText.remove ( 0, 1 );
+ if ( TriggerText.toLower() == TexttoTrigger.toLower() )
+ {
+ trigger = false; // Stop
+ emit Triggered();
+ }
+ }
+ }
+ QString s = ScrollBuffer[Row]->text() + QString ( QChar ( c ) );
+ ScrollBuffer[Row]->setText ( s );
+ Column++;
+
+ if ( Column >= 80 )
+ NeueZeile();
+ }
+
+
+}
+
+void CRxWindow::clearRxWindow()
+{
+ Column = 0;
+ Row = 0;
+ for ( int i = 0;i < RXWINDOWBUFFER;i++ )
+ ScrollBuffer[i]->setText ( "" );
+ ensureVisible ( 0, Row*rowHeight, 20, 15 );
+}
+
+
+void CRxWindow::removeLines ( int number2Remove )
+{
+ int i;
+ for ( i = number2Remove; i < RXWINDOWBUFFER; i++ )
+ ScrollBuffer[i-number2Remove]->setText ( ScrollBuffer[i]->text() );
+ for ( i = RXWINDOWBUFFER - number2Remove;i < RXWINDOWBUFFER;i++ )
+ ScrollBuffer[i]->setText ( "" );
+}
+
+void CRxWindow::NeueZeile()
+{
+
+ Column = 0;
+ Row++;
+ if ( Row >= RXWINDOWBUFFER )
+ {
+ if ( save && stream != 0 )
+ for ( int i = 0;i < 10; i++ )
+ *stream << ScrollBuffer[i]->text() << "\n";
+ removeLines ( 10 );
+ Row -= 10;
+ }
+ if ( ! AutoScroll )
+ return;
+// ensureVisible ( 0, Row*rowHeight, 20, 15 );
+ ensureWidgetVisible ( ( QWidget* ) ScrollBuffer[Row] );
+}
+void CRxWindow::setColor ( QColor color )
+{
+
+ for ( int i = 0;i < RXWINDOWBUFFER;i++ )
+ ScrollBuffer[i]->setStyleSheet ( "QLineEdit{color: " + color.name() + "; }" );
+}
+
+void CRxWindow::fontChange ( const QFont & )
+{
+ QFontMetrics fm ( font() );
+ for ( int i = 0;i < RXWINDOWBUFFER;i++ )
+ ScrollBuffer[i]->setFixedHeight ( fm.height() );
+}
+void CRxWindow::activateTrigger ( QString s )
+{
+ trigger = true;
+ TexttoTrigger = s;
+ TriggerText = "";
+}
+void CRxWindow::deactivateTrigger()
+{
+ trigger = false;
+}
+bool CRxWindow::getTriggerStatus()
+{
+ return trigger;
+}
+QString CRxWindow::getTriggerText()
+{
+ return TexttoTrigger;
+}
+
+void CRxWindow::stopRecording()
+{
+ /** Save all ScrollBuffer in Buffer **/
+ if ( save )
+ {
+ for ( int i = 0; i <= Row; i++ )
+ *stream << ScrollBuffer[i]->text() << "\n";
+ File.close();
+ save = false;
+ delete stream;
+ }
+}
+void CRxWindow::startRecording ( QString Datei )
+{
+ if ( !save )
+ {
+ File.setFileName ( Datei );
+ File.open ( QIODevice::WriteOnly );
+ save = true;
+ stream = new QTextStream ( &File );
+ }
+}
+bool CRxWindow::getRecordingState()
+{
+ return save;
+}
+
+void CRxWindow::resizeEvent ( QResizeEvent * )
+{
+ int width = this->width();
+ DisplayBox->setFixedWidth ( width );;
+ for ( int i = 0;i < RXWINDOWBUFFER;i++ )
+ ScrollBuffer[i]->setFixedWidth ( width );
+}
+void CRxWindow::contextMenu ( QPoint p )
+{
+ int selectedLine, selectedColumn;
+ char c = 0xF8;
+ QPoint p1 = QCursor::pos();
+ selectedLine = p.y() / DisplayLineHeight;
+ selectedColumn = ScrollBuffer[selectedLine]->cursorPositionAt ( QPoint ( p.x(), 2 ) );
+ ScrollBuffer[selectedLine]->setCursorPosition ( selectedColumn );
+ ScrollBuffer[selectedLine]->cursorWordForward ( true );
+ selectedString = ScrollBuffer[selectedLine]->selectedText();
+ selectedString = selectedString.replace ( QChar ( c ), QLatin1String ( "0" ) ); // Replace Slashed zero by zero
+ if ( selectedString == QString ( " " ) )
+ {
+ ScrollBuffer[selectedLine]->setCursorPosition ( selectedColumn + 1 );
+ ScrollBuffer[selectedLine]->cursorWordForward ( true );
+ selectedString = ScrollBuffer[selectedLine]->selectedText();
+ }
+ qDebug ( "Copy %s", qPrintable ( selectedString ) );
+ menu->exec ( p1 );
+}
+void CRxWindow::copyCallSign()
+{
+ emit copyCallSign ( selectedString );
+}
+void CRxWindow::copyQTH()
+{
+ emit copyQTH ( selectedString );
+}
+void CRxWindow::copyName()
+{
+ emit copyName ( selectedString );
+}
+void CRxWindow::copyLocator()
+{
+ emit copyLocator ( selectedString );
+}
+void CRxWindow::copyRST()
+{
+ emit copyRST ( selectedString );
+}
diff --git a/src/crxwindow.h b/src/crxwindow.h
new file mode 100644
index 0000000..e174453
--- /dev/null
+++ b/src/crxwindow.h
@@ -0,0 +1,90 @@
+/***************************************************************************
+ crxwindow.h - description
+ -------------------
+ begin : Mon Mar 6 2000
+ copyright : (C) 2000 by Volker Schroer
+ email : DL1KSV at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifndef CRXWINDOW_H
+#define CRXWINDOW_H
+
+#include <QScrollArea>
+#include "constants.h"
+
+#include <QFile>
+#include <QTextStream>
+class QLineEdit;
+class QWidget;
+class QString;
+class QMenu;
+class CRxWindow : public QScrollArea
+{
+ Q_OBJECT
+
+ public:
+ CRxWindow ( QWidget* parent = 0 );
+ ~CRxWindow();
+ bool getTriggerStatus();
+ QString getTriggerText();
+ void stopRecording();
+ void startRecording ( QString );
+ bool getRecordingState();
+ public slots:
+ void updateRx ( char );
+ void clearRxWindow();
+ void setColor ( QColor );
+ void activateTrigger ( QString );
+ void deactivateTrigger();
+ void contextMenu ( QPoint );
+
+ protected:
+ virtual void fontChange ( const QFont & );
+ virtual void resizeEvent ( QResizeEvent * e );
+
+ protected slots:
+ void copyCallSign();
+ void copyQTH();
+ void copyName();
+ void copyLocator();
+ void copyRST();
+
+ private:
+
+
+ QLineEdit* ScrollBuffer[RXWINDOWBUFFER];
+
+ int Row, Column, rowHeight;
+ void removeLines(int);
+ void NeueZeile();
+ QWidget* DisplayBox;
+ bool AutoScroll;
+ bool trigger;
+ QString TriggerText;
+ QString TexttoTrigger;
+ bool save;
+ QFile File;
+ QTextStream *stream;
+
+ QMenu *menu;
+ QString selectedString;
+ int DisplayLineHeight;
+ signals:
+ void Triggered();
+ void copyCallSign ( QString );
+ void copyQTH ( QString );
+ void copyName ( QString );
+ void copyLocator ( QString );
+ void copyRST ( QString );
+
+};
+
+#endif // CRXWINDOW_H
diff --git a/src/csound.cpp b/src/csound.cpp
new file mode 100644
index 0000000..fe43d8e
--- /dev/null
+++ b/src/csound.cpp
@@ -0,0 +1,498 @@
+/***************************************************************************
+ csound.cpp - description
+ -------------------
+ begin : Wed Apr 5 2000
+ copyright : (C) 2000 by Volker Schroer
+ email : huv.schroer at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#include "csound.h"
+#include "parameter.h"
+#include <cstdlib>
+
+using namespace std;
+extern Parameter settings;
+CSound::CSound ( int ptt = -1 ) : Input ( ptt )
+{
+ started = false;
+ output = false;
+ freePointer = 0;
+ available = 0;
+ readPointer = 0;
+ free = 2 * BUF_SIZE;
+
+}
+CSound::~CSound()
+{
+}
+
+int CSound::getSamples ( double *sample, int anzahl )
+{
+ if ( !started )
+ return 0;
+ if ( anzahl > available )
+ return 0;
+ memcpy ( sample, &buffer[readPointer], anzahl*sizeof ( double ) ) ;
+ LockPointers.lock();
+ available -= anzahl;
+ free += anzahl;
+ WakeUp.wakeAll();
+ LockPointers.unlock();
+ readPointer += anzahl;
+ readPointer %= ( 2 * BUF_SIZE );
+ return anzahl;
+}
+
+bool CSound::open_Device_read ( QString *errorstring )
+{
+ int err;
+ snd_pcm_hw_params_t *hwparams;
+ snd_pcm_sw_params_t *swparams;
+ snd_pcm_uframes_t period_size = 512;
+ unsigned int SampleRate = 11025;
+ output = false;
+ freePointer = 0;
+ available = 0;
+ readPointer = 0;
+ free = 2 * BUF_SIZE;
+
+ err = snd_pcm_open ( &handle, "LinPSK_Record", SND_PCM_STREAM_CAPTURE, SND_PCM_ASYNC );
+
+ if ( err < 0 )
+ {
+ *errorstring = QString ( "Unable to open Device LinPSK_Record: " ) + QString ( snd_strerror ( err ) ) + QString ( "\nPlease read the README for configuration hints\n" );
+ return false;
+ }
+ snd_pcm_hw_params_malloc ( &hwparams );
+ snd_pcm_sw_params_malloc ( &swparams );
+
+ /* Choose all parameters */
+ err = snd_pcm_hw_params_any ( handle, hwparams );
+ if ( err < 0 )
+ {
+ *errorstring = QString ( "Broken configuration : no configurations available: " ) + QString ( snd_strerror ( err ) );
+ return false;
+ }
+ /* Set the interleaved read/write format */
+ err = snd_pcm_hw_params_set_access ( handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED );
+ if ( err < 0 )
+ {
+ *errorstring = QString ( "Access type not available : " ) + QString ( snd_strerror ( err ) );
+ return false;
+ }
+ /* Set the sample format */
+ err = snd_pcm_hw_params_set_format ( handle, hwparams, SND_PCM_FORMAT_FLOAT_LE );
+ if ( err < 0 )
+ {
+ *errorstring = QString ( "Sample format Float not available : " ) + QString ( snd_strerror ( err ) );
+ return false;
+ }
+ /* Set the count of channels, most soundcards only support stereo */
+ err = snd_pcm_hw_params_set_channels ( handle, hwparams, 2 );
+ if ( err < 0 )
+ {
+ *errorstring = QString ( "Channels count 2 not available, please modify your plugin: " ) + QString ( snd_strerror ( err ) );
+ return false;
+ }
+
+ err = snd_pcm_hw_params_set_rate ( handle, hwparams, SampleRate, 0 );
+ if ( err < 0 )
+ {
+ *errorstring = QString ( "Samplerate %1 not available for capture: " ).arg ( SampleRate ) + QString ( snd_strerror ( err ) );
+ return false;
+ }
+ int kkk = 0;
+ err = snd_pcm_hw_params_set_period_size_near ( handle, hwparams, &period_size, &kkk );
+ if ( err < 0 )
+ {
+ *errorstring = QString ( "Unable to set period size %d for play: " ).arg ( period_size ) + QString ( snd_strerror ( err ) );
+ return false;
+ }
+ snd_pcm_uframes_t buffer_size = 2048;
+ err = snd_pcm_hw_params_set_buffer_size_near ( handle, hwparams, &buffer_size );
+ if ( err < 0 )
+ {
+ *errorstring = QString ( "Unable to set buffer size %i for capture: " ).arg ( buffer_size ) + QString ( snd_strerror ( err ) );
+ return false;
+ }
+ err = snd_pcm_hw_params ( handle, hwparams );
+ if ( err < 0 )
+ {
+ *errorstring = QString ( "Unable to set hw params for input: " ) + QString ( snd_strerror ( err ) );
+ return false;
+ }
+ snd_pcm_hw_params_free ( hwparams );
+ /* Get the current swparams */
+ err = snd_pcm_sw_params_current ( handle, swparams );
+ if ( err < 0 )
+ {
+ *errorstring = QString ( "Unable to determine current swparams for capture: " ) + QString ( snd_strerror ( err ) );
+ return false;
+ }
+
+ err = snd_pcm_sw_params_set_start_threshold ( handle, swparams, 1 );
+ if ( err < 0 )
+ {
+ *errorstring = QString ( "Unable to set start threshold for capture: " ) + QString ( snd_strerror ( err ) );
+ return false;
+ }
+
+ /* Write the parameters to the record device */
+ err = snd_pcm_sw_params ( handle, swparams );
+ if ( err < 0 )
+ {
+ *errorstring = QString ( "Unable to set sw params for input: " ) + QString ( snd_strerror ( err ) );
+ return false;
+ }
+ snd_pcm_sw_params_free ( swparams );
+
+ output = false;
+ err = snd_pcm_start ( handle );
+ if ( err <= 0 )
+ started = true;
+ else
+ {
+ *errorstring = QString ( "Unable to start soundcard for receiving: " ) + QString ( snd_strerror ( err ) );
+ started = false;
+ return false;
+ }
+
+ return true;
+}
+
+
+bool CSound::open_Device_write ( QString *errorstring )
+{
+ int err;
+ snd_pcm_hw_params_t *hwparams;
+ snd_pcm_sw_params_t *swparams;
+ snd_pcm_uframes_t period_size = 1024;
+ unsigned int SampleRate = 11025;
+ output = true;
+ qDebug ( "Open Device write" );
+ err = snd_pcm_open ( &handle, "LinPSK_Play", SND_PCM_STREAM_PLAYBACK, 0 );
+ if ( err < 0 )
+ {
+ *errorstring = QString ( "Unable to open Device LinPSK_Play: " ) + QString ( snd_strerror ( err ) );
+ return false;
+ }
+// Set blocking mode
+ err = snd_pcm_nonblock ( handle, 0 );
+
+ snd_pcm_hw_params_malloc ( &hwparams );
+ snd_pcm_sw_params_malloc ( &swparams );
+
+ /* Choose all parameters */
+ err = snd_pcm_hw_params_any ( handle, hwparams );
+ if ( err < 0 )
+ {
+ *errorstring = QString ( "Broken configuration : no configurations available: " ) + QString ( snd_strerror ( err ) );
+ return false;
+ }
+ /* Set the interleaved read/write format */
+ err = snd_pcm_hw_params_set_access ( handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED );
+
+ if ( err < 0 )
+ {
+ *errorstring = QString ( "Access type not available : " ) + QString ( snd_strerror ( err ) );
+ return false;
+ }
+ /* Set the sample format */
+ err = snd_pcm_hw_params_set_format ( handle, hwparams, SND_PCM_FORMAT_FLOAT_LE );
+ if ( err < 0 )
+ {
+ *errorstring = QString ( "Sample format Float not available : " ) + QString ( snd_strerror ( err ) );
+ return false;
+ }
+ /* Set the count of channels */
+ err = snd_pcm_hw_params_set_channels ( handle, hwparams, 2 );
+ if ( err < 0 )
+ {
+ *errorstring = QString ( "Channels count 2 not available, please modify your plugin: " ) + QString ( snd_strerror ( err ) );
+ return false;
+ }
+
+ err = snd_pcm_hw_params_set_rate ( handle, hwparams, SampleRate, 0 );
+ if ( err < 0 )
+ {
+ *errorstring = QString ( "Samplerate %1 not available for playing: " ).arg ( SampleRate ) + QString ( snd_strerror ( err ) );
+ return false;
+ }
+ int kkk = 0;
+ err = snd_pcm_hw_params_set_period_size_near ( handle, hwparams, &period_size, &kkk );
+ if ( err < 0 )
+ {
+ *errorstring = QString ( "Unable to set period size %d for play: " ).arg ( period_size ) + QString ( snd_strerror ( err ) );
+ return false;
+ }
+ snd_pcm_uframes_t buffer_size = 9192;
+ err = snd_pcm_hw_params_set_buffer_size_near ( handle, hwparams, &buffer_size );
+ if ( err < 0 )
+ {
+ *errorstring = QString ( "Unable to set buffer size %i for play: " ).arg ( buffer_size ) + QString ( snd_strerror ( err ) );
+ return false;
+ }
+ else
+ qDebug("Buffersize set to %i",buffer_size);
+ err = snd_pcm_hw_params ( handle, hwparams );
+ if ( err < 0 )
+ {
+ *errorstring = QString ( "Unable to set hw params for input: " ) + QString ( snd_strerror ( err ) );
+ return false;
+ }
+ snd_pcm_hw_params_free ( hwparams );
+ /* Get the current swparams */
+ err = snd_pcm_sw_params_current ( handle, swparams );
+ if ( err < 0 )
+ {
+ *errorstring = QString ( "Unable to determine current swparams for play: " ) + QString ( snd_strerror ( err ) );
+ return false;
+ }
+ snd_pcm_uframes_t threshold=buffer_size/2;
+ if ( threshold > 2048)
+ threshold=2048;
+ err = snd_pcm_sw_params_set_start_threshold ( handle, swparams, threshold );
+ if ( err < 0 )
+ {
+ *errorstring = QString ( "Unable to set start threshold mode : " ) + QString ( snd_strerror ( err ) );
+ return false;
+ }
+ else
+ qDebug("Setting start threshold to %i", threshold);
+ /* Write the parameters to the record/playback device */
+ err = snd_pcm_sw_params ( handle, swparams );
+ if ( err < 0 )
+ {
+ *errorstring = QString ( "Unable to set sw params for output: " ) + QString ( snd_strerror ( err ) );
+ return false;
+ }
+ output = true;
+ return true;
+}
+
+int CSound::putSamples ( double *sample, int anzahl )
+{
+ if ( anzahl <= free )
+ {
+ memcpy ( &buffer[freePointer], sample, anzahl*sizeof ( double ) );
+ LockPointers.lock();
+ toBePlayed += anzahl;
+ free -= anzahl;
+ if ( toBePlayed > 2*BUF_SIZE )
+ qDebug ( "putSamples: Bufferoverrun" );
+ WakeUp.wakeAll();
+ LockPointers.unlock();
+
+ freePointer += anzahl;
+ freePointer %= ( 2 * BUF_SIZE );
+
+ }
+ else
+ {
+ anzahl=0;
+ qDebug ( "++++++free too low %d", free );
+ }
+ return anzahl;
+}
+
+void CSound::PTT ( bool mode )
+{
+ int flags;
+ int ii;
+ flags = TIOCM_RTS | TIOCM_DTR;
+ if ( serial < 0 ) // No serial Device selected
+ {
+// No PTT, only start stream
+ if ( mode )
+ {
+ if ( !started )
+ {
+ started = true;
+ }
+ }
+ else
+ {
+ if ( started )
+ {
+ started = false;
+ }
+ }
+ return;
+ }
+ if ( mode ) // PTT on
+ {
+ ii = ioctl ( serial, TIOCMBIS, &flags );
+ if ( !started )
+ {
+ started = true;
+ }
+ }
+ else
+ {
+ if ( started )
+ {
+ started = false;
+ }
+ ii = ioctl ( serial, TIOCMBIC, &flags );
+ }
+ return;
+}
+
+bool CSound::close_Device()
+{
+ wait();
+ if ( handle != 0 )
+ snd_pcm_close ( handle );
+ handle = 0;
+ started = false;
+ output = false;
+ return true;
+}
+
+void CSound::run()
+{
+ started = true;
+ if ( !output )
+ record();
+ else
+ play();
+
+}
+void CSound::record()
+{
+ int toBeRead, err;
+ float SampleBuffer[256];
+ qDebug ( "Start recording" );
+ while ( started )
+ {
+ LockPointers.lock();
+ while ( free < 128 && started )
+ WakeUp.wait ( &LockPointers );
+ LockPointers.unlock();
+ if ( !started )
+ break;
+ toBeRead = min ( free, 128 );
+ if ( toBeRead > BUF_SIZE )
+ {
+ qDebug ( "Error toBeRead zu gross" );
+ return;
+ }
+ if ( ( freePointer + toBeRead ) > 2*BUF_SIZE )
+ qDebug ( "Out of Bounds \n" );
+ err = snd_pcm_readi ( handle, SampleBuffer, toBeRead );
+ if ( err == toBeRead )
+ {
+ for ( int i = 0; i < toBeRead;i++ )
+ buffer[freePointer+i] = SampleBuffer[2*i];
+ LockPointers.lock();
+ available += toBeRead;
+ free -= toBeRead;
+ LockPointers.unlock();
+ freePointer = ( freePointer + toBeRead ) % ( 2 * BUF_SIZE );
+ if ( available >= BUF_SIZE )
+ emit samplesAvailable();
+ }
+ else
+ {
+ if ( err == -EPIPE )
+ {
+ // Overrun
+ snd_pcm_prepare ( handle );
+ snd_pcm_start ( handle );
+ qDebug ( "Record: Overrun" );
+ }
+ else
+ {
+ qDebug ( "Record: unhandled error %d\n %s\n", err, snd_strerror ( err ) );
+ return ;
+ }
+ }
+ }
+ snd_pcm_drop ( handle );
+ qDebug ( "record thread terminated" );
+}
+
+void CSound::play()
+{
+ float SampleBuffer[256], x;
+ bool signaled;
+ int err, laenge;
+ laenge = 128;
+ signaled = false;
+ freePointer = 0;
+ readPointer = 0;
+ free = 2 * BUF_SIZE;
+ toBePlayed = 0;
+ qDebug ( "Play thread started" );
+
+ while ( started )
+ {
+ LockPointers.lock();
+ if ( toBePlayed <= BUF_SIZE && ( !signaled ) )
+ {
+ emit samplesAvailable();
+ signaled = true;
+ }
+ if ( free > ( 2* BUF_SIZE ) )
+ qDebug ( "Out of bounds" );
+ while ( toBePlayed < laenge && started )
+ WakeUp.wait ( &LockPointers );
+ LockPointers.unlock();
+ if ( !started )
+ {
+ qDebug ( "Stop received" );
+ break;
+ }
+ if ( toBePlayed >= BUF_SIZE )
+ signaled = false;
+ for ( int i = 0;i < laenge;i++ )
+ {
+ x = buffer[readPointer+i];
+ SampleBuffer[2*i] = x;
+ SampleBuffer[2*i+1] = x;
+ }
+ err = snd_pcm_writei ( handle, SampleBuffer , laenge );
+ if ( err == laenge )
+ {
+ LockPointers.lock();
+ toBePlayed -= err;
+ free += err;
+ readPointer = ( readPointer + err ) % ( 2 * BUF_SIZE );
+ LockPointers.unlock();
+ }
+ else
+ {
+ if ( err == -EPIPE )
+ {
+ /* under-run */
+ qDebug ( "Underun in Play position 2 laenge %d Pointer %d available %d\n", laenge, readPointer, toBePlayed );
+ err = snd_pcm_prepare ( handle );
+ if ( err < 0 )
+ {
+ qDebug ( "Can't recover from underrun, prepare failed: %s\nStopping Play Thread", snd_strerror ( err ) );
+ break;
+ }
+ }
+ else if ( err == -EAGAIN )
+ qDebug ( "Play ???? \n" );
+ else
+ {
+ qDebug("Errorcode %i",err);
+ qDebug ( " %s\nStopping Play Thread", snd_strerror ( err ) );
+ break;
+ }
+
+ }
+ }
+ qDebug ( "Now dropping" );
+ snd_pcm_drop ( handle );
+ qDebug ( "Play Thread terminated" );
+}
diff --git a/src/csound.h b/src/csound.h
new file mode 100644
index 0000000..3dc696c
--- /dev/null
+++ b/src/csound.h
@@ -0,0 +1,63 @@
+/***************************************************************************
+ csound.h - description
+ -------------------
+ begin : Wed Apr 5 2000
+ copyright : (C) 2000 by Volker Schroer
+ email : DL1KSV at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifndef CSOUND_H
+#define CSOUND_H
+
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <QMutex>
+#include <QWaitCondition>
+#include "input.h"
+#include "constants.h"
+#include <alsa/asoundlib.h>
+#define ALSA_PCM_NEW_HW_PARAMS_API
+#define ALSA_PCM_NEW_SW_PARAMS_API
+
+/**Class for operating on SoundCard
+ *@author Volker Schroer
+ */
+class CSound : public Input
+{
+ public:
+ CSound ( int ptt );
+ ~CSound();
+ virtual bool open_Device_write ( QString * );
+ virtual bool open_Device_read ( QString * );
+ virtual bool close_Device();
+ int getSamples ( double *, int ); // Reading Samples from Soundcard
+ int putSamples ( double *, int ); // Writing Samples to Soundcard
+ void PTT ( bool );
+
+ private: // Private attributes
+ snd_pcm_t *handle;
+ bool output;
+ double buffer[2*BUF_SIZE]; // 16 bit , stereo
+ QMutex LockPointers;
+ QWaitCondition WakeUp;
+ void record();
+ void play();
+ protected:
+ void run();
+ int free, freePointer, available, readPointer,toBePlayed;
+
+};
+
+#endif
diff --git a/src/csquelch.cpp b/src/csquelch.cpp
new file mode 100644
index 0000000..acbbb01
--- /dev/null
+++ b/src/csquelch.cpp
@@ -0,0 +1,187 @@
+/***************************************************************************
+ |FILENAME| - description
+ -------------------
+ begin : |DATE|
+ copyright : (C) |YEAR| by |AUTHOR|
+ email : |EMAIL|
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#include "csquelch.h"
+#include "color.h"
+#include <QPalette>
+#include <QRadioButton>
+#include <QLabel>
+#include <QPainter>
+#include <QColor>
+#include <QPolygon>
+#include <QLabel>
+#include <QStyleOptionSlider>
+#include <QStylePainter>
+#include <QStyle>
+
+#define Cyan color[127]
+#define Yellow color[192]
+
+mySlider::mySlider ( QWidget *parent ) :
+ QSlider ( Qt::Vertical, parent )
+{
+ setTickInterval ( 10 );
+ setTickPosition ( QSlider::NoTicks );
+ setMinimum ( 0 );
+ setMaximum ( 100 );
+
+ setValue ( 50 );
+ SquelchLevel = 0;
+
+}
+
+mySlider::~mySlider()
+{}
+/** Painting Slider Background depending on Threshold and Signal Strength
+*/
+
+void mySlider::paintEvent ( QPaintEvent * )
+{
+
+ QStylePainter p;
+
+ int scale;
+ p.begin ( this );
+// Get Parameters of the Slider
+ initStyleOption ( &option );
+ option.type = QStyleOption::SO_Slider;
+ option.subControls = QStyle::SC_SliderGroove;
+ const QColor c0 = option.palette.color ( QPalette::Window );
+ QRect groove = option.rect;
+ if ( SquelchLevel > 0 )
+ {
+ // Draw the two parts of the slider groove, if we have a signal
+ int height = option.rect.height();
+ scale = ( height * ( 100 - SquelchLevel ) ) / 100;
+ // Set Color depending on signal strength
+
+ if ( SquelchLevel < option.sliderValue ) // Too low
+ option.palette.setColor ( QPalette::Window, Yellow );
+ else
+ option.palette.setColor ( QPalette::Window, Cyan );
+ p.drawComplexControl ( QStyle::CC_Slider, option );
+ option.rect.setHeight ( scale );
+ }
+ option.palette.setColor ( QPalette::Window, c0 );
+ p.drawComplexControl ( QStyle::CC_Slider, option );
+ option.rect = groove;
+ option.subControls = QStyle::SC_SliderHandle;
+ p.drawComplexControl ( QStyle::CC_Slider, option );
+
+}
+
+void mySlider::setSquelchLevel ( int level )
+{
+ SquelchLevel = level;
+ repaint();
+}
+
+int mySlider::getThreshold()
+{
+ return value();
+}
+
+/*
+ * Constructs a CSquelch which is a child of 'parent', with the
+ * name 'name'.'
+ */
+CSquelch::CSquelch ( const QString name, QWidget* parent )
+ : QGroupBox ( name, parent )
+{
+ setAlignment ( int ( Qt::AlignHCenter ) );
+
+ Activate = new QRadioButton ( tr ( "On/Off" ), this );
+ Activate->setGeometry ( QRect ( 120, 340, 60, 41 ) );
+
+
+ Squelch = new mySlider ( this );
+//connect(Squelch,SIGNAL(sliderMoved(int)),this,SLOT(setThreshold(int)));
+
+ languageChange();
+
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+CSquelch::~CSquelch()
+{
+ // no need to delete child widgets, Qt does it all for us
+}
+
+/*
+ * Sets the strings of the subwidgets using the current
+ * language.
+ */
+void CSquelch::languageChange()
+{
+ setTitle ( tr ( "Squelch" ) );
+}
+void CSquelch::resizeEvent ( QResizeEvent * )
+{
+ calculateSizeofComponents();
+}
+
+void CSquelch::calculateSizeofComponents()
+{
+ /** Margins **/
+#define TOPMARGIN 10
+ /** WIDTH and Height in % **/
+#define SQUELCHWIDTH 25
+#define SQUELCHHEIGHT 70
+#define BUTTONWIDTH 75
+#define BUTTONHEIGHT 10
+
+ int xpos, ypos, width, height, innerwidth, innerheight;
+
+ width = this->width();
+ height = this->height();
+ innerwidth = width * SQUELCHWIDTH / 100;
+ xpos = ( width - innerwidth ) / 2;
+ ypos = height * TOPMARGIN / 100;
+ innerheight = height * SQUELCHHEIGHT / 100;
+ Squelch->setGeometry ( xpos, ypos, innerwidth, innerheight );
+ ypos = ypos + innerheight + TOPMARGIN;
+ innerwidth = width * BUTTONWIDTH / 100;
+ xpos = ( width - innerwidth ) / 2;
+ innerheight = height * BUTTONHEIGHT / 100;
+ Activate->setGeometry ( xpos, ypos, innerwidth, innerheight );
+ resize ( width, height );
+}
+
+
+void CSquelch::setSquelchLevel ( int level )
+{
+ Squelch->setSquelchLevel ( level );
+//repaint();
+
+}
+int CSquelch::getThreshold()
+{
+ return Squelch->getThreshold();
+}
+bool CSquelch::getSquelchState()
+{
+ return Activate->isChecked();
+}
+void CSquelch::setSquelchState ( bool state )
+{
+ Activate->setChecked ( state );
+}
+void CSquelch::setThreshold ( int Threshold )
+{
+ Squelch->setValue ( Threshold );
+}
diff --git a/src/csquelch.h b/src/csquelch.h
new file mode 100644
index 0000000..5aab3aa
--- /dev/null
+++ b/src/csquelch.h
@@ -0,0 +1,77 @@
+/***************************************************************************
+ |FILENAME| - description
+ -------------------
+ begin : |DATE|
+ copyright : (C) |YEAR| by |AUTHOR|
+ email : |EMAIL|
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * The PSK part is based on WinPSK 1.0 by Moe Wheatley, AE4JY *
+ ***************************************************************************/
+
+#ifndef CSQUELCH_H
+#define CSQUELCH_H
+
+
+#include <QSlider>
+#include <QGroupBox>
+class QRadioButton;
+#include <QStyleOptionSlider>
+
+class mySlider : public QSlider {
+ Q_OBJECT
+public:
+ mySlider(QWidget *parent);
+ virtual ~mySlider();
+ void setSquelchLevel(int);
+ int getThreshold();
+private:
+
+int SquelchLevel;
+QStyleOptionSlider option;
+protected:
+/** Painter for Squelch */
+ void paintEvent(QPaintEvent *);
+
+};
+
+
+class CSquelch : public QGroupBox
+{
+ Q_OBJECT
+
+public:
+ CSquelch(const QString, QWidget* parent = 0);
+ ~CSquelch();
+ void setSquelchLevel(int);
+ int getThreshold();
+ bool getSquelchState();
+ void setSquelchState(bool);
+
+public slots:
+void setThreshold(int);
+
+protected:
+ void resizeEvent( QResizeEvent * );
+
+
+protected slots:
+ virtual void languageChange();
+
+private:
+ void calculateSizeofComponents();
+ mySlider* Squelch;
+ QRadioButton* Activate;
+
+
+
+
+};
+
+#endif // CSQUELCH_H
diff --git a/src/ctrigger.cpp b/src/ctrigger.cpp
new file mode 100644
index 0000000..b699a71
--- /dev/null
+++ b/src/ctrigger.cpp
@@ -0,0 +1,68 @@
+
+#include "ctrigger.h"
+
+#include <QLineEdit>
+#include <QRadioButton>
+
+
+
+/*
+ * Constructs a CTrigger which is a child of 'parent', with the
+ * name 'name'.'
+ */
+CTrigger::CTrigger(const QString name, QWidget* parent )
+ : QGroupBox(name, parent)
+{
+// setFrameShape( QGroupBox::WinPanel );
+// setFrameShadow( QGroupBox::Raised );
+ setAlignment( Qt::AlignHCenter );
+
+ TriggerText = new QLineEdit( this );
+// TriggerText->setMaxLength( 80 );
+
+ Activate = new QRadioButton( "Activate", this );
+ languageChange();
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+CTrigger::~CTrigger()
+{
+ // no need to delete child widgets, Qt does it all for us
+}
+
+/*
+ * Sets the strings of the subwidgets using the current
+ * language.
+ */
+void CTrigger::languageChange()
+{
+ setTitle( tr( "Trigger" ) );
+ TriggerText->setText( tr( "CQ CQ" ) );
+ Activate->setText( tr( "Activate" ) );
+}
+
+void CTrigger::resizeEvent( QResizeEvent * )
+{
+calculateSizeofComponents();
+}
+
+void CTrigger::calculateSizeofComponents()
+{
+#define LEFTANDRIGHTMARGIN 5
+#define TOP 30
+#define LABELHEIGHT 30
+int xpos,ypos,width,height,innerwidth,innerheight;
+width=this->width();
+height=this->height();
+xpos=width*LEFTANDRIGHTMARGIN/100;
+ypos=height*TOP/100;
+innerwidth=width-2*xpos;
+innerheight=height*LABELHEIGHT/100;
+TriggerText->setGeometry(xpos,ypos,innerwidth,innerheight);
+ypos=ypos+innerheight;
+Activate->setGeometry(xpos+1,ypos,innerwidth-2,innerheight);
+//this->setFrameRect(QRect(0,0,width,height));
+resize(width,height);
+}
diff --git a/src/ctrigger.h b/src/ctrigger.h
new file mode 100644
index 0000000..146ad54
--- /dev/null
+++ b/src/ctrigger.h
@@ -0,0 +1,54 @@
+/***************************************************************************
+ |FILENAME| - description
+ -------------------
+ begin : |DATE|
+ copyright : (C) |YEAR| by |AUTHOR|
+ email : |EMAIL|
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * The PSK part is based on WinPSK 1.0 by Moe Wheatley, AE4JY *
+ ***************************************************************************/
+
+#ifndef CTRIGGER_H
+#define CTRIGGER_H
+
+
+#include <QGroupBox>
+class QVBoxLayout;
+class QHBoxLayout;
+class QGridLayout;
+class QLineEdit;
+class QRadioButton;
+
+class CTrigger : public QGroupBox
+{
+ Q_OBJECT
+
+public:
+ CTrigger(const QString, QWidget* parent = 0 );
+ ~CTrigger();
+
+ QLineEdit* TriggerText;
+ QRadioButton* Activate;
+
+public slots:
+
+
+protected:
+ void resizeEvent( QResizeEvent * );
+
+
+protected slots:
+ virtual void languageChange();
+private:
+ void calculateSizeofComponents();
+
+};
+
+#endif // CTRIGGER_H
diff --git a/src/ctxbuffer.cpp b/src/ctxbuffer.cpp
new file mode 100644
index 0000000..e146af0
--- /dev/null
+++ b/src/ctxbuffer.cpp
@@ -0,0 +1,111 @@
+/***************************************************************************
+ ctxbuffer.cpp - description
+ -------------------
+ begin : Sam Feb 22 2003
+ copyright : (C) 2003 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#include "ctxbuffer.h"
+#include <QString>
+#include <QApplication>
+
+CTxBuffer::CTxBuffer()
+{
+filled=0;
+inpos=0;
+outpos=0;
+}
+CTxBuffer::~CTxBuffer()
+{
+}
+bool CTxBuffer::Filled()
+{
+if ( filled < TXBUFFER_LENGTH )
+ return false;
+else
+ return true;
+}
+int CTxBuffer::getTxChar()
+{
+int ch;
+if (filled > 0)
+ {
+ ch=txbuffer[outpos++];
+ filled--;
+ if (filled == 0)
+ {
+ inpos=0;
+ outpos=0;
+ }
+ else
+ outpos=outpos % TXBUFFER_LENGTH;
+ return ch;
+ }
+else
+ return TXTOG_CODE;
+
+}
+void CTxBuffer::insert(int c)
+{
+if ( c != '\b' )
+{
+ if (filled < TXBUFFER_LENGTH)
+ {
+ filled++;
+ txbuffer[inpos++]=c;
+ inpos = inpos % TXBUFFER_LENGTH;
+ }
+}
+else
+{
+ filled--;
+ if ( filled <= 0)
+ {
+ inpos=0;
+ outpos=0;
+ filled=0;
+ }
+ else
+ {
+ inpos--;
+ if (inpos < 0)
+ inpos +=TXBUFFER_LENGTH;
+ }
+}
+}
+void CTxBuffer::clear()
+{
+filled=0;
+inpos=0;
+outpos=0;
+}
+void CTxBuffer::insert(QString Text,int length)
+{
+for (int i=0;i <length; i++)
+ {
+ if ( filled < TXBUFFER_LENGTH )
+ {
+ filled++;
+ txbuffer[inpos++]=Text.at(i).toAscii();
+ inpos = inpos % TXBUFFER_LENGTH;
+ }
+ else
+ {
+ while(this->Filled()) // Wait until Buffer is not filled
+ qApp->processEvents(QEventLoop::AllEvents,100);
+ filled++;
+ txbuffer[inpos++]=Text.at(i).toAscii();
+ inpos = inpos % TXBUFFER_LENGTH;
+
+ }
+ }
+}
diff --git a/src/ctxbuffer.h b/src/ctxbuffer.h
new file mode 100644
index 0000000..df9a4e1
--- /dev/null
+++ b/src/ctxbuffer.h
@@ -0,0 +1,44 @@
+/***************************************************************************
+ ctxbuffer.h - description
+ -------------------
+ begin : Sam Feb 22 2003
+ copyright : (C) 2003 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * The PSK part is based on WinPSK 1.0 by Moe Wheatley, AE4JY *
+ ***************************************************************************/
+
+#ifndef CTXBUFFER_H
+#define CTXBUFFER_H
+
+#include "constants.h"
+
+/**Stores Characters that should be transmitted
+ *@author Volker Schroer
+ */
+class QString;
+class CTxBuffer {
+public:
+ CTxBuffer();
+ ~CTxBuffer();
+ bool Filled();
+int getTxChar();
+void insert(int);
+void insert(QString,int);
+void clear();
+
+private:
+int txbuffer[TXBUFFER_LENGTH];
+int filled;
+int inpos;
+int outpos;
+};
+
+#endif
diff --git a/src/ctxdisplay.cpp b/src/ctxdisplay.cpp
new file mode 100644
index 0000000..1c6c195
--- /dev/null
+++ b/src/ctxdisplay.cpp
@@ -0,0 +1,120 @@
+/***************************************************************************
+ |FILENAME| - description
+ -------------------
+ begin : |DATE|
+ copyright : (C) |YEAR| by |AUTHOR|
+ email : |EMAIL|
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#include "ctxdisplay.h"
+
+
+#include "cledbutton.h"
+#include "ctxwindow.h"
+#include "frequencyselect.h"
+/*
+ * Constructs a CTxDisplay which is a child of 'parent', with the
+ * name 'name'.'
+ */
+CTxDisplay::CTxDisplay( QWidget* parent )
+ : QFrame( parent)
+{
+ setMinimumSize( QSize( 540, 96 ) );
+ setBaseSize( QSize( 540, 96 ) );
+ setFrameShape( QFrame::Panel );
+ setFrameShadow( QFrame::Sunken );
+
+ TxWindow = new CTxWindow( this );
+
+ TxFreq = new FrequencySelect( this );
+ TxFreq->setFunctionText("Net");
+ TxFreq->setTitle("Tx Freq");
+ TxFreq->setAfcDisplayMode(Narrow);
+ TxFreq->setAfcMode(Narrow);
+// TxFunctions = new CTxFunctions( "Rx / Tx", this );
+ TxFunctions =new CLedButton(this);
+ connect(TxFunctions,SIGNAL(startRx()),this,SIGNAL(startRx()));
+ connect(TxFunctions,SIGNAL(startTx()),this,SIGNAL(startTx()));
+
+ TxFunctions->setGeometry( QRect( 100, 20, 51, 71 ) );
+ languageChange();
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+CTxDisplay::~CTxDisplay()
+{
+ // no need to delete child widgets, Qt does it all for us
+}
+
+/*
+ * Sets the strings of the subwidgets using the current
+ * language.
+ */
+void CTxDisplay::languageChange()
+{
+}
+
+void CTxDisplay::calculateSizeofComponents()
+{
+/** in percent of whole widget **/
+/** TX Function part **/
+#define TXFUNCTIONWIDTH 10
+/** TxFrequency (Width) **/
+#define TXFREQWIDTH 18
+#define TXFREQHEIGHT 70
+/** Left and Right Margin **/
+#define LEFTANDRIGHTMARGIN 1
+/** Top and Bottom Margin **/
+#define TOPANDBOTTOMMARGIN 2
+/** Inner distance **/
+#define distance 1
+
+int xpos,ypos,width,height,innerheight,innerwidth;
+width=this->width();
+height=this->height();
+xpos=width*LEFTANDRIGHTMARGIN/100;
+
+/** Frequency select Box **/
+
+innerheight=height*TXFREQHEIGHT/100;
+ypos=(height-innerheight)/2;
+innerwidth=width*TXFREQWIDTH/100;
+
+TxFreq->setGeometry(xpos,ypos,innerwidth,innerheight);
+
+/** TX- Functions **/
+
+
+//ypos=height*TOPANDBOTTOMMARGIN/100;
+//innerheight=height-2*ypos;
+innerheight=height*TXFREQHEIGHT/100;
+xpos=xpos+innerwidth+width*distance/100;
+innerwidth=width*TXFUNCTIONWIDTH/100;
+
+TxFunctions->setGeometry(xpos,ypos,innerwidth,innerheight);
+/** TX- Window **/
+xpos=xpos+innerwidth+width*distance/100;
+innerwidth=width-xpos-width*LEFTANDRIGHTMARGIN/100;
+TxWindow->setGeometry(xpos,ypos,innerwidth,innerheight);
+
+}
+
+void CTxDisplay::resizeEvent( QResizeEvent * )
+{
+calculateSizeofComponents();
+
+}
+void CTxDisplay::abbruch()
+{
+TxFunctions->setStatus(UNDEF);
+}
diff --git a/src/ctxdisplay.h b/src/ctxdisplay.h
new file mode 100644
index 0000000..af7f698
--- /dev/null
+++ b/src/ctxdisplay.h
@@ -0,0 +1,60 @@
+/***************************************************************************
+ |FILENAME| - description
+ -------------------
+ begin : |DATE|
+ copyright : (C) |YEAR| by |AUTHOR|
+ email : |EMAIL|
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * The PSK part is based on WinPSK 1.0 by Moe Wheatley, AE4JY *
+ ***************************************************************************/
+
+#ifndef CTXDISPLAY_H
+#define CTXDISPLAY_H
+
+
+#include <QFrame>
+//class QVBoxLayout;
+//class QHBoxLayout;
+//class QGridLayout;
+//class CTxFunctions;
+class CLedButton;
+class CTxWindow;
+class FrequencySelect;
+
+class CTxDisplay : public QFrame
+{
+ Q_OBJECT
+
+public:
+ CTxDisplay( QWidget* parent = 0);
+ ~CTxDisplay();
+
+ CTxWindow* TxWindow;
+ FrequencySelect* TxFreq;
+ // CTxFunctions* TxFunctions;
+CLedButton *TxFunctions;
+
+public slots:
+void abbruch();
+protected:
+ void resizeEvent( QResizeEvent * );
+
+
+protected slots:
+ virtual void languageChange();
+private:
+ void calculateSizeofComponents();
+signals:
+void startRx();
+void startTx();
+
+};
+
+#endif // CTXDISPLAY_H
diff --git a/src/ctxwindow.cpp b/src/ctxwindow.cpp
new file mode 100644
index 0000000..05d5aa9
--- /dev/null
+++ b/src/ctxwindow.cpp
@@ -0,0 +1,292 @@
+/***************************************************************************
+ |FILENAME| - description
+ -------------------
+ begin : |DATE|
+ copyright : (C) |YEAR| by |AUTHOR|
+ email : |EMAIL|
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * The PSK part is based on WinPSK 1.0 by Moe Wheatly, AE4JY *
+ ***************************************************************************/
+
+
+
+#include "ctxbuffer.h"
+#include "ctxwindow.h"
+
+#include <QPushButton>
+#include <QLineEdit>
+#include <QApplication>
+#include <QKeyEvent>
+#include "parameter.h"
+
+extern Parameter settings;
+/*
+ * Constructs a CTxWindow which is a child of 'parent', with the
+ * name 'name'.'
+ */
+
+
+CTxWindow::CTxWindow ( QWidget* parent )
+ : QFrame ( parent )
+{
+ setFrameShape ( QFrame::Panel );
+ setFrameShadow ( QFrame::Sunken );
+// setLineWidth( 2 );
+// setMargin( 2 );
+// setMidLineWidth( 1 );
+
+ Clear = new QPushButton ( "TXClear", this );
+
+
+ Zeile1 = new QLineEdit ( this );
+ Zeile1->setFrame ( false );
+
+ Zeile2 = new QLineEdit ( this );
+ Zeile2->setFrame ( false );
+// Zeile2->setFrameShadow( QLineEdit::Plain );
+// Zeile2->setLineWidth( 0 );
+
+
+ Zeile3 = new QLineEdit ( this );
+ Zeile3->setFrame ( false );
+ languageChange();
+ Zeile = 0;
+ Spalte = 0;
+ Zeile1->setFocusProxy ( this );
+ Zeile2->setFocusProxy ( this );
+ Zeile3->setFocusProxy ( this );
+ setFocusPolicy(Qt::ClickFocus);
+
+ // signals and slots connections
+ connect ( Clear , SIGNAL ( clicked() ), this, SLOT ( clear() ) );
+ connect ( Zeile1, SIGNAL ( returnPressed() ), this, SLOT ( gotoNextLine() ) );
+ connect ( Zeile2, SIGNAL ( returnPressed() ), this, SLOT ( gotoNextLine() ) );
+ connect ( Zeile3, SIGNAL ( returnPressed() ), this, SLOT ( gotoNextLine() ) );
+ /**
+ connect( Zeile1, SIGNAL( textChanged(const QString &)) , this, SLOT(transmitText(const QString &)));
+ connect( Zeile2, SIGNAL( textChanged(const QString &)) , this, SLOT(transmitText(const QString &)));
+ connect( Zeile3, SIGNAL( textChanged(const QString &)) , this, SLOT(transmitText(const QString &)));
+ **/
+ setEnabled ( true );
+}
+
+void CTxWindow::clear()
+{
+ Zeile1->clear();
+ Zeile2->clear();
+ Zeile3->clear();
+ Zeile = 0;
+ Spalte = 0;
+ Zeile1->setCursorPosition ( Spalte );
+ Buffer->clear();
+}
+
+
+void CTxWindow::resizeEvent ( QResizeEvent * )
+{
+ calculateSizeofComponents();
+}
+
+void CTxWindow::gotoNextLine()
+{
+ if ( Zeile == 2 ) // Reached last Line
+ {
+ Zeile1->setText ( Zeile2->text() );
+ Zeile2->setText ( Zeile3->text() );
+ Zeile3->clear();
+ Spalte = 0;
+ Zeile3->setCursorPosition ( Spalte );
+ }
+ else
+ {
+ Zeile++;
+ Spalte = 0;
+ if ( Zeile == 1 )
+ Zeile2->setCursorPosition ( Spalte );
+ else
+ Zeile3->setCursorPosition ( Spalte );
+ }
+}
+
+void CTxWindow::calculateSizeofComponents()
+{
+#define MARGINS 3
+#define DISTANCE 2
+#define BUTTOMWIDTH 20
+ int xpos, ypos, width, height, innerheight, innerwidth;
+ width = this->width();
+ height = this->height();
+ xpos = DISTANCE;
+ ypos = height * MARGINS / 100;
+ innerheight = ( height - 2 * ypos - height * DISTANCE / 100 ) / 4;
+ Zeile1->setGeometry ( xpos, ypos, width - 2*xpos, innerheight );
+ ypos = ypos + innerheight - 2;
+ Zeile2->setGeometry ( xpos, ypos, width - 2*xpos, innerheight );
+ ypos = ypos + innerheight - 2;
+ Zeile3->setGeometry ( xpos, ypos, width - 2*xpos, innerheight );
+ ypos = ypos + innerheight + height * DISTANCE / 100;
+ innerwidth = 100;
+ xpos = width - innerwidth - 2 * xpos;
+ Clear->setGeometry ( xpos, ypos, innerwidth, innerheight );
+}
+
+void CTxWindow::mousePressEvent ( QMouseEvent * )
+{
+ if ( Zeile == 0 ) Zeile1->setCursorPosition ( Spalte );
+ if ( Zeile == 1 ) Zeile2->setCursorPosition ( Spalte );
+ if ( Zeile == 2 ) Zeile3->setCursorPosition ( Spalte );
+}
+
+
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+CTxWindow::~CTxWindow()
+{
+ // no need to delete child widgets, Qt does it all for us
+}
+
+/*
+ * Sets the strings of the subwidgets using the current
+ * language.
+ */
+void CTxWindow::languageChange()
+{
+ Clear->setText ( tr ( "Clear" ) );
+}
+
+
+void CTxWindow::keyPressEvent ( QKeyEvent *e ) // Bearbeiten der Eingaben im
+// TX Window
+{
+ unsigned char c;
+ static bool CapsLock = false;
+ if ( Buffer->Filled() )
+ {
+ QApplication::beep();
+ e->ignore();
+ return;
+ }
+ /**
+ if ( e->state() & ControlButton )
+ {
+ if ( e->key() == Key_V )
+ pasteText( QApplication::clipboard()->text( QClipboard::Clipboard ) );
+ }
+ else
+ **/
+ switch ( e->key() )
+ {
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ gotoNextLine();
+ if(settings.autoCrLf)
+ Buffer->insert('\r');
+ Buffer->insert ( '\n' );
+ e->accept();
+ break;
+ case Qt::Key_Home:
+ Buffer->insert('\r');
+ e->accept();
+ break;
+ case Qt::Key_CapsLock:
+ CapsLock = !CapsLock;
+ e->accept();
+ break;
+
+ case Qt::Key_Backspace:
+ c = '\b';
+ backspace();
+ e->accept();
+ Buffer->insert ( c );
+ break;
+
+ default:
+// ButtonState cc=e->state();
+// if ( (cc == ShiftButton) )
+ if ( ( e->modifiers() == Qt::ShiftModifier ) || CapsLock )
+ {
+ if ( !e->text().isEmpty() )
+ c = e->text().toUpper().at ( 0 ).toAscii();
+ else
+ c = 0;
+ }
+ else
+ {
+ if ( !e->text().isEmpty() )
+ c = e->text().toLower().at ( 0 ).toAscii();
+ else
+ c = 0;
+ }
+ if ( c != 0 )
+ {
+ Spalte++;
+ if ( Spalte > 80 )
+ {
+ Buffer->insert ( '\n' ); //This newline Char will be Transmitted
+ gotoNextLine();
+ }
+ Buffer->insert ( c );
+ insert ( c );
+ e->accept();
+ }
+ } // End Case
+
+} // keyPressEvent
+
+
+void CTxWindow::backspace()
+{
+
+ QLineEdit * line;
+ if ( Zeile == 0 )
+ line = Zeile1;
+ if ( Zeile == 1 )
+ line = Zeile2;
+ if ( Zeile == 2 )
+ line = Zeile3;
+ line->backspace();
+
+}
+void CTxWindow::insert ( unsigned char c )
+{
+ QLineEdit *line;
+ if ( Zeile == 0 )
+ line = Zeile1;
+ if ( Zeile == 1 )
+ line = Zeile2;
+ if ( Zeile == 2 )
+ line = Zeile3;
+ QString s = line->text() + QString ( QChar ( c ) );
+ line->setText ( s );
+}
+void CTxWindow::setTxBuffer ( CTxBuffer *p )
+{
+ Buffer = p;
+}
+
+void CTxWindow::pasteText ( const QString &Text )
+{
+ int length;
+ length = Text.length();
+ for ( int i = 0; i < length; i++ )
+ {
+ Spalte++;
+ if ( Spalte > 80 )
+ {
+ Buffer->insert ( '\n' ); //This newline Char will be Transmitted
+ gotoNextLine();
+ }
+ char c = Text.at ( i ).toAscii();
+ Buffer->insert ( c );
+ insert ( c );
+ }
+}
diff --git a/src/ctxwindow.h b/src/ctxwindow.h
new file mode 100644
index 0000000..69f8039
--- /dev/null
+++ b/src/ctxwindow.h
@@ -0,0 +1,71 @@
+/***************************************************************************
+ |FILENAME| - description
+ -------------------
+ begin : |DATE|
+ copyright : (C) |YEAR| by |AUTHOR|
+ email : |EMAIL|
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * The PSK part is based on WinPSK 1.0 by Moe Wheatley, AE4JY *
+ ***************************************************************************/
+
+#ifndef CTXWINDOW_H
+#define CTXWINDOW_H
+
+#include <QFrame>
+class QLineEdit;
+class QPushButton;
+class CTxBuffer;
+class QString;
+
+class CTxWindow : public QFrame
+{
+ Q_OBJECT
+
+public:
+ CTxWindow( QWidget* parent = 0);
+ ~CTxWindow();
+
+ QPushButton* Clear;
+ void setTxBuffer(CTxBuffer *);
+
+public slots:
+
+signals:
+
+
+protected:
+ virtual void resizeEvent( QResizeEvent * e );
+ virtual void mousePressEvent( QMouseEvent * );
+
+
+
+protected slots:
+ virtual void languageChange();
+ void pasteText(const QString &);
+private:
+ unsigned int Zeile;
+ unsigned int Spalte;
+ QLineEdit* Zeile2;
+ QLineEdit* Zeile1;
+ QLineEdit* Zeile3;
+
+ void calculateSizeofComponents();
+ void keyPressEvent(QKeyEvent *);
+ CTxBuffer * Buffer;
+ void backspace();
+ void insert(unsigned char);
+
+private slots:
+ virtual void clear();
+ void gotoNextLine();
+
+};
+
+#endif // CTXWINDOW_H
diff --git a/src/deinterleaver.cpp b/src/deinterleaver.cpp
new file mode 100644
index 0000000..e145ca4
--- /dev/null
+++ b/src/deinterleaver.cpp
@@ -0,0 +1,57 @@
+/***************************************************************************
+ deinterleaver.cpp - description
+ -------------------
+ begin : Sam Feb 1 2003
+ copyright : (C) 2003 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ ***************************************************************************/
+/***************************************************************************
+ * *
+ * The deinterleaver follows a proposal of Chen, W7AY *
+ * Instead of deinterleaving in multiple steps the deinterleaving is done *
+ * in one single step *
+ * Many thanks to Chen, for the allowance to use his idea *
+ ***************************************************************************/
+
+
+#include "deinterleaver.h"
+
+Deinterleaver::Deinterleaver ( int grade )
+{
+ interleaverGrade=grade*16;
+ delayLine= new double[interleaverGrade];
+
+ for ( int i=0; i <interleaverGrade ; i++ )
+ delayLine[i]=0;
+ index=0;
+}
+Deinterleaver::~Deinterleaver()
+{
+ if ( delayLine !=0 )
+ {
+ delete delayLine;
+// delayLine=0;
+ }
+}
+void Deinterleaver::deinterleave ( double *p )
+{
+ double result[4];
+ int offset,i;
+ offset=interleaverGrade/4+1;
+ for ( i=0;i < 4; i++ )
+ result[i]=delayLine[ ( index+i*offset ) % interleaverGrade];
+ for ( i=0;i < 4; i++ )
+ {
+ delayLine[index+i]=p[i];
+ p[i]=result[i];
+ }
+ index = ( index+4 ) % interleaverGrade;
+}
diff --git a/src/deinterleaver.h b/src/deinterleaver.h
new file mode 100644
index 0000000..8e3e5dc
--- /dev/null
+++ b/src/deinterleaver.h
@@ -0,0 +1,37 @@
+/***************************************************************************
+ deinterleaver.h - description
+ -------------------
+ begin : Sam Feb 1 2003
+ copyright : (C) 2003 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * The PSK part is based on WinPSK 1.0 by Moe Wheatley, AE4JY *
+ ***************************************************************************/
+
+#ifndef DEINTERLEAVER_H
+#define DEINTERLEAVER_H
+
+
+/**Diagonal Deinterleaver
+ *@author Volker Schroer
+ */
+
+class Deinterleaver {
+public:
+ Deinterleaver(int);
+ ~Deinterleaver();
+void deinterleave(double *);
+private:
+double *delayLine;
+int index;
+int interleaverGrade;
+};
+
+#endif
diff --git a/src/feccoder.cpp b/src/feccoder.cpp
new file mode 100644
index 0000000..5be794d
--- /dev/null
+++ b/src/feccoder.cpp
@@ -0,0 +1,56 @@
+/***************************************************************************
+ feccoder.cpp - description
+ -------------------
+ begin : Sam M�r 1 2003
+ copyright : (C) 2003 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#include "feccoder.h"
+/* The two generator polynomials for the NASA Standard K=7 rate 1/2 code. */
+#define POLYA 0x6d
+#define POLYB 0x4f
+/*
+ * 8-bit parity lookup table, generated
+ */
+const unsigned char FECCoder::Partab[256] = {
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+};
+
+FECCoder::FECCoder()
+{
+
+}
+FECCoder::~FECCoder()
+{
+}
+void FECCoder::FECEncode(int data, unsigned char *bits)
+{
+ coded = (coded << 1) | !!data;
+ // return (Partab[coded & POLYA] << 1) | Partab[coded & POLYB];
+ bits[0]=Partab[coded & POLYA]; // High
+ bits[1]=Partab[coded & POLYB]; // Low
+}
diff --git a/src/feccoder.h b/src/feccoder.h
new file mode 100644
index 0000000..7a0d923
--- /dev/null
+++ b/src/feccoder.h
@@ -0,0 +1,36 @@
+/***************************************************************************
+ feccoder.h - description
+ -------------------
+ begin : Sam M�r 1 2003
+ copyright : (C) 2003 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * The PSK part is based on WinPSK 1.0 by Moe Wheatley, AE4JY *
+ ***************************************************************************/
+
+#ifndef FECCODER_H
+#define FECCODER_H
+
+
+/**
+ *@author Volker Schroer
+ */
+
+class FECCoder {
+public:
+ FECCoder();
+ ~FECCoder();
+void FECEncode(int,unsigned char *);
+private:
+static const unsigned char Partab[256];
+unsigned int coded;
+};
+
+#endif
diff --git a/src/fircoeffs.h b/src/fircoeffs.h
new file mode 100644
index 0000000..8a773e9
--- /dev/null
+++ b/src/fircoeffs.h
@@ -0,0 +1,485 @@
+//////////////////////////////////////////////////////////////////////
+// Copyright 1999. Moe Wheatley AE4JY <ae4jy at mindspring.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 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.
+//
+//////////////////////////////////////////////////////////////////////
+//
+
+#define DEC2_LPFIR_LENGTH 45
+
+// Design method: Parks-McClellan method
+// Number of taps = 45
+
+
+// Number of bands = 2
+// Band Lower Upper Value Weight
+// edge edge
+// 1 0.0 .018 1.0 1
+// 2 .25 .5 .00007 100
+/**
+const double Dec2LPCoef[DEC2_LPFIR_LENGTH ] = {
+ 0.00041063658,
+ 0.00040020444,
+ -0.0014690721,
+ -0.0046244896,
+ -0.0048873265,
+ 0.00057075169,
+ 0.0064849067,
+ 0.0034999371,
+ -0.0072838126,
+ -0.010484073,
+ 0.0032609865,
+ 0.017545124,
+ 0.0073308048,
+ -0.02042501,
+ -0.024496589,
+ 0.013398095,
+ 0.045762697,
+ 0.010940839,
+ -0.066633815,
+ -0.069373038,
+ 0.081944411,
+ 0.30510648,
+ 0.41246774,
+ 0.30510648,
+ 0.081944411,
+ -0.069373038,
+ -0.066633815,
+ 0.010940839,
+ 0.045762697,
+ 0.013398095,
+ -0.024496589,
+ -0.02042501,
+ 0.0073308048,
+ 0.017545124,
+ 0.0032609865,
+ -0.010484073,
+ -0.0072838126,
+ 0.0034999371,
+ 0.0064849067,
+ 0.00057075169,
+ -0.0048873265,
+ -0.0046244896,
+ -0.0014690721,
+ 0.00040020444,
+ 0.00041063658
+};
+**/
+const double Dec2LPCoef[DEC2_LPFIR_LENGTH ] = {
+ 0.0041063658,
+ 0.0040020444,
+ -0.014690721,
+ -0.046244896,
+ -0.048873265,
+ 0.0057075169,
+ 0.064849067,
+ 0.034999371,
+ -0.072838126,
+ -0.10484073,
+ 0.032609865,
+ 0.17545124,
+ 0.073308048,
+ -0.2042501,
+ -0.24496589,
+ 0.13398095,
+ 0.45762697,
+ 0.10940839,
+ -0.66633815,
+ -0.69373038,
+ 0.81944411,
+ 3.0510648,
+ 4.1246774,
+ 3.0510648,
+ 0.81944411,
+ -0.69373038,
+ -0.66633815,
+ 0.10940839,
+ 0.45762697,
+ 0.13398095,
+ -0.24496589,
+ -0.2042501,
+ 0.073308048,
+ 0.17545124,
+ 0.032609865,
+ -0.10484073,
+ -0.072838126,
+ 0.034999371,
+ 0.064849067,
+ 0.0057075169,
+ -0.048873265,
+ -0.046244896,
+ -0.014690721,
+ 0.0040020444,
+ 0.0041063658
+};
+
+#define DEC3_LPFIR_LENGTH 27
+// Design method: Parks-McClellan method
+// Number of taps = 27
+// Number of bands = 2
+// Band Lower Upper Value Weight
+// edge edge
+// 1 0.0 .017 1.0 1
+// 2 .166666 .5 .00002 10
+
+const double Dec3LPCoef[DEC3_LPFIR_LENGTH ] = {
+ /**
+ -0.00028892587,
+ -0.0012431135,
+ -0.0033184787,
+ -0.0065777314,
+ -0.010172455,
+ -0.011982908,
+ -0.0087991708,
+ 0.0027573615,
+ 0.024743232,
+ 0.05640933,
+ 0.09349033,
+ 0.12882953,
+ 0.15434156,
+ 0.16367159,
+ 0.15434156,
+ 0.12882953,
+ 0.09349033,
+ 0.05640933,
+ 0.024743232,
+ 0.0027573615,
+ -0.0087991708,
+ -0.011982908,
+ -0.010172455,
+ -0.0065777314,
+ -0.0033184787,
+ -0.0012431135,
+ -0.00028892587
+ **/
+ -0.0028892587,
+ -0.012431135,
+ -0.033184787,
+ -0.065777314,
+ -0.10172455,
+ -0.11982908,
+ -0.087991708,
+ 0.027573615,
+ 0.24743232,
+ 0.5640933,
+ 0.9349033,
+ 1.2882953,
+ 1.5434156,
+ 1.6367159,
+ 1.5434156,
+ 1.2882953,
+ 0.9349033,
+ 0.5640933,
+ 0.24743232,
+ 0.027573615,
+ -0.087991708,
+ -0.11982908,
+ -0.10172455,
+ -0.065777314,
+ -0.033184787,
+ -0.012431135,
+ -0.0028892587
+};
+
+
+#if 1
+#define BITFIR_LENGTH 79
+const double BitFirCoef[BITFIR_LENGTH] = { // 16 Hz bw LP filter for data recovery
+ 3.8780526e-005,
+ -0.00043373927,
+ -0.00057165992,
+ -0.00090520784,
+ -0.00135488,
+ -0.0019236412,
+ -0.0026169379,
+ -0.0034345504,
+ -0.0043691791,
+ -0.0054046365,
+ -0.0065156454,
+ -0.0076664838,
+ -0.0088120663,
+ -0.0098975766,
+ -0.010860162,
+ -0.011630504,
+ -0.012135381,
+ -0.012299909,
+ -0.012051495,
+ -0.011323131,
+ -0.010057012,
+ -0.0082078785,
+ -0.0057472009,
+ -0.0026644814,
+ 0.0010286189,
+ 0.0052985616,
+ 0.010087661,
+ 0.015316424,
+ 0.020883009,
+ 0.026668057,
+ 0.032536465,
+ 0.038341551,
+ 0.043932665,
+ 0.049156847,
+ 0.053867496,
+ 0.057929091,
+ 0.061222375,
+ 0.063648481,
+ 0.065134147,
+ 0.065654404,
+ 0.065134147,
+ 0.063648481,
+ 0.061222375,
+ 0.057929091,
+ 0.053867496,
+ 0.049156847,
+ 0.043932665,
+ 0.038341551,
+ 0.032536465,
+ 0.026668057,
+ 0.020883009,
+ 0.015316424,
+ 0.010087661,
+ 0.0052985616,
+ 0.0010286189,
+ -0.0026644814,
+ -0.0057472009,
+ -0.0082078785,
+ -0.010057012,
+ -0.011323131,
+ -0.012051495,
+ -0.012299909,
+ -0.012135381,
+ -0.011630504,
+ -0.010860162,
+ -0.0098975766,
+ -0.0088120663,
+ -0.0076664838,
+ -0.0065156454,
+ -0.0054046365,
+ -0.0043691791,
+ -0.0034345504,
+ -0.0026169379,
+ -0.0019236412,
+ -0.00135488,
+ -0.00090520784,
+ -0.00057165992,
+ -0.00043373927,
+ 3.8780526e-005
+
+};
+#else
+#define BITFIR_LENGTH 79
+const double BitFirCoef[BITFIR_LENGTH] = { // 16 Hz bw Martinez LP filter for data recovery
+ -3.567202e-004,
+ -4.542733e-004,
+ -6.506069e-004,
+ -9.477393e-004,
+ -1.347645e-003,
+ -1.851098e-003,
+ -2.456292e-003,
+ -3.157368e-003,
+ -3.942984e-003,
+ -4.795060e-003,
+ -5.687838e-003,
+ -6.587355e-003,
+ -7.451419e-003,
+ -8.230144e-003,
+ -8.867057e-003,
+ -9.300761e-003,
+ -9.467104e-003,
+ -9.301771e-003,
+ -8.743191e-003,
+ -7.735620e-003,
+ -6.232267e-003,
+ -4.198302e-003,
+ -1.613592e-003,
+ 1.524992e-003,
+ 5.201817e-003,
+ 9.381422e-003,
+ 1.400822e-002,
+ 1.900705e-002,
+ 2.428456e-002,
+ 2.973155e-002,
+ 3.522593e-002,
+ 4.063663e-002,
+ 4.582786e-002,
+ 5.066388e-002,
+ 5.501399e-002,
+ 5.875741e-002,
+ 6.178797e-002,
+ 6.401828e-002,
+ 6.538327e-002,
+ 6.584278e-002,
+ 6.538327e-002,
+ 6.401828e-002,
+ 6.178797e-002,
+ 5.875741e-002,
+ 5.501399e-002,
+ 5.066388e-002,
+ 4.582786e-002,
+ 4.063663e-002,
+ 3.522593e-002,
+ 2.973155e-002,
+ 2.428456e-002,
+ 1.900705e-002,
+ 1.400822e-002,
+ 9.381422e-003,
+ 5.201817e-003,
+ 1.524992e-003,
+ -1.613592e-003,
+ -4.198302e-003,
+ -6.232267e-003,
+ -7.735620e-003,
+ -8.743191e-003,
+ -9.301771e-003,
+ -9.467104e-003,
+ -9.300761e-003,
+ -8.867057e-003,
+ -8.230144e-003,
+ -7.451419e-003,
+ -6.587355e-003,
+ -5.687838e-003,
+ -4.795060e-003,
+ -3.942984e-003,
+ -3.157368e-003,
+ -2.456292e-003,
+ -1.851098e-003,
+ -1.347645e-003,
+ -9.477393e-004,
+ -6.506069e-004,
+ -4.542733e-004,
+ -3.567202e-004
+};
+#endif
+
+
+// Filter type: Multiband filter
+// Design method: Parks-McClellan method
+// Number of taps = 79
+// Number of bands = 2
+// Band Lower Upper Value Weight
+// edge edge
+//
+// 1 0.0 .04 1. 1.
+// 2 .07 .5 .00001 30.
+const double FreqFirCoef[BITFIR_LENGTH] = { // 31.25 Hz bw LP filter for frequency error
+ -0.00088970285,
+ -0.00095069429,
+ -0.001333873,
+ -0.0016964002,
+ -0.0019708148,
+ -0.0020817198,
+ -0.0019538899,
+ -0.0015246954,
+ -0.00075521572,
+ 0.00035617931,
+ 0.0017654549,
+ 0.0033764437,
+ 0.005044567,
+ 0.006582916,
+ 0.0077790286,
+ 0.008414395,
+ 0.0082949352,
+ 0.007277045,
+ 0.0052959804,
+ 0.0023882104,
+ -0.0012898644,
+ -0.0054642152,
+ -0.0097488405,
+ -0.013668084,
+ -0.01669712,
+ -0.018301826,
+ -0.017996533,
+ -0.015393401,
+ -0.010253263,
+ -0.0025234426,
+ 0.0076375654,
+ 0.019855931,
+ 0.033557222,
+ 0.048001634,
+ 0.062336497,
+ 0.075662948,
+ 0.087109104,
+ 0.095901874,
+ 0.10143605,
+ 0.10333491,
+ 0.10143605,
+ 0.095901874,
+ 0.087109104,
+ 0.075662948,
+ 0.062336497,
+ 0.048001634,
+ 0.033557222,
+ 0.019855931,
+ 0.0076375654,
+ -0.0025234426,
+ -0.010253263,
+ -0.015393401,
+ -0.017996533,
+ -0.018301826,
+ -0.01669712,
+ -0.013668084,
+ -0.0097488405,
+ -0.0054642152,
+ -0.0012898644,
+ 0.0023882104,
+ 0.0052959804,
+ 0.007277045,
+ 0.0082949352,
+ 0.008414395,
+ 0.0077790286,
+ 0.006582916,
+ 0.005044567,
+ 0.0033764437,
+ 0.0017654549,
+ 0.00035617931,
+ -0.00075521572,
+ -0.0015246954,
+ -0.0019538899,
+ -0.0020817198,
+ -0.0019708148,
+ -0.0016964002,
+ -0.001333873,
+ -0.00095069429,
+ -0.00088970285
+};
+
+// bit sync half distance table
+// index any position 0 to 19 and it returns a position halfway from the index
+const int HALF_TBL[20] = {
+ 9, // 0
+ 10, // 1
+ 11, // 2
+ 12, // 3
+ 13, // 4
+ 14, // 5
+ 15, // 6
+ 16, // 7
+ 17, // 8
+ 18, // 9
+ 19, // 0, // 10
+ 0, //
+ 1, // 11
+
+ 2, // 12
+ 3, // 13
+ 4, // 14
+ 5, // 15
+ 6, // 16
+ 7, // 17
+ 8, // 18
+// 9, // 19
+};
+
diff --git a/src/firfilter.cpp b/src/firfilter.cpp
new file mode 100644
index 0000000..39b67ce
--- /dev/null
+++ b/src/firfilter.cpp
@@ -0,0 +1,114 @@
+/***************************************************************************
+ firfilter.cpp - description
+ -------------------
+ begin : Fr Nov 7 2003
+ copyright : (C) 2003 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#include "firfilter.h"
+
+FIRFilter::FIRFilter(double *Filtercoeffs,int Filterlength,FilterMode Mode)
+{
+NxCoeffs=Filterlength;
+
+h=new double[Filterlength];
+if (Mode == RealData)
+ filterbuffer=new double[Filterlength];
+else
+ cfilterbuffer=new complex<double>[Filterlength];
+
+for(int i=0;i <Filterlength;i++)
+ {
+ if(Filtercoeffs != 0)
+ h[i] = *(Filtercoeffs+i);
+ if (Mode == RealData)
+ filterbuffer[i]=0.0;
+ else
+ cfilterbuffer[i]=complex<double>(0.,0.);
+ }
+if (Mode == RealData)
+ fbBuffer=filterbuffer;
+else
+ cfbBuffer=cfilterbuffer;
+}
+
+FIRFilter::~FIRFilter()
+{
+if (h != 0)
+ delete h;
+if (filterbuffer != 0)
+ delete filterbuffer;
+if (cfilterbuffer != 0)
+ delete cfilterbuffer;
+}
+void FIRFilter::processFilter(double *input,double *output,int NxSamples)
+{
+double *oPtr,*fPtr,*fbPtr;
+double acc;
+oPtr=output;
+fbPtr=fbBuffer;
+
+for(int i=0; i <NxSamples;i++)
+ {
+ *fbPtr=input[i];
+ acc=0.0;
+ fPtr=h;
+ for(int j=0;j < NxCoeffs; j++)
+ {
+ acc +=(*fbPtr--)*(*fPtr++); // x(n-j)*h(j)
+ if (fbPtr < filterbuffer )
+ fbPtr = filterbuffer+NxCoeffs-1;
+ }
+ fbPtr++;
+ if (fbPtr >= (filterbuffer + NxCoeffs ) )
+ fbPtr=filterbuffer;
+ *oPtr++ =acc;
+ }
+
+
+fbBuffer=fbPtr;
+}
+void FIRFilter::setnewCoeffs(double *Filtercoeffs)
+{
+for(int i=0;i <NxCoeffs;i++)
+ h[i] = *(Filtercoeffs+i);
+ }
+
+void FIRFilter::processFilter(complex<double> *input,complex<double> *output,int NxSamples)
+{
+ complex<double> *oPtr,*fbPtr;
+ complex<double> acc;
+ double *fPtr;
+ oPtr=output;
+ fbPtr=cfbBuffer;
+
+ for(int i=0; i <NxSamples;i++)
+ {
+ *fbPtr=input[i];
+ acc=0.0;
+ fPtr=h;
+ for(int j=0;j < NxCoeffs; j++)
+ {
+ acc +=(*fbPtr--)*(*fPtr++); // x(n-j)*h(j)
+ if (fbPtr < cfilterbuffer )
+ fbPtr = cfilterbuffer+NxCoeffs-1;
+ }
+ fbPtr++;
+ if (fbPtr >= (cfilterbuffer + NxCoeffs ) )
+ fbPtr=cfilterbuffer;
+ *oPtr++ =acc;
+ }
+
+
+ cfbBuffer=fbPtr;
+}
diff --git a/src/firfilter.h b/src/firfilter.h
new file mode 100644
index 0000000..2b82449
--- /dev/null
+++ b/src/firfilter.h
@@ -0,0 +1,43 @@
+/***************************************************************************
+ firfilter.h - description
+ -------------------
+ begin : Fr Nov 7 2003
+ copyright : (C) 2003 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef FIRFILTER_H
+#define FIRFILTER_H
+
+#include <complex>
+using namespace std;
+/**Implements an FIR- Filter
+ *@author Volker Schroer
+ */
+enum FilterMode{RealData,ComplexData};
+class FIRFilter {
+public:
+ FIRFilter(double *Filtercoeffs,int Filterlength,FilterMode);
+ ~FIRFilter();
+ void processFilter(double *input,double *output,int NxSamples);
+ void processFilter(complex<double> *input,complex<double> *output,int NxSamples);
+ void setnewCoeffs(double *Filtercoeffs);
+private:
+int NxCoeffs;
+double *h;
+complex<double> *cfilterbuffer;
+complex<double> *cfbBuffer;
+double *filterbuffer;
+double *fbBuffer;
+};
+
+#endif
diff --git a/src/frequencyselect.cpp b/src/frequencyselect.cpp
new file mode 100644
index 0000000..09ad4f4
--- /dev/null
+++ b/src/frequencyselect.cpp
@@ -0,0 +1,204 @@
+/***************************************************************************
+ |FILENAME| - description
+ -------------------
+ begin : |DATE|
+ copyright : (C) |YEAR| by |AUTHOR|
+ email : |EMAIL|
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * The PSK part is based on WinPSK 1.0 by Moe Wheatly, AE4JY *
+ ***************************************************************************/
+#include "frequencyselect.h"
+
+#include <QRadioButton>
+#include <QSpinBox>
+
+
+/*
+ * Constructs a FrequencySelect which is a child of 'parent', with the
+ * name 'name'.'
+ */
+FrequencySelect::FrequencySelect( QWidget* parent , AfcMode WithMode)
+ : QGroupBox( parent )
+{
+ // setFrameShape( QGroupBox::WinPanel );
+ // setFrameShadow( QGroupBox::Raised );
+ setAlignment( Qt::AlignCenter );
+
+ Activate = new QRadioButton( "Activate", this );
+Activate->setAutoExclusive(false);
+ AfcWide = new QRadioButton("Wide", this);
+AfcWide->setAutoExclusive(false);
+ modus=Wide;
+ switch (WithMode)
+ {
+ case Off:
+ Activate->hide();
+ AfcWide->hide();
+ break;
+ case Narrow:
+ Activate->show();
+ AfcWide->hide();
+ break;
+ case Wide:
+ Activate->show();
+ AfcWide->show();
+ break;
+ }
+ Frequency = new QSpinBox( this );
+ Frequency->setMaximum( 2500 );
+ Frequency->setMinimum( 300 );
+ frequency = 1000;
+ Frequency->setValue( (int) frequency );
+ languageChange();
+ connect(Frequency,SIGNAL(valueChanged(int)),this,SLOT(checkFrequency(int)));
+ connect(AfcWide,SIGNAL(clicked()),this,SLOT(toggleWide()));
+ connect(Activate,SIGNAL(clicked()),this,SLOT(toggleActivate()));
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+FrequencySelect::~FrequencySelect()
+{
+ // no need to delete child widgets, Qt does it all for us
+}
+
+/*
+ * Sets the strings of the subwidgets using the current
+ * language.
+ */
+void FrequencySelect::languageChange()
+{
+ Activate->setText( tr( "Frequency" ) );
+}
+
+
+double FrequencySelect::getFrequency()
+{
+return frequency;
+}
+
+
+void FrequencySelect::setFunctionText( QString Text)
+{
+Activate->setText(Text);
+}
+
+
+
+void FrequencySelect::calculateSizeofComponents()
+{
+#define LEFTANDRIGHTMARGIN 6
+#define TOPANDBOTTOM 30
+#define LABELHEIGHT 35
+int width,height,xpos,ypos,innerwidth,innerheight;
+width=this->width();
+height=this->height();
+xpos=width*LEFTANDRIGHTMARGIN/100;
+ypos=height*TOPANDBOTTOM/100;
+innerwidth=width-2*xpos;
+innerheight=height*LABELHEIGHT/100;
+Frequency->setGeometry(xpos,ypos,innerwidth,innerheight);
+ypos=ypos+innerheight;
+innerwidth=innerwidth/2;
+xpos = xpos -2;
+Activate->setGeometry(xpos,ypos,innerwidth,innerheight);
+AfcWide->setText("Wide");
+AfcWide->setGeometry(xpos+innerwidth+1,ypos,innerwidth,innerheight);
+
+resize(width,height);
+
+}
+
+void FrequencySelect::resizeEvent( QResizeEvent * )
+{
+calculateSizeofComponents();
+}
+
+
+void FrequencySelect::setFrequency( double freq)
+{
+Frequency->setValue( (int) freq);
+frequency=freq;
+}
+
+void FrequencySelect::checkFrequency(int freq)
+{
+if ((unsigned int) freq != (unsigned int)frequency)
+ {
+ frequency= freq;
+ emit FrequencyChanged(frequency);
+ }
+}
+
+AfcMode FrequencySelect::getAfcMode()
+{
+return modus;
+}
+
+void FrequencySelect::setAfcMode(AfcMode mode)
+{
+modus=mode;
+if ( modus == Narrow )
+ {
+ Activate->setChecked(true);
+ AfcWide->setChecked(false);
+ }
+ else if ( modus == Wide )
+ {
+ Activate->setChecked(false);
+ AfcWide->setChecked(true);
+ }
+ else
+ {
+ Activate->setChecked(false);
+ AfcWide->setChecked(false);
+ }
+}
+void FrequencySelect::setAfcDisplayMode(AfcMode Mode)
+{
+ switch (Mode)
+ {
+ case Off:
+ Activate->hide();
+ AfcWide->hide();
+ break;
+ case Narrow:
+ Activate->show();
+ AfcWide->hide();
+ break;
+ case Wide:
+ Activate->show();
+ AfcWide->show();
+ break;
+ }
+}
+
+void FrequencySelect::toggleWide()
+{
+ bool OnOff=AfcWide->isChecked();
+ Activate->setChecked(false);
+ AfcWide->setChecked(OnOff);
+ if( OnOff )
+ modus=Wide;
+ else
+ modus=Off;
+}
+void FrequencySelect::toggleActivate()
+{
+ bool OnOff=Activate->isChecked();
+ AfcWide->setChecked(false);
+ Activate->setChecked(OnOff);
+ if( OnOff )
+ modus=Narrow;
+ else
+ modus=Off;
+}
+
diff --git a/src/frequencyselect.h b/src/frequencyselect.h
new file mode 100644
index 0000000..63e8fc0
--- /dev/null
+++ b/src/frequencyselect.h
@@ -0,0 +1,67 @@
+/***************************************************************************
+ |FILENAME| - description
+ -------------------
+ begin : |DATE|
+ copyright : (C) |YEAR| by |AUTHOR|
+ email : |EMAIL|
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * The PSK part is based on WinPSK 1.0 by Moe Wheatley, AE4JY *
+ ***************************************************************************/
+
+#ifndef FREQUENCYSELECT_H
+#define FREQUENCYSELECT_H
+
+#include <QGroupBox>
+#include "constants.h"
+class QRadioButton;
+class QSpinBox;
+
+class FrequencySelect : public QGroupBox
+{
+ Q_OBJECT
+
+public:
+ FrequencySelect( QWidget* parent = 0, AfcMode WithMode = Wide);
+ ~FrequencySelect();
+
+ QRadioButton* Activate;
+ QSpinBox* Frequency;
+
+ void setFunctionText( QString text );
+ AfcMode getAfcMode();
+ void setAfcMode(AfcMode);
+ void setAfcDisplayMode(AfcMode);
+
+public slots:
+ double getFrequency();
+ void setFrequency( double );
+
+protected:
+ void resizeEvent( QResizeEvent * );
+
+
+protected slots:
+ virtual void languageChange();
+ void checkFrequency(int);
+ void toggleWide();
+ void toggleActivate();
+
+private:
+ double frequency;
+ QRadioButton* AfcWide;
+ void calculateSizeofComponents();
+ AfcMode modus;
+signals:
+ void FrequencyChanged(double);
+// void toggleAFC(bool);
+
+};
+
+#endif // FREQUENCYSELECT_H
diff --git a/src/fskmodulator.cpp b/src/fskmodulator.cpp
new file mode 100644
index 0000000..0f373db
--- /dev/null
+++ b/src/fskmodulator.cpp
@@ -0,0 +1,66 @@
+/***************************************************************************
+ fskmodulator.cpp - description
+ -------------------
+ begin : Sam M�r 1 2003
+ copyright : (C) 2003 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#include "fskmodulator.h"
+#include "constants.h"
+
+FSKModulator::FSKModulator(int FS,CTxBuffer * TxBuffer ):CModulator(FS,TxBuffer)
+{
+NxSamples=0;
+NumberofTones=0;
+Frequencyr=1.;
+Frequencyi=0.;
+
+}
+FSKModulator::~FSKModulator()
+{
+}
+int FSKModulator::CalcSignal( double* pData , int Bufsize)
+{
+ double temp;
+
+for(int i=0;i<Bufsize;i++)
+ {
+ if (NxSamples >=SamplesperSymbol)
+ {
+ c=getToneNumber();
+ NxSamples=0;
+ }
+ if ( c < 0)
+ {
+ if (i > 0)
+ {
+ i--; // We should stop transmission
+ return -i;
+ }
+ else
+ return -1;
+ }
+ // Calculate next Sample
+temp = Frequencyr *ToneFrequencyr[c] - Frequencyi*ToneFrequencyi[c];
+Frequencyi = Frequencyr *ToneFrequencyi[c] + Frequencyi*ToneFrequencyr[c];
+Frequencyr = temp;
+temp = 0.95*(2.0 -(Frequencyr*Frequencyr+Frequencyi*Frequencyi));
+Frequencyr *=temp;
+Frequencyi *=temp;
+
+ pData[i] = Frequencyr;
+ NxSamples++;
+ }
+return Bufsize;
+
+}
+
diff --git a/src/fskmodulator.h b/src/fskmodulator.h
new file mode 100644
index 0000000..71900a1
--- /dev/null
+++ b/src/fskmodulator.h
@@ -0,0 +1,48 @@
+/***************************************************************************
+ fskmodulator.h - description
+ -------------------
+ begin : Sam M�r 1 2003
+ copyright : (C) 2003 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * The PSK part is based on WinPSK 1.0 by Moe Wheatley, AE4JY *
+ ***************************************************************************/
+
+#ifndef FSKMODULATOR_H
+#define FSKMODULATOR_H
+
+#include "cmodulator.h"
+
+/**
+ *@author Volker Schroer
+ */
+
+class FSKModulator : public CModulator {
+public:
+ FSKModulator(int,CTxBuffer *);
+ ~FSKModulator();
+ int CalcSignal( double* pData , int n);
+protected:
+virtual int getToneNumber()=0;
+unsigned int NumberofTones;
+//double *ToneFrequencyr;
+//double *ToneFrequencyi;
+double ToneFrequencyr[16];
+double ToneFrequencyi[16];
+double Frequencyr,Frequencyi;
+
+unsigned int SamplesperSymbol;
+float Baudrate;
+unsigned int NxSamples;
+private:
+int c;
+};
+
+#endif
diff --git a/src/input.cpp b/src/input.cpp
new file mode 100644
index 0000000..f69ed70
--- /dev/null
+++ b/src/input.cpp
@@ -0,0 +1,47 @@
+/***************************************************************************
+ input.cpp - description
+ -------------------
+ begin : Sat May 5 2001
+ copyright : (C) 2001 by Volker Schroer
+ email : DL1KSV at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#include "input.h"
+#include <errno.h>
+Input::Input ( int ptt ) : QThread()
+{
+ serial = ptt;
+}
+Input::~Input()
+{
+}
+void Input::run()
+{
+ started = true;
+ while ( started )
+ {
+ msleep ( 300 );
+ emit samplesAvailable();
+ }
+}
+void Input::stop()
+{
+ started = false;
+}
+
+
+
+
+
+
+
+
+
diff --git a/src/input.h b/src/input.h
new file mode 100644
index 0000000..ba7b75f
--- /dev/null
+++ b/src/input.h
@@ -0,0 +1,71 @@
+/***************************************************************************
+ input.h - description
+ -------------------
+ begin : Sat May 5 2001
+ copyright : (C) 2001 by Volker Schroer
+ email : DL1KSV at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifndef INPUT_H
+#define INPUT_H
+
+#include <QString>
+#include <QThread>
+#include <sys/ioctl.h>
+#include <cstdio>
+#include <fcntl.h>
+
+
+
+/**Abstract base class for the different input devices like soundcard, textfile, Wavfile
+ *@author Volker Schroer
+ */
+
+
+class Input: public QThread
+{
+ Q_OBJECT
+ public:
+ Input ( int ptt );
+ virtual ~Input();
+
+ /** Opens the Device named Device for reading */
+ virtual bool open_Device_read ( QString * ) = 0;
+
+ /** Opens the Device named Device for writing */
+ virtual bool open_Device_write ( QString * ) = 0;
+
+ /** Closes the open Device */
+ virtual bool close_Device() = 0 ;
+
+ /** Tries to read anzahl samples and returns the nuber of read samples */
+ virtual int getSamples ( double *sample, int anzahl ) = 0;
+
+ /** Tries to write anzahl samples and returns the nuber of written samples */
+ virtual int putSamples ( double *sample, int anzahl ) = 0;
+
+ /** Switches PTT */
+ virtual void PTT ( bool mode ) = 0;
+ /** Stopping the Thread **/
+ void stop();
+ signals:
+ void samplesAvailable();
+ protected:
+
+ /** Filedescriptor of PTT- Device */
+ int serial;
+ void run(); //Running the thread
+ bool started;
+
+
+};
+
+#endif
diff --git a/src/interleaver.cpp b/src/interleaver.cpp
new file mode 100644
index 0000000..6c5b89a
--- /dev/null
+++ b/src/interleaver.cpp
@@ -0,0 +1,52 @@
+/***************************************************************************
+ interleaver.cpp - description
+ -------------------
+ begin : Sam M�r 1 2003
+ copyright : (C) 2003 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * The interleaver follows a proposal of Chen, W7AY *
+ * Instead of dinterleaving in multiple steps the interleaving is done *
+ * in one single step *
+ * Many thanks to Chen, for the allowance to use his idea *
+ ***************************************************************************/
+
+#include "interleaver.h"
+
+Interleaver::Interleaver ( int grade )
+{
+ interleaverGrade = grade * 4;
+delayLine= new unsigned char[interleaverGrade*4];
+ for ( int i = 0; i < interleaverGrade*4 ; i++ )
+ delayLine[i] = 0;
+ index = 0;
+offset=grade*3;
+}
+Interleaver::~Interleaver()
+{}
+int Interleaver::interleave ( unsigned char *inout )
+{
+ int i,code;
+ for ( i = 0;i < 4; i++ )
+ delayLine[index+interleaverGrade*i]=inout[i];
+code=0;
+ for ( i = 0;i < 4; i++ )
+{
+ inout[i] = delayLine[(index+i*offset)%interleaverGrade+i*interleaverGrade ];
+if(inout[i] != 0 )
+ code |= (1 << (3-i) );
+}
+ index = ( index + 1) % interleaverGrade;
+return code;
+}
diff --git a/src/interleaver.h b/src/interleaver.h
new file mode 100644
index 0000000..34be99a
--- /dev/null
+++ b/src/interleaver.h
@@ -0,0 +1,39 @@
+/***************************************************************************
+ interleaver.h - description
+ -------------------
+ begin : Sam M�r 1 2003
+ copyright : (C) 2003 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * The PSK part is based on WinPSK 1.0 by Moe Wheatley, AE4JY *
+ ***************************************************************************/
+
+#ifndef INTERLEAVER_H
+#define INTERLEAVER_H
+
+
+/**
+ *@author Volker Schroer
+ */
+
+class Interleaver {
+public:
+ Interleaver(int);
+ ~Interleaver();
+int interleave(unsigned char* inout);
+private:
+unsigned char * delayLine;
+int interleaverGrade;
+int index;
+int offset;
+
+};
+
+#endif
diff --git a/src/linpsk.cpp b/src/linpsk.cpp
new file mode 100644
index 0000000..53344e0
--- /dev/null
+++ b/src/linpsk.cpp
@@ -0,0 +1,982 @@
+/***************************************************************************
+ |FILENAME| - description
+ -------------------
+ begin : |DATE|
+ copyright : (C) |YEAR| by |AUTHOR|
+ email : |EMAIL|
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * The PSK part is based on WinPSK 1.0 by Moe Wheatly, AE4JY *
+ ***************************************************************************/
+
+#include "linpsk.h"
+
+
+#include "controlpanel.h"
+#include "crxdisplay.h"
+#include "ctxdisplay.h"
+
+#include "parameter.h"
+#include "addrxwindow.h"
+#include "spectrumdisplay.h"
+#include "frequencyselect.h"
+#include "cledbutton.h"
+#include "rttymodulator.h"
+#include "pskmodulator.h"
+#include "bpskmodulator.h"
+#include "qpskmodulator.h"
+#include "mfskmodulator.h"
+#include "ctxbuffer.h"
+#include "crxchannel.h"
+#include "input.h"
+#include "textinput.h"
+#include "waveinput.h"
+#include "csound.h"
+#include "generalsettings.h"
+#include "modemenu.h"
+#include "macrowindow.h"
+#include "addmacro.h"
+#include "deletemacro.h"
+#include "macros.h"
+#include "qsodata.h"
+#include "editmacro.h"
+#include "deletemacro.h"
+#include "renamemacro.h"
+#include "color.h"
+#include "crecording.h"
+
+
+#include <QtGui>
+#include <QEventLoop>
+
+#ifdef HAVE_CONFIG
+#include "config.h"
+#else
+#define VERSION "1.1"
+#endif
+
+
+#define ProgramName "LinPSK "
+
+extern Parameter settings;
+/*
+ * Constructs a LinPSK as a child of 'parent', with the
+ * name 'name' and widget flags set to 'f'.
+ *
+ */
+LinPSK::LinPSK ( QWidget* parent, Qt::WFlags fl )
+ : QMainWindow ( parent, fl )
+{
+ RxDisplay = 0;
+ TxDisplay = 0;
+ Control = 0;
+ Sound = 0;
+ SaveParameters = new Parameter();
+
+ Macro = new Macros(); // Macros will be used in read_config
+ read_config();
+
+ if ( settings.ApplicationFont == 0 )
+ {
+ settings.ApplicationFont = new QFont ( qApp->font().family() );
+ settings.ApplicationFont->setPixelSize ( 10 );
+ qApp->setFont ( *settings.ApplicationFont );
+ }
+ else
+ qApp->setFont ( *settings.ApplicationFont );
+
+// Save Settings to be able to make local modifications
+ *SaveParameters = settings;
+
+ if ( WindowColors.size() == 0 )
+ WindowColors << color[0] ;
+ Modulator = 0;
+ setCentralWidget ( new QWidget ( this ) );
+ centralWidget()->setMinimumSize ( settings.MinimumWindowWidth, settings.MinimumWindowHeight );
+ setWindowTitle ( QString ( ProgramName ) + QString ( VERSION ) );
+ setWindowIcon ( QIcon ( ":/images/linpsk.png" ) );
+// Create Statusbar
+ QStatusBar *StatusBar = this->statusBar();
+ StatusBar->setSizeGripEnabled ( true );
+
+
+//Messages
+ msg = new QLabel ( StatusBar );
+ StatusBar->addPermanentWidget ( msg, 2 );
+ msg->setText ( tr ( "Ready" ) );
+
+// IMD
+ IMD = new QLabel ( StatusBar );
+ StatusBar -> addPermanentWidget ( IMD, 1 );
+
+
+// Time
+ zeit = new QLabel ( StatusBar );
+ StatusBar->addPermanentWidget ( zeit, 1 );
+
+// date
+ datum = new QLabel ( StatusBar );
+ StatusBar ->addPermanentWidget ( datum, 1 );
+ setclock();
+
+// Let the time pass
+ QTimer *clock = new QTimer ( this );
+ connect ( clock, SIGNAL ( timeout() ), SLOT ( setclock() ) );
+ clock->start ( 60000 );
+
+ RxDisplay = new CRxDisplay ( centralWidget() );
+ TxDisplay = new CTxDisplay ( centralWidget() );
+
+ Control = new ControlPanel ( Macro, centralWidget() );
+ RxDisplay->RxFreq->setAfcDisplayMode ( settings.ActChannel->AfcProperties() );
+ RxDisplay->RxFreq->setAfcMode ( settings.ActChannel->getAfcMode() );
+ RxDisplay->setColorList ( &WindowColors );
+ connect ( RxDisplay, SIGNAL ( copyCallSign ( QString ) ), Control->QSO, SLOT ( copyCallSign ( QString ) ) );
+ connect ( RxDisplay, SIGNAL ( copyQTH ( QString ) ), Control->QSO, SLOT ( copyQTH ( QString ) ) );
+ connect ( RxDisplay, SIGNAL ( copyName ( QString ) ), Control->QSO, SLOT ( copyName ( QString ) ) );
+ connect ( RxDisplay, SIGNAL ( copyLocator ( QString ) ), Control->QSO, SLOT ( copyLocator ( QString ) ) );
+ connect ( RxDisplay, SIGNAL ( copyRST ( QString ) ), Control->QSO, SLOT ( copyRST ( QString ) ) );
+
+ settings.QslData = settings.ActChannel->getQsoData();
+ Control->Display->setPhasePointer ( settings.ActChannel->getPhasePointer() );
+
+ Control->Display->setColorList ( &WindowColors );
+ //Control->MacroBox->updateMacroWindow ( Macro );
+ // menubar
+ menubar = menuBar();
+// File Menu
+ fileMenu = menubar->addMenu ( tr ( "File" ) );
+ // Settings Menu
+
+ editMenu = menubar->addMenu ( tr ( "Settings" ) );
+
+ menubar->addSeparator();
+//=======
+ changeRxParams = menubar->addMenu ( tr ( "RxParams" ) );
+ helpMenu = menubar->addMenu ( tr ( "Help" ) );
+ QAction *A;
+ // File Menu
+ // ================= File Actions ========
+ A = fileMenu->addAction ( tr ( "Open Demo File" ) );
+ connect ( A, SIGNAL ( activated() ), this, SLOT ( fileOpen() ) );
+ A = fileMenu->addAction ( tr ( "add RxWindow" ) );
+ connect ( A, SIGNAL ( activated() ), this, SLOT ( addRxWindow() ) );
+
+ fileMenu->addSeparator();
+ fileMenu->addSeparator();
+
+ A = fileMenu->addAction ( tr ( "Exit" ) );
+ connect ( A, SIGNAL ( activated() ), this, SLOT ( Exit() ) );
+
+// Settings Menu
+ // ================= Settings Actions=================
+ A = editMenu->addAction ( tr ( "General_Settings" ) );
+ connect ( A, SIGNAL ( activated() ), this, SLOT ( generalSettings() ) );
+ editMenu->addSeparator();
+ A = editMenu->addAction ( tr ( "Add Macros" ) );
+ connect ( A, SIGNAL ( activated() ), this, SLOT ( addMacro() ) );
+ A = editMenu->addAction ( tr ( "Edit Macros" ) );
+ connect ( A , SIGNAL ( activated() ), this, SLOT ( editMacro() ) );
+ A = editMenu->addAction ( tr ( "Delete Macros" ) );
+ connect ( A , SIGNAL ( activated() ), this, SLOT ( deleteMacro() ) );
+ A = editMenu->addAction ( tr ( "Rename Macros" ) );
+ connect ( A , SIGNAL ( activated() ), this, SLOT ( renameMacro() ) );
+//===============================================================================
+ A = editMenu->addSeparator();
+
+ A = editMenu->addAction ( tr ( "Font Settings" ) );
+ connect ( A , SIGNAL ( activated() ), this, SLOT ( FontSetup() ) );
+ A = editMenu->addAction ( tr ( "ColorSettings" ) );
+ connect ( A , SIGNAL ( activated() ), this, SLOT ( chooseColor() ) );
+ editMenu->addSeparator();
+
+ A = editMenu->addAction ( tr ( "Save Settings" ) );
+ connect ( A , SIGNAL ( activated() ), this, SLOT ( saveSettings() ) );
+ // Menu Rx Settings
+ //================Actions for RX Window ===========
+ A = changeRxParams->addAction ( tr ( "Change Rx Mode" ) );
+ connect ( A , SIGNAL ( activated() ), this, SLOT ( setRxMode() ) );
+// A= changeRxParams->addAction(tr( " ???") );
+// connect ( A , SIGNAL ( activated() ), settings.ActChannel, SLOT ( clearRxWindow() ) );
+//Help Menu
+ // ================= Help Actions =========
+ A = helpMenu->addAction ( tr ( "helpContentsAction" ) );
+ connect ( A, SIGNAL ( activated() ), this, SLOT ( helpIndex() ) );
+ A = helpMenu->addAction ( tr ( "helpIndexAction" ) );
+ connect ( A, SIGNAL ( activated() ), this, SLOT ( helpContents() ) );
+ A = helpMenu->addAction ( tr ( "helpAboutAction" ) );
+ connect ( A, SIGNAL ( activated() ), this, SLOT ( helpAbout() ) );
+
+
+ languageChange();
+
+ // signals and slots connections
+
+//================================= Rx Parames ===================
+//================================================================
+ connect ( TxDisplay, SIGNAL ( startRx() ), this, SLOT ( startRx() ) );
+ connect ( TxDisplay, SIGNAL ( startTx() ), this, SLOT ( startTx() ) );
+ connect ( Macro, SIGNAL ( StartRx() ), this, SLOT ( startRx() ) );
+ connect ( Macro, SIGNAL ( StartTx() ), this, SLOT ( startTx() ) );
+
+ connect ( RxDisplay, SIGNAL ( startPlotting ( double *, bool ) ), Control->Display, SLOT ( startPlot ( double *, bool ) ) );
+ connect ( Control->Display, SIGNAL ( FrequencyChanged ( double ) ), RxDisplay->RxFreq, SLOT ( setFrequency ( double ) ) );
+ connect ( RxDisplay, SIGNAL ( new_IMD ( float ) ), this, SLOT ( setIMD ( float ) ) );
+ connect ( Control->MacroBox, SIGNAL ( callMacro ( int ) ), this, SLOT ( executeMacro ( int ) ) );
+ connect ( RxDisplay, SIGNAL ( newActiveChannel() ), this, SLOT ( setChannelParams() ) );
+ connect ( RxDisplay->Recording->Record, SIGNAL ( toggled ( bool ) ), this, SLOT ( recording ( bool ) ) );
+//===================================================================
+
+ TxBuffer = new CTxBuffer();
+ TxDisplay->TxWindow->setTxBuffer ( TxBuffer );
+ apply_settings();
+
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+LinPSK::~LinPSK()
+{
+
+ // no need to delete child widgets, Qt does it all for us
+}
+
+/*
+ * Sets the strings of the subwidgets using the current
+ * language.
+ */
+void LinPSK::languageChange()
+{
+ /**
+ // File
+ Open_Demo_File->setText( tr( "Open Demo File" ) );
+ Open_Demo_File->setMenuText( tr( "&Open Demo File" ) );
+ Open_Demo_File->setAccel( tr( "Ctrl+O" ) );
+ fileExitAction->setText( tr( "Exit" ) );
+ fileExitAction->setMenuText( tr( "E&xit" ) );
+ fileExitAction->setAccel( QString::null );
+ // Help
+ helpContentsAction->setText( tr( "Contents" ) );
+ helpContentsAction->setMenuText( tr( "&Contents..." ) );
+ helpContentsAction->setAccel( QString::null );
+ helpIndexAction->setText( tr( "Index" ) );
+ helpIndexAction->setMenuText( tr( "&Index..." ) );
+ helpIndexAction->setAccel( QString::null );
+ helpAboutAction->setText( tr( "About" ) );
+ helpAboutAction->setMenuText( tr( "&About" ) );
+ helpAboutAction->setAccel( QString::null );
+ add_Rx_Window->setText( tr( "add Rx Window" ) );
+ add_Rx_Window->setMenuText( tr( "&Add another RxWindow" ) );
+ // Settings
+ General_Settings->setText( tr( "General Settings" ) );
+ AddMacros->setText( tr( "Add Macro" ) );
+ FontSettings->setText( tr( "Font Settings" ) );
+ ColorSettings->setText( tr( "Color Settings" ) );
+ EditMacros->setText( tr( "Edit Macro" ) );
+ DeleteMacros->setText( tr("Delete Macro") );
+ RenameMacros->setText( tr("Rename Macro") );
+ // EditFiles->setText( tr( "Edit Files" ) );
+ SaveSettings->setText( tr( "Save Settings" ) );
+ // Rx Params
+ Clear_RxWindow->setMenuText( tr ("Clear active RX Channel") );
+ ChangeRxMode->setMenuText( tr ("Change Mode of active Rx Channel") );
+
+ menubar->findItem( 0 )->setText( tr( "&File" ) );
+ menubar->findItem( 1 )->setText( tr( "&Settings" ) );
+ menubar->findItem( 2 )->setText( tr( "&RxParams" ) );
+ menubar->findItem( 4 )->setText( tr( "&Help" ) );
+ **/
+}
+
+void LinPSK::fileOpen()
+{
+ QString fileName;
+
+ fileName = QFileDialog::getOpenFileName ( 0, tr ( "Open Demofile" ), "", settings.DemoModeFileType[settings.DemoTypeNumber] );
+ if ( !fileName.isEmpty() )
+ settings.inputFilename = fileName;
+}
+
+void LinPSK::Exit()
+{
+ if ( settings.Status == ON ) // We arejust transmitting
+ {
+ QMessageBox::information ( 0, ProgramName,
+ "You should stop transmitting before closing this window!" );
+ return;
+ }
+ else
+ {
+ if ( RxDisplay != 0 )
+ RxDisplay->stop_process_loop();
+ settings = *SaveParameters;
+ save_config();
+ qApp->quit();
+ return;
+ }
+}
+
+void LinPSK::helpIndex()
+{}
+
+void LinPSK::helpContents()
+{}
+
+void LinPSK::helpAbout()
+{}
+
+
+void LinPSK::addRxWindow()
+{
+ AddRxWindow *Channel = new AddRxWindow();
+ if ( Channel->exec() != 0 )
+ {
+ AfcMode modus;
+ modus = RxDisplay->RxFreq->getAfcMode();
+ settings.ActChannel->setAfcMode ( modus );
+ Mode rxmode = ( Mode ) Channel->selectedMode();
+ if ( WindowColors.size() <= settings.RxChannels )
+ WindowColors << color[ ( settings.RxChannels*51 ) % 256];
+
+ RxDisplay->addRxWindow ( Channel->frequency(), rxmode, Channel->titleText() );
+
+ settings.ActChannel->setWindowColor ( WindowColors.at ( settings.RxChannels ) );
+ settings.RxChannels++;
+ RxDisplay->RxFreq->setAfcDisplayMode ( settings.ActChannel->AfcProperties() );
+ }
+
+}
+
+
+
+void LinPSK::calculateSizeofComponents()
+{
+ /** Anteile in percent of mainwindow **/
+ /** RXDisplay **/
+#define RXPART 36
+ /** TXDisplay **/
+#define TXPART 20
+ /** Controlpanel **/
+#ifndef LINPSK_FOR_MAC
+#define CONTROLPART 37
+#else
+#define CONTROLPART 40
+#endif
+
+ int width, height;
+ int xpos, ypos;
+ int windowsheight;
+
+ width = this->width();
+ height = this->height();
+
+ xpos = 0;
+ ypos = 0;;
+ windowsheight = height * RXPART / 100;
+ if ( RxDisplay != 0 )
+ RxDisplay->setGeometry ( xpos, ypos, width, windowsheight );
+
+ ypos = ypos + windowsheight;
+ windowsheight = height * TXPART / 100;
+ if ( TxDisplay != 0 )
+ TxDisplay->setGeometry ( xpos, ypos, width, windowsheight );
+ ypos = ypos + windowsheight;
+
+ windowsheight = height * CONTROLPART / 100;
+ if ( Control != 0 )
+ Control->setGeometry ( xpos, ypos, width, windowsheight );
+}
+
+
+
+void LinPSK::resizeEvent ( QResizeEvent * )
+{
+ calculateSizeofComponents();
+}
+
+
+void LinPSK::setclock()
+{
+ QString s;
+ QDateTime t;
+ t = QDateTime::currentDateTime();
+ t = t.addSecs ( settings.timeoffset * 3600 );
+ s.sprintf ( " %2d:%2d UTC", t.time().hour(), t.time().minute() );
+ s.replace ( QRegExp ( ": " ), ":0" );
+ zeit->setText ( s );
+ zeit->update();
+ s = t.toString ( "dd.MM.yyyy" );
+ datum->setText ( s );
+}
+
+void LinPSK::setIMD ( float IMDvalue )
+{
+ QString s;
+ if ( IMDvalue != 0.0 )
+ s.sprintf ( " IMD = %6.2f dB", IMDvalue );
+ else
+ s.sprintf ( " IMD " );
+ IMD->setText ( s );
+}
+void LinPSK::startRx()
+{
+ if ( Modulator != 0 )
+ {
+ TxBuffer->insert ( TXOFF_CODE );
+ if ( Sound > 0 ) // Switch Trx to rx
+ while ( Sound->isRunning() ) // Wait for buffer to be cleared
+ qApp->processEvents ( QEventLoop::AllEvents, 100 );
+ }
+ if ( RxDisplay->start_process_loop() )
+ {
+ QString Info;
+ TxDisplay->TxFunctions->setStatus ( OFF );
+ if ( settings.ActChannel != 0 )
+ switch ( settings.ActChannel->getModulationType() )
+ {
+ case QPSK:
+ Info = "QPSK";
+ break;
+
+ case BPSK:
+ Info = "BPSK";
+ break;
+
+ case RTTY:
+ Info = "RTTY";
+ break;
+
+ case MFSK16:
+ Info = "MFSK16";
+ break;
+
+
+ default:
+ Info = "undefined";
+ }
+
+ msg->setText ( tr ( "Receiving " ) + Info );
+ }
+ else
+ TxDisplay->TxFunctions->setStatus ( UNDEF );
+ Control->Display->show();
+ settings.Status = TxDisplay->TxFunctions->getstatus();
+TxDisplay->TxWindow->setFocus();
+}
+
+void LinPSK::startTx()
+{
+ Mode ModulationType;
+ QString errorstring;
+ QString Info;
+ double Frequency;
+
+
+ RxDisplay->stop_process_loop();
+ if ( settings.ActChannel == 0 )
+ {
+ QMessageBox::critical ( 0, " Programm Error! LinPsk", "No active Channel available" );
+ TxDisplay->TxFunctions->setStatus ( UNDEF );
+ return;
+ }
+ ModulationType = settings.ActChannel->getModulationType();
+ if ( TxDisplay->TxFreq->getAfcMode() != Off ) // net ?
+ TxDisplay->TxFreq->setFrequency ( settings.ActChannel->getRxFrequency() );
+ Frequency = TxDisplay->TxFreq->getFrequency();
+ switch ( ModulationType )
+ {
+ case QPSK:
+ Modulator = new QPskModulator ( 11025, Frequency, TxBuffer );
+ Info = "QPSK";
+ break;
+ case BPSK:
+ Modulator = new BPSKModulator ( 11025, Frequency, TxBuffer );
+ Info = "BPSK";
+ break;
+
+ case RTTY:
+ Modulator = new RTTYModulator ( 11025, Frequency, TxBuffer );
+ if ( settings.ActChannel->getParameter ( Extra ) != 0 )
+ Modulator->setParameter ( Extra, settings.ActChannel->getParameter ( Extra ) );
+ Info = "RTTY";
+ break;
+ case MFSK16:
+ Modulator = new MFSKModulator ( 11025, Frequency, TxBuffer );
+ Info = "MFSK16";
+ break;
+
+ default:
+ Modulator = new BPSKModulator ( 11025, Frequency, TxBuffer );
+ Info = "BPSK";
+ break;
+ }
+ if ( Sound <= 0 ) // Only create Sound Device once for output
+ {
+ if ( settings.DemoMode )
+ {
+ if ( settings.DemoTypeNumber == 0 )
+ Sound = new WaveInput ( -1 );
+ else
+ Sound = new TextInput ( -1 );
+ msg->setText ( tr ( "Transmitting (Demo)" ) );
+ }
+ else
+ Sound = new CSound ( settings.serial );
+ connect ( Sound, SIGNAL ( samplesAvailable() ), this, SLOT ( process_txdata() ) );
+ }
+ if ( Sound <= 0 )
+ {
+ QMessageBox::critical ( 0, " Programm Error! LinPsk", "Could not create Sound Device for Output" );
+ TxDisplay->TxFunctions->setStatus ( ON );
+ return;
+ }
+
+ if ( Sound->open_Device_write ( &errorstring ) < 0 )
+ {
+ QMessageBox::information ( 0, ProgramName, errorstring );
+ stopTx();
+ return;
+ }
+
+ connect ( Modulator, SIGNAL ( charSend ( char ) ), settings.ActChannel, SLOT ( updateRx ( char ) ) );
+ TxDisplay->TxFunctions->setStatus ( ON );
+ msg->setText ( tr ( "Transmitting " ) + Info );
+ TxDisplay->TxWindow->setFocus();
+ settings.Status = TxDisplay->TxFunctions->getstatus();
+ Control->Display->hide();
+
+ Txcount = BUF_SIZE;
+// process_txdata(); // Generate first Sample
+ Sound->PTT ( true );
+ Sound->start();
+}
+
+void LinPSK::process_txdata()
+{
+ int length;
+// To avoid pending calls to process_txdata() after stopping tx
+// when Modulator is alredy deleted
+ if (Modulator == 0)
+ return;
+ if ( Txcount > 0 )
+ {
+ length = Modulator->CalcSignal ( Output, BUF_SIZE );
+ if ( length <= 0 )
+ {
+
+ length = -length;
+ while ( length < BUF_SIZE )
+ Output[length++] = 0.0;
+ length = BUF_SIZE;
+ Txcount = Sound->putSamples ( Output, length );
+ stopTx();
+ return;
+ }
+ }
+ else
+ length = BUF_SIZE;
+
+ Txcount = Sound->putSamples ( Output, length ); // If Txcount >= 0 and length < BUF_SIZE
+ // we've reached end of Transmiision
+
+}
+
+void LinPSK::generalSettings()
+{
+ GeneralSettings *LocalSettings = new GeneralSettings ( this );
+ if ( LocalSettings->exec() != 0 )
+ settings = LocalSettings->getSettings();
+ apply_settings();
+}
+void LinPSK::chooseColor()
+{
+ int ID = settings.ActChannel->getID();
+ QColor color = QColorDialog::getColor ( WindowColors[ID], this );
+ if ( color.isValid() )
+ {
+ settings.ActChannel->setWindowColor ( color );
+ WindowColors[ID] = color;
+ RxDisplay->repaint();
+ RxDisplay->newColor();
+ }
+
+}
+void LinPSK::FontSetup()
+{
+ bool ok;
+ QFont f = QFontDialog::getFont ( &ok, font(), this );
+ if ( ok )
+ {
+ settings.ApplicationFont->setFamily ( f.family() );
+ int ii = f.pixelSize();
+ if ( ii <= 0 )
+ {
+ ii = f.pointSize();
+ settings.ApplicationFont->setPointSize ( ii );
+ }
+ else
+ settings.ApplicationFont->setPixelSize ( ii );
+
+ qApp->setFont ( f );
+ }
+}
+void LinPSK::stopTx()
+{
+ Modulator->disconnect();
+ if ( Sound != 0 )
+ {
+ Sound->PTT ( false );
+ Sound->close_Device();
+ }
+ delete Modulator;
+ Modulator = 0;
+}
+
+void LinPSK::apply_settings()
+{
+ selectPTTDevice();
+}
+void LinPSK::setChannelParams()
+{
+ Control->Display->setPhasePointer ( settings.ActChannel->getPhasePointer() );
+ Control->QSO->newChannel();
+ if ( settings.ActChannel != 0 )
+ {
+ QString Info;
+ switch ( settings.ActChannel->getModulationType() )
+ {
+
+ case QPSK:
+ Info = "QPSK";
+ break;
+
+ case BPSK:
+ Info = "BPSK";
+ break;
+
+ case RTTY:
+ Info = "RTTY";
+ break;
+
+ case MFSK16:
+ Info = "MFSK16";
+ break;
+ default:
+ Info = "undefined";
+ }
+ RxDisplay->RxFreq->setAfcDisplayMode ( settings.ActChannel->AfcProperties() );
+ msg->setText ( tr ( "Receiving " ) + Info );
+ }
+}
+void LinPSK::setRxMode()
+{
+ QString Info;
+ ModeMenu Menu ;
+ ExtraParameter *Param;
+ Param = ( ExtraParameter * ) settings.ActChannel->getParameter ( Extra );
+ if ( Param != 0 )
+ Menu.setParameter ( *Param );
+ if ( Menu.exec() != 0 )
+ {
+ Mode rxmode = ( Mode ) Menu.selectedMode();
+ settings.ActChannel->setMode ( rxmode );
+ RxDisplay->RxFreq->setAfcDisplayMode ( settings.ActChannel->AfcProperties() );
+ RxDisplay->RxFreq->setAfcMode ( settings.ActChannel->getAfcMode() );
+ Control->Display->setPhasePointer ( settings.ActChannel->getPhasePointer() );
+ settings.ActChannel->setParameter ( Extra, &Menu.getParameter() );
+ }
+ if ( settings.ActChannel != 0 )
+ switch ( settings.ActChannel->getModulationType() )
+ {
+ case QPSK:
+ Info = "QPSK";
+ break;
+
+ case BPSK:
+ Info = "BPSK";
+ break;
+
+ case RTTY:
+ Info = "RTTY";
+ break;
+
+ case MFSK16:
+ Info = "MFSK16";
+ break;
+
+ default:
+ Info = "undefined";
+ }
+
+ msg->setText ( tr ( "Receiving " ) + Info );
+}
+
+void LinPSK::save_config()
+{
+ int i;
+ QSettings config ( "DL1KSV", "LinPSK" );
+ /** Windows Parameter **/
+ config.beginGroup ( "WindowsParameter" );
+// config.setValue ( "MinimumWindowWidth", settings.MinimumWindowWidth );
+ config.setValue ( "WindowWidth", width() );
+// config.setValue ( "MinimumWindowHeight", settings.MinimumWindowHeight );
+ config.setValue ( "Xpos", this->x() );
+ config.setValue ( "Ypos", this->y() );
+ config.setValue ( "WindowHeight", height() );
+ config.setValue ( "FontName", qApp->font().family() );
+ config.setValue ( "FontSize", qApp->font().pointSize() );
+ config.endGroup();
+ /** DemoMode **/
+ config.setValue ( "DemoMode", settings.DemoMode );
+ config.setValue ( "DemoTypeNumber", settings.DemoTypeNumber );
+//Operating
+ config.setValue ( "Callsign", settings.callsign );
+ config.setValue ( "MyLocator", settings.myLocator );
+
+ config.setValue ( "PTTDevice", settings.SerialDevice );
+//Logging
+ config.setValue ( "Directory", settings.Directory );
+ config.setValue ( "QSoFileName", settings.QSOFileName );
+ config.setValue ( "FileLog", settings.fileLog );
+ config.setValue ( "LinLog", settings.LinLog );
+ if ( settings.LinLog )
+ {
+ config.setValue ( "Host", settings.Host );
+ config.setValue ( "Port", settings.Port );
+ }
+
+ config.setValue ( "TimeOffset", settings.timeoffset );
+ config.setValue ( "dateFormat", settings.dateFormat );
+ config.setValue ( "Slashed0", settings.slashed0 );
+ config.setValue ("autoCrLf",settings.autoCrLf);
+ /** Colors **/
+ if ( WindowColors.size() > 0 )
+ {
+ config.beginWriteArray ( "Colors" );
+ for ( i = 0; i < WindowColors.size();i++ )
+ {
+ config.setArrayIndex ( i );
+ config.setValue ( "r", WindowColors[i].red() );
+ config.setValue ( "g", WindowColors[i].green() );
+ config.setValue ( "b", WindowColors[i].blue() );
+ }
+ config.endArray();
+ }
+// Macros
+ if ( ( Macro->count() > 0 ) )
+ {
+ config.beginWriteArray ( "Macros" );
+ for ( i = 0; i < Macro->count();i++ )
+ {
+ config.setArrayIndex ( i );
+ config.setValue ( "Name", Macro->getMacroName ( i ) );
+ QString s = Macro->getDefinition ( i );
+ config.setValue ( "Definition", s );
+ config.setValue ( "Accelerator", Macro->getAccelerator ( i ) );
+ }
+ config.endArray();
+ }
+
+}
+
+void LinPSK::executeMacro ( int MacroNumber )
+{
+ Macro->executeMacro ( MacroNumber, TxBuffer );
+}
+
+void LinPSK::addMacro()
+{
+
+ AddMacro *NewMacro = new AddMacro ( Macro );
+// NewMacro->setKeywords ( Macro );
+ if ( NewMacro->exec() != 0 )
+ {
+ Macro->insert ( NewMacro->macroName(),
+ NewMacro->macroDefinition(), NewMacro->accelerator(), NewMacro->position() );
+ Control->MacroBox->updateMacroWindow ( Macro );
+ }
+}
+void LinPSK::editMacro()
+{
+ if ( Macro->count() > 0 )
+ {
+ EditMacro *Edit = new EditMacro ( Macro );
+
+ if ( Edit->exec() != 0 )
+// Control->MacroBox->updateMacroWindow ( Macro );
+ Control->MacroBox->setMacroWindow ( Macro );
+ }
+}
+void LinPSK::deleteMacro()
+{
+ if ( Macro->count() > 0 )
+ {
+ DeleteMacro *Del = new DeleteMacro ( Macro );
+
+ if ( Del->exec() != 0 )
+ Control->MacroBox->setMacroWindow ( Macro );
+ }
+}
+void LinPSK::renameMacro()
+{
+ if ( Macro->count() > 0 )
+ {
+ RenameMacro *Ren = new RenameMacro ( Macro );
+
+ if ( Ren->exec() != 0 )
+ Control->MacroBox->setMacroWindow ( Macro );
+ }
+}
+
+void LinPSK::read_config()
+{
+ QSettings config ( "DL1KSV", "LinPSK" );
+
+ int HeighttoSet = 0;
+ int WidthtoSet = 0;
+ int X = -1;
+ int Y = -1;
+ int i, size;
+// Try to read settings from Configfile
+ /** Windows Parameter **/
+ config.beginGroup ( "WindowsParameter" );
+// settings.MinimumWindowWidth = config.value ( "MinimumWindowWidth" , 600 ).toInt();
+ WidthtoSet = config.value ( "WindowWidth" ).toInt();
+// settings.MinimumWindowHeight = config.value ( "MinimumWindowHeight", 400 ).toInt();
+ X = config.value ( "Xpos" ).toInt();
+ Y = config.value ( "Ypos" ).toInt();
+ HeighttoSet = config.value ( "WindowHeight" ).toInt();
+ if ( config.contains ( "FontName" ) )
+ {
+ settings.ApplicationFont = new QFont ( config.value ( "FontName" ).toString() );
+ size = config.value ( "FontSize" ).toInt();
+ if ( size < 10 )
+ size = 10;
+ settings.ApplicationFont->setPointSize ( size );
+
+ }
+ config.endGroup();
+ /** DemoMode **/
+ settings.DemoMode = config.value ( "DemoMode" ).toBool();
+ settings.DemoTypeNumber = config.value ( "DemoTypeNumber" ).toInt();
+//Operating
+ settings.callsign = config.value ( "Callsign" ).toString();
+ settings.myLocator = config.value ( "MyLocator" ).toString();
+
+ settings.SerialDevice = config.value ( "PTTDevice" ).toString();
+//Logging
+ settings.Directory = config.value ( "Directory", QDir::homePath() ).toString();
+
+ settings.QSOFileName = config.value ( "QSoFileName" ).toString();
+ settings.fileLog = config.value ( "FileLog", true ).toBool();
+ settings.LinLog = config.value ( "LinLog", false ).toBool();
+ if ( settings.LinLog )
+ {
+ settings.Host = config.value ( "Host", "localhost" ).toString();
+ settings.Port = config.value ( "Port", 8080 ).toInt();
+ }
+ settings.timeoffset = config.value ( "TimeOffset" ).toInt();
+ settings.dateFormat = config.value ( "dateFormat", "dd.MM.yyyy" ).toString();
+ settings.slashed0 = config.value ( "Slashed0" ).toBool();
+ settings.autoCrLf = config.value("autoCrLf").toBool();
+ /** Colors **/
+ if ( config.contains ( "Colors" ) )
+ {
+ size = config.beginReadArray ( "Colors" );
+ for ( i = 0; i < size;i++ )
+ {
+ config.setArrayIndex ( i );
+ int r = config.value ( "r" ).toInt();
+ int g = config.value ( "g" ).toInt();
+ int b = config.value ( "b" ).toInt();
+ WindowColors.push_back ( QColor ( r, g, b ) );
+
+ }
+ config.endArray();
+ }
+// Macros
+ size = config.beginReadArray ( "Macros" );
+ if ( size > 0 )
+ {
+ QString name, def, acc;
+
+ for ( i = 0; i < size;i++ )
+ {
+ config.setArrayIndex ( i );
+ name = config.value ( "Name" ).toString();
+ def = config.value ( "Definition" ).toString();
+ acc = config.value ( "Accelerator" ).toString();
+ Macro->insert ( name, def, acc, i + 1 );
+ }
+ config.endArray();
+ }
+
+ if ( ( HeighttoSet > 0 ) && ( WidthtoSet > 0 ) )
+ resize ( WidthtoSet, HeighttoSet );
+ if ( ( X >= 0 ) && ( Y >= 0 ) )
+ move ( X, Y );
+
+}
+void LinPSK::selectPTTDevice()
+{
+
+//if (settings.serial >0 )
+// close(settings.serial);
+ settings.serial = -1;
+ if ( settings.SerialDevice != "None" )
+//{
+// QMessageBox::information(0,"LinPsk","Trying to open Device " + settings.SerialDevice);
+ settings.serial = open ( settings.SerialDevice.toAscii().data(), O_EXCL | O_WRONLY );
+// if (settings.serial > 0 )
+// QMessageBox::information(0,"LinPsk","Opening successfull");
+// else
+// QMessageBox::information(0,"LinPsk","Opening unsuccessfull");
+//}
+ int flags = TIOCM_RTS | TIOCM_DTR;
+ if ( settings.serial > 0 )
+ ioctl ( settings.serial, TIOCMBIC, &flags );
+ else
+ settings.SerialDevice = "None"; //Their seems to be a wrong Value in the ConfigFile
+}
+void LinPSK::recording ( bool on )
+{
+ settings.ActChannel->record ( on );
+}
+void LinPSK::HelpAbout()
+{
+ QMessageBox::about ( this, tr ( "About..." ),
+ ProgramName + QString ( VERSION ) + "\n written by Volker Schroer, DL1KSV\n" );
+// setActiveWindow();
+}
+
+void LinPSK::saveSettings()
+{
+ *SaveParameters = settings;
+ save_config();
+}
+
+void LinPSK::closeEvent ( QCloseEvent *e )
+{
+ if ( settings.Status != ON ) // We are not just transmitting
+ {
+ if ( RxDisplay != 0 )
+ RxDisplay->stop_process_loop();
+ e->accept();
+ save_config();
+ }
+ else
+ {
+ QMessageBox::information ( 0, ProgramName,
+ "You should stop transmitting before closing this window!" );
+ e->ignore();
+ }
+ return;
+}
+
diff --git a/src/linpsk.h b/src/linpsk.h
new file mode 100644
index 0000000..e039b8e
--- /dev/null
+++ b/src/linpsk.h
@@ -0,0 +1,146 @@
+/***************************************************************************
+ |FILENAME| - description
+ -------------------
+ begin : |DATE|
+ copyright : (C) |YEAR| by |AUTHOR|
+ email : |EMAIL|
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * The PSK part is based on WinPSK 1.0 by Moe Wheatley, AE4JY *
+ ***************************************************************************/
+
+#ifndef LINPSK_H
+#define LINPSK_H
+
+#include <QMainWindow>
+#include <QList>
+#include "constants.h"
+
+class QActionGroup;
+class QToolBar;
+class QMenu;
+class QCloseEvent;
+
+class CRxDisplay;
+class CTxDisplay;
+class ControlPanel;
+class QLabel;
+class CModulator;
+class CTxBuffer;
+class Input;
+class Macros;
+class Parameter;
+
+
+class LinPSK : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ LinPSK( QWidget* parent = 0,Qt::WFlags fl = 0);
+ ~LinPSK();
+
+ CRxDisplay* RxDisplay;
+ CTxDisplay* TxDisplay;
+ ControlPanel* Control;
+ QMenuBar *menubar;
+ QMenu *fileMenu;
+ QMenu *editMenu;
+ QMenu *changeRxParams;
+ QMenu *helpMenu;
+
+public slots:
+ virtual void fileOpen();
+ virtual void Exit();
+ virtual void helpIndex();
+ virtual void helpContents();
+ virtual void helpAbout();
+ virtual void addRxWindow();
+ virtual void generalSettings();
+ virtual void chooseColor();
+
+protected:
+ void resizeEvent(QResizeEvent *);
+
+protected slots:
+ virtual void languageChange();
+ /** Show Time */
+ void setclock();
+ /** Set IMD */
+ void setIMD(float);
+ /** Start Rx **/
+ void startRx();
+ /** Start Tx **/
+ void startTx();
+ /** Calculate the TX Data **/
+ void process_txdata();
+ /** Font Settings **/
+ void FontSetup();
+ /** Switching from TX to RX after TX- Bufefr ist empty **/
+ void stopTx();
+ /** apply the settings **/
+ void apply_settings();
+ /** Changig some Channel Parameters **/
+ void setChannelParams();
+ /** Changing Rx Mode ( Moulation type ) **/
+ void setRxMode();
+ /** Save Settings **/
+ void saveSettings();
+ /** Executing Macros **/
+ void executeMacro(int);
+ /** Add Macro **/
+ void addMacro();
+ /** Edit Macro **/
+ void editMacro();
+ /** Delete Macro **/
+ void deleteMacro();
+ /** Rename Macro **/
+ void renameMacro();
+ /** Recording **/
+ void recording(bool);
+ /** About Info **/
+ void HelpAbout();
+
+ /** Closing this window **/
+ void closeEvent( QCloseEvent *);
+
+private:
+
+ void calculateSizeofComponents();
+ void read_config();
+ void save_config();
+Parameter *SaveParameters;
+/** Modulator **/
+CModulator *Modulator;
+/** Characters to transmit **/
+CTxBuffer *TxBuffer;
+/** Signalbuffer **/
+double Output[BUF_SIZE];
+/** Numbers of Char to transmit **/
+unsigned int Txcount;
+/** Sound Device **/
+Input *Sound;
+/** To show messages in Statusbar */
+QLabel *msg;
+/** TxTimer **/
+///QTimer *TxTimer;
+
+void selectPTTDevice();
+
+/** To show date and time **/
+QLabel *datum;
+QLabel *zeit;
+QLabel *IMD;
+
+QLabel *clockadj;
+Macros *Macro;
+QList<QColor> WindowColors;
+};
+
+#endif // LINPSK_H
diff --git a/src/macros.cpp b/src/macros.cpp
new file mode 100644
index 0000000..f7f771d
--- /dev/null
+++ b/src/macros.cpp
@@ -0,0 +1,259 @@
+/***************************************************************************
+ Macros.cpp - description
+ -------------------
+ begin : Sam Mai 10 2003
+ copyright : (C) 2003 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#include "macros.h"
+#include "parameter.h"
+#include "ctxbuffer.h"
+#include <QDateTime>
+#include <QMessageBox>
+#include "constants.h"
+#include <QFile>
+#include <QTextStream>
+extern Parameter settings;
+
+Macros::Macros()
+{
+
+ Words << "@CALLSIGN@" << "@DATE@" << "@Replace by filename@" << "@RX@" << "@THEIRCALL@" << "@THEIRNAME@" << "@TIMELOCAL@" << "@TIMEUTC@" << "@TX@" << "@RSTGIVEN@" << "@RSTRCVD@";
+ NumberofMacros = 0;
+}
+Macros::~Macros()
+{
+}
+void Macros::insert ( QString Name, QString Definition, QString Acc, int position )
+{
+ if ( position <= NumberofMacros )
+ {
+ MacroNames.replace ( position - 1, Name );
+ MacroText.replace ( position - 1, Definition );
+ Accelerator.replace ( position - 1, Acc );
+ }
+ else
+ {
+ MacroNames << Name;
+ MacroText << Definition;
+ Accelerator << Acc;
+ }
+ NumberofMacros++;
+
+}
+void Macros::executeMacro ( int MacroNumber, CTxBuffer *TxBuffer )
+{
+ QString Macro = MacroText[MacroNumber];
+ QString Token;
+
+ int anzahl = Macro.count ( '@' ) / 2;
+ if ( anzahl > 0 )
+ {
+ int indexbis, indexvon = 0;
+ for ( int i = 0; i < anzahl; i++ )
+ {
+ indexbis = Macro.indexOf ( '@', indexvon );
+ indexvon = indexbis;
+ indexbis = Macro.indexOf ( '@', indexvon + 1 );
+ Token = Macro.mid ( indexvon, indexbis - indexvon + 1 );
+ if ( Token == Words[0] ) // callsign
+ {
+ Macro.replace ( indexvon, Words[0].length(), settings.callsign );
+
+ }
+ else
+ if ( Token == Words[1] ) // Date
+ {
+ QDate t = QDate::currentDate();
+ Macro.replace ( indexvon, Words[1].length(), t.toString ( QString ( "d.MM.yyyy" ) ) );
+
+ }
+ else
+ if ( Token == Words[3] ) // RX
+ {
+ Macro.remove ( indexvon, 4 );
+ if ( settings.Status == ON )
+ {
+ TxBuffer->insert ( Macro, indexvon );
+ emit StartRx();
+ }
+ return;
+ }
+ else
+ if ( Token == Words[4] ) // Remote callsign
+ {
+ Macro.replace ( indexvon, Words[4].length(), settings.QslData->RemoteCallsign );
+
+ }
+ else
+ if ( Token == Words[5] ) // Remote op's name
+ {
+ Macro.replace ( indexvon, Words[5].length(), settings.QslData->OpName );
+
+ }
+ else
+ if ( Token == Words[6] ) // Time Local
+ {
+ QDateTime t;
+ t = QDateTime::currentDateTime();
+
+ Macro.replace ( indexvon, Words[6].length(), t.toString ( "h:mm" ) );
+
+ }
+ else
+ if ( Token == Words[7] ) // Time UTC
+ {
+ QDateTime t;
+ t = QDateTime::currentDateTime();
+ t = t.addSecs ( settings.timeoffset * 3600 );
+ Macro.replace ( indexvon, Words[7].length(), t.toString ( "h:mm" ) );
+ }
+ else
+ if ( Token == Words[8] ) // TX
+ {
+ if ( settings.Status == UNDEF )
+ {
+ QMessageBox::warning ( 0, "Warning", "Please listen before transmitting",
+ QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton );
+
+ return;
+ }
+ Macro.remove ( indexvon, 4 );
+ if ( settings.Status == OFF )
+ emit StartTx();
+ }
+ else
+ if ( Token == Words[9] ) // RST given
+ {
+ Macro.replace ( indexvon, Words[9].length(), settings.QslData->MyRST );
+
+ }
+ else
+ if ( Token == Words[10] ) // RST received
+ {
+ Macro.replace ( indexvon, Words[10].length(), settings.QslData->HisRST );
+
+ }
+ else // Must be File
+ {
+ Macro.remove ( indexvon, Token.length() );
+ if ( indexvon > 0 )
+ {
+ TxBuffer->insert ( Macro, indexvon );
+ Macro.remove ( 0, indexvon );
+ indexvon = 0;
+ }
+ Token = Token.mid ( 1, Token.length() - 2 );
+ QFile MacroFile ( settings.Directory + QString ( "/" ) + Token );
+ if ( MacroFile.open ( QIODevice::ReadOnly ) )
+ {
+ QTextStream line ( &MacroFile );
+ while ( !line.atEnd() )
+ {
+ QString Txstring = line.readLine();
+ if(settings.autoCrLf) // AutoCrLF ??
+ Txstring += '\r';
+ Txstring += "\n";
+ TxBuffer->insert ( Txstring, Txstring.length() );
+ }
+ MacroFile.close();
+ }
+ else
+ QMessageBox::warning ( 0, "Warning", "File " + Token + " not found ",
+ QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton );
+
+ }
+ }
+
+
+ }
+ TxBuffer->insert ( Macro, Macro.length() );
+
+}
+
+void Macros::deleteMacro ( int number )
+{
+ if ( number < 0 || number >= NumberofMacros )
+ return;
+
+ MacroNames.erase ( MacroNames.begin() + number );
+ MacroText.erase ( MacroText.begin() + number );
+ Accelerator.erase ( Accelerator.begin() + number );
+
+ if ( NumberofMacros > 0 )
+ NumberofMacros--;
+}
+
+QString Macros::getMacroName ( int number )
+{
+
+ if ( number < 0 || number >= NumberofMacros )
+ return QString ( "" );
+ QString s = MacroNames.at ( number );
+ return s;
+}
+int Macros::count()
+{
+ return NumberofMacros;
+}
+QString Macros::getDefinition ( int number )
+{
+
+ if ( number < 0 || number >= NumberofMacros )
+ return QString ( "" );
+ return MacroText[number];
+}
+QString Macros::getAccelerator ( int number )
+{
+ if ( number < 0 || number >= NumberofMacros )
+ return QString ( "" );
+ return Accelerator[number];
+}
+int Macros::Keywordcount()
+{
+ return Words.size();;
+}
+QString Macros::getKeyword ( int number )
+{
+ if ( number < 0 || number >= Keywordcount() )
+ return QString ( "" );
+ return Words[number];
+}
+void Macros::setDefinition ( QString s, int position )
+{
+ if ( position < MacroText.size() )
+ MacroText.replace ( position, s );
+ else
+ MacroText << s;
+}
+void Macros::setAccelerator ( QString s, int position )
+{
+ if ( position < Accelerator.size() )
+ Accelerator.replace ( position, s );
+ else
+ Accelerator << s;
+}
+void Macros::setMacroName ( QString s, int MacroNumber )
+{
+ if ( MacroNumber < MacroNames.size() )
+ MacroNames.replace ( MacroNumber, s );
+ else
+ MacroNames << s;
+}
+QStringList Macros::getKeyWordList()
+{
+ return Words;
+}
+QStringList Macros::getMacroList()
+{
+ return MacroNames;
+}
diff --git a/src/macros.h b/src/macros.h
new file mode 100644
index 0000000..c105d09
--- /dev/null
+++ b/src/macros.h
@@ -0,0 +1,61 @@
+/***************************************************************************
+ keywords.h - description
+ -------------------
+ begin : Sam Mai 10 2003
+ copyright : (C) 2003 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * The PSK part is based on WinPSK 1.0 by Moe Wheatley, AE4JY *
+ ***************************************************************************/
+
+#ifndef MACROS_H
+#define MACROS_H
+#include <QObject>
+
+#include <QStringList>
+
+/**Contains the Keywords for Macro Processing
+Offers the methods for processing the Keywords
+ *@author Volker Schroer
+ */
+class CTxBuffer;
+class Macros : public QObject
+ {
+ Q_OBJECT
+public:
+ Macros();
+ ~Macros();
+void executeMacro(int,CTxBuffer *);
+void insert(QString ,QString , QString,int);
+void deleteMacro(int);
+QString getMacroName(int);
+QString getDefinition(int);
+void setDefinition(QString,int);
+void setAccelerator(QString,int);
+void setMacroName(QString,int);
+QString getAccelerator(int);
+QString getKeyword(int);
+QStringList getKeyWordList();
+QStringList getMacroList();
+int count();
+int Keywordcount();
+private:
+QStringList Words;
+QStringList MacroNames ;
+QStringList MacroText;
+QStringList Accelerator;
+int NumberofMacros;
+signals:
+void StartRx();
+void StartTx();
+
+};
+
+#endif
diff --git a/src/macrowindow.cpp b/src/macrowindow.cpp
new file mode 100644
index 0000000..2a78c06
--- /dev/null
+++ b/src/macrowindow.cpp
@@ -0,0 +1,135 @@
+/***************************************************************************
+ macros.cpp - description
+ -------------------
+ begin : Sam Mai 3 2003
+ copyright : (C) 2003 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#include "macrowindow.h"
+#include <QPushButton>
+#include <QGroupBox>
+#include <QButtonGroup>
+#include <QScrollBar>
+#include "parameter.h"
+
+#include "macros.h"
+
+extern Parameter settings;
+
+MacroWindow::MacroWindow ( Macros *Macro, QWidget *parent ) : QScrollArea ( parent )
+{
+ QPushButton *pb;
+ Area = new QGroupBox ( this );
+ Area->setAlignment ( Qt::AlignHCenter );
+ DisplayBox = new QButtonGroup ( Area );
+ setWidget ( Area );
+ setHorizontalScrollBarPolicy ( Qt::ScrollBarAlwaysOff );
+ setVerticalScrollBarPolicy ( Qt::ScrollBarAlwaysOn );
+ NumberOfMacros = Macro->count();
+ if ( NumberOfMacros > 0 )
+ for ( int i = 0; i < NumberOfMacros;i++ )
+ {
+
+ pb = new QPushButton ( Macro->getMacroName ( i ), Area );
+ DisplayBox->addButton ( pb, i );
+ }
+ else
+ Area->hide();
+ connect ( DisplayBox, SIGNAL ( buttonClicked ( int ) ), this, SIGNAL ( callMacro ( int ) ) );
+}
+MacroWindow::~MacroWindow()
+{}
+
+
+void MacroWindow::resizeEvent ( QResizeEvent * )
+{
+ if ( NumberOfMacros == 0 )
+ return; // Nothing to do
+
+
+ int width, height, y;
+
+ width = this->width();
+ width = width - verticalScrollBar()->width();
+ y = 5;
+ if ( settings.ApplicationFont != 0 )
+ height = QFontMetrics ( *settings.ApplicationFont ).height();
+ else
+ height = QFontMetrics ( this->font() ).height();
+if(NumberOfMacros > 0)
+ for ( int i = 0; i < NumberOfMacros; i++ )
+ {
+ QPushButton *pb;
+ pb = static_cast<QPushButton *> ( DisplayBox->button ( i ) );
+// if (settings.ApplicationFont != 0)
+// pb->setFont(*settings.ApplicationFont);
+
+ pb->setFixedSize ( width - 20, height );
+ pb->move ( 8, y );
+ y = y + height + 5;
+ }
+ Area->setFixedSize ( width-5, y );
+ Area->show();
+}
+
+void MacroWindow::updateMacroWindow ( Macros *Macro )
+{
+ QPushButton *pb;
+
+ NumberOfMacros = Macro->count();
+ pb = new QPushButton ( Macro->getMacroName ( NumberOfMacros - 1 ), Area );
+ DisplayBox->addButton ( pb, NumberOfMacros - 1 );
+
+ pb->show();
+ resizeEvent ( 0 );
+}
+void MacroWindow::fontChange ( const QFont & )
+{
+ /**
+ if (settings.ApplicationFont != 0)
+ {
+ DisplayBox->setFont(*settings.ApplicationFont);
+ int anzahl = DisplayBox->count();
+ for(int i=0; i < anzahl; i++)
+ {
+ QButton *pb;
+ pb=DisplayBox->find(i);
+ pb->setFont(*settings.ApplicationFont);
+ }
+ }
+ **/
+}
+void MacroWindow::setMacroWindow ( Macros *M )
+{
+ int i, anzahl;
+ QPushButton *pb;
+ anzahl = DisplayBox->buttons().size();
+if ( anzahl > 0)
+ for ( i = 0; i < anzahl; i++ )
+{
+ pb= static_cast<QPushButton *> ( DisplayBox->button ( i ) );
+ DisplayBox->removeButton (pb );
+delete pb;
+}
+ NumberOfMacros = M->count();
+
+ if ( NumberOfMacros > 0 )
+ for ( i = 0; i < NumberOfMacros;i++ )
+ {
+ pb = new QPushButton ( M->getMacroName ( i ), Area );
+ DisplayBox->addButton ( pb, i );
+pb->show();
+ }
+ else
+ Area->hide();
+ resizeEvent ( 0 );
+}
diff --git a/src/macrowindow.h b/src/macrowindow.h
new file mode 100644
index 0000000..1e4ee6b
--- /dev/null
+++ b/src/macrowindow.h
@@ -0,0 +1,53 @@
+/***************************************************************************
+ macros.h - description
+ -------------------
+ begin : Sam Mai 3 2003
+ copyright : (C) 2003 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifndef MACROWINDOW_H
+#define MACROWINDOW_H
+
+#include <QScrollArea>
+
+
+class Macros;
+class QGroupBox;
+class QButtonGroup;
+/**This class implements simple text and file macros.
+The macros are startet by a pushbutton and the pushbuttons are arranged in a scrollview.
+ *@author Volker Schroer
+ */
+
+
+class MacroWindow : public QScrollArea {
+ Q_OBJECT
+public:
+ MacroWindow(Macros *M,QWidget *parent=0);
+ ~MacroWindow();
+void setMacroWindow ( Macros *M);
+private:
+QButtonGroup* DisplayBox;
+QGroupBox* Area;
+int NumberOfMacros;
+protected:
+void fontChange(const QFont &);
+
+public slots:
+virtual void resizeEvent( QResizeEvent * );
+void updateMacroWindow(Macros *);
+
+signals:
+void callMacro(int);
+};
+
+#endif
diff --git a/src/main.cpp b/src/main.cpp
new file mode 100644
index 0000000..b7b9a2a
--- /dev/null
+++ b/src/main.cpp
@@ -0,0 +1,40 @@
+/***************************************************************************
+ main.cpp - description
+ -------------------
+ begin : Sam Nov 23 11:37:46 CET 2002
+ copyright : (C) 2002 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * The PSK part is based on WinPSk 1.0 by Moe Wheatly, AE4JY *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <QApplication>
+#include "linpsk.h"
+#include "parameter.h"
+
+
+
+
+Parameter settings;
+
+int main ( int argc, char *argv[] )
+{
+ QApplication a ( argc, argv );
+
+ LinPSK *w = new LinPSK ( 0 );
+ w->show();
+ a.connect ( &a, SIGNAL ( lastWindowClosed() ), &a, SLOT ( quit() ) );
+ a.exec();
+ return 0;
+}
diff --git a/src/mfskdemodulator.cpp b/src/mfskdemodulator.cpp
new file mode 100644
index 0000000..432f097
--- /dev/null
+++ b/src/mfskdemodulator.cpp
@@ -0,0 +1,249 @@
+/***************************************************************************
+ mfskdemodulator.cpp - description
+ -------------------
+ begin : Mit Jan 29 2003
+ copyright : (C) 2003 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * The PSK part is based on WinPSK 1.0 by Moe Wheatly, AE4JY *
+ ***************************************************************************/
+
+#include "mfskdemodulator.h"
+#include "deinterleaver.h"
+#include "viterbi.h"
+#include "constants.h"
+#include "mfskvaricode.h"
+
+#define NumberofTones 16
+
+const double MFSKDistance ( double *xa, int b )
+{
+ double dist;
+ int a1, a2;
+ a1 = ( b & 2 ) >> 1;
+ a2 = b & 1;
+ dist = abs ( xa[0] - a1 ) + abs ( xa[1] - a2 );
+ return dist;
+
+}
+
+MFSKDemodulator::MFSKDemodulator() : CDemodulator()
+{
+ OszFrequency = 0.;
+ Decoder = new MFSKVaricode();
+ viterbi = new Viterbi ( 7, 0x6D, 0x4F, MFSKDistance );
+ datashreg = 0;
+}
+MFSKDemodulator::~MFSKDemodulator()
+{
+ if ( viterbi != 0 )
+ delete viterbi;
+ if ( Decoder != 0 )
+ delete Decoder;
+}
+
+void MFSKDemodulator::ProcessInput ( double * input, double * )
+{
+// Mix and downsample
+ mixdown ( input ); // Result is now in downBuffer
+ bitEstimate();
+
+}
+
+int MFSKDemodulator::getSquelchValue()
+{
+
+ return 0;
+}
+bool MFSKDemodulator::Init ( double FS, int NumberofSamples )
+{
+ int i;
+ NxSamples = NumberofSamples;
+ SampleRate = FS;
+// OszFreqinc = ( RxFrequency - 1000. ) * PI2 / SampleRate;
+ OszFreqinc = 2.*M_PI * ( RxFrequency - 4*SampleRate / ( DOWNRATE * DELAY ) ) / SampleRate;
+ OszFrequency = 0.;
+ leave = new Deinterleaver ( 10 );
+ processPtr = 0;
+ bitEstimatePtr = 0;
+ syncPtr = 0;
+ oscPos = 6;
+ for ( i = 0;i < DELAY;i++ )
+ delayLine[i] = complex<double> ( 0.0, 0.0 );
+ for ( i = 0; i < RESOLUTION;i++ )
+ twiddles[i] = complex<double> ( cos ( i * M_PI / RESOLUTION ), - sin ( i * M_PI / RESOLUTION ) );
+
+ return true;
+}
+
+
+void MFSKDemodulator::afc ( int freq,double energy )
+{
+ if ( UseAfc == Off )
+ return;
+ if ( (( freq - oscPos ) > 30) && (energy > 10) )
+ {
+ oscPos = freq - 30;
+ RxFrequency +=( oscPos-6 ) *7.8125 ;
+ return;
+ }
+ if ( (freq < oscPos) && (energy > 10) )
+ {
+ oscPos = freq;
+ RxFrequency+= ( oscPos-6 ) *7.8125 ;
+ }
+
+}
+
+void MFSKDemodulator::recvbit ( int bit )
+{
+ int c;
+ char zeichen;
+ datashreg = ( datashreg << 1 );
+ c = !! bit;
+ datashreg = datashreg | c;
+
+ /* search for "001" */
+ c = datashreg & 7;
+ if ( ( datashreg & 7 ) == 1 )
+ {
+ /* the "1" belongs to the next symbol */
+ c = Decoder->decode ( datashreg >> 1 );
+
+ zeichen = c;
+ if ( c != -1 )
+ emit newSymbol ( ( char ) c );
+ /* we already received this */
+ datashreg = 1;
+ }
+}
+double MFSKDemodulator::get2RxFrequency()
+{
+ return RxFrequency + NumberofTones*15.625;
+}
+AfcMode MFSKDemodulator::AfcProperties()
+{
+ return Narrow;
+}
+void MFSKDemodulator::mixdown ( double * inputBuffer )
+{
+ complex<double> accu;
+ int index;
+ index = 0;
+ for ( int i = 0; i <= ( NxSamples - DOWNRATE );i += DOWNRATE )
+ {
+ accu = complex<double> ( 0., 0. );
+ for ( int k = i;k < i + DOWNRATE;k++ )
+ {
+ accu += inputBuffer[k] * exp ( complex<double> ( 0., -OszFrequency ) );;
+ OszFrequency += OszFreqinc;
+ OszFrequency = fmod ( OszFrequency, M_PI + M_PI );
+ }
+ downBuffer[index] = accu;
+ index++;
+ }
+}
+void MFSKDemodulator::sfft ( complex<double> input )
+{
+ complex<double> z;
+ int i, j, index;
+
+ /* calculate the energy */
+ delayLine[processPtr] = input;
+ if ( bitEstimatePtr >= 0 )
+ {
+ for ( i = 0; i < 48; i++ )
+ {
+ z = complex<double> ( 0., 0. );
+ for ( j = DELAY - 1; j >= 0; j-- )
+ {
+ index = ( processPtr + j + 1 + DELAY ) % DELAY;
+ z += delayLine[index] * twiddles[ ( j* ( 2+i ) ) %RESOLUTION];
+ }
+ energy[i][bitEstimatePtr] = abs ( z );
+ }
+ }
+ processPtr = ( processPtr + 1 ) % DELAY;
+}
+void MFSKDemodulator::bitEstimate()
+{
+ double max ;
+ int j, k, freq, pos;
+ double softBits[4];;
+
+// Now we do some sliding fft on the downsampled values
+ for ( int i = 0;i < DOWNSAMPLEDBUFFERLENGTH;i++ )
+ {
+ sfft ( downBuffer[i] );
+ bitEstimatePtr++;
+ if ( bitEstimatePtr == DELAY )
+ {
+ bitEstimatePtr = 0;
+ max = -1;
+ for ( j = 0; j < 48; j++ )
+ {
+ for ( k = 5; k < DELAY;k++ )
+ {
+ if ( energy[j][k] > max )
+ {
+ freq = j;
+ pos = k;
+ max = energy[j][k];
+ }
+ }
+ }
+ afc ( freq,max );
+
+ calcSoftBits ( pos, softBits );
+ leave->deinterleave ( softBits );
+ viterbi->decode ( &softBits[0] );
+ recvbit ( viterbi->getbit ( 48 ) );
+ viterbi->decode ( &softBits[2] );
+ recvbit ( viterbi->getbit ( 48 ) );
+
+ if ( pos > 3*DELAY / 4 )
+ bitEstimatePtr = -DELAY / 8;
+ else if ( pos < DELAY / 4 )
+ {
+ bitEstimatePtr = DELAY / 8;
+ for ( j = 0; j < 48;j++ )
+ for ( k = 0; k < bitEstimatePtr;k++ )
+ energy[j][k] = energy[j][DELAY-bitEstimatePtr+k];
+ }
+ }
+ }
+}
+void MFSKDemodulator::calcSoftBits ( int pos, double *softBits )
+{
+ int i, j;
+ double x, sum;
+ for ( i = 0;i < 4; i++ )
+ softBits[i] = 0.;
+ sum = 0.;
+ for ( i = 0; i < 16;i++ )
+ {
+ j = graydecode ( i );
+ x = energy[2*i+oscPos][pos];
+ sum += x;
+ softBits[0] += ( j & 8 ) ? x : 0.;
+ softBits[1] += ( j & 4 ) ? x : 0.;
+ softBits[2] += ( j & 2 ) ? x : 0.;
+ softBits[3] += ( j & 1 ) ? x : 0.;
+ }
+ if ( sum > 0 )
+ for ( i = 0; i < 4; i++ )
+ softBits[i] /= sum;
+}
+void MFSKDemodulator::setRxFrequency ( double freq )
+{
+ RxFrequency = freq;
+ OszFreqinc = 2.*M_PI * ( RxFrequency - 4*SampleRate / ( DOWNRATE * DELAY ) ) / SampleRate;
+ oscPos = 6;
+}
diff --git a/src/mfskdemodulator.h b/src/mfskdemodulator.h
new file mode 100644
index 0000000..a791c2f
--- /dev/null
+++ b/src/mfskdemodulator.h
@@ -0,0 +1,84 @@
+/***************************************************************************
+ mfskdemodulator.h - description
+ -------------------
+ begin : Mit Jan 29 2003
+ copyright : (C) 2003 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * The PSK part is based on WinPSK 1.0 by Moe Wheatley, AE4JY *
+ ***************************************************************************/
+
+#ifndef MFSKDEMODULATOR_H
+#define MFSKDEMODULATOR_H
+
+#include "cdemodulator.h"
+#include <complex>
+#include <vector>
+
+using namespace std;
+class Deinterleaver;
+class Viterbi;
+class MFSKVaricode;
+/**
+ *@author Volker Schroer
+ */
+
+#define DOWNSAMPLEDBUFFERLENGTH 256 // 4096 /16
+#define DOWNRATE 16
+#define DELAY 44 // = Samplerate / DOWNRATE /BAUDRATE = 11025/16/15.625
+#define RESOLUTION 88 // 88 = 2* DELAY
+
+//class MFSKDemodulator : public FSKDemodulator {
+class MFSKDemodulator : public CDemodulator {
+public:
+ MFSKDemodulator();
+ ~MFSKDemodulator();
+ /** Prozess the input */
+ void ProcessInput(double * input,double *);
+ int getSquelchValue();
+ bool Init(double,int);
+ virtual double get2RxFrequency();
+private:
+AfcMode AfcProperties();
+void mixdown(double *);
+void calcSoftBits(int pos, double *softBits);
+
+ unsigned int datashreg;
+
+MFSKVaricode *Decoder;
+
+Deinterleaver * leave;
+complex<double> *history;
+Viterbi * viterbi;
+void sfft(complex<double>);
+void bitEstimate();
+void afc(int,double);
+void recvbit(int);
+int processPtr,bitEstimatePtr,syncPtr,oscPos;
+/******************************/
+/** coeficients for slidding fft */
+complex<double> twiddles[RESOLUTION];;
+complex<double> downBuffer[DOWNSAMPLEDBUFFERLENGTH];
+complex<double> delayLine[DELAY];
+double energy[48][DELAY];
+
+inline unsigned char graydecode(unsigned char data)
+{
+ return data ^ (data >> 1);
+}
+inline unsigned char clamp(double x)
+{
+ return (x < 0) ? 0 : ((x > 255) ? 255 :(unsigned char) x);
+}
+public slots:
+void setRxFrequency(double);
+};
+
+#endif
diff --git a/src/mfskmodulator.cpp b/src/mfskmodulator.cpp
new file mode 100644
index 0000000..7dfd493
--- /dev/null
+++ b/src/mfskmodulator.cpp
@@ -0,0 +1,117 @@
+/***************************************************************************
+ mfskmodulator.cpp - description
+ -------------------
+ begin : Fre Feb 28 2003
+ copyright : (C) 2003 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#include "mfskmodulator.h"
+#include "mfskvaricode.h"
+#include "ctxbuffer.h"
+#include "interleaver.h"
+#include "feccoder.h"
+
+MFSKModulator::MFSKModulator ( int FS, double freq, CTxBuffer *TxBuffer ) : FSKModulator ( FS, TxBuffer )
+{
+ Encoder = new MFSKVaricode();
+ leave = new Interleaver ( 10 );
+ Fec = new FECCoder();
+ Allbitsgone = true;
+ bitcounter = 0;
+ varicode = 0;
+ NumberofTones = 16;
+ postamblePtr = 0;
+ preamblePtr = 5;
+// ToneFrequencyr = new double[NumberofTones];
+// ToneFrequencyi = new double[NumberofTones];
+ Baudrate = 15.625;
+ SamplesperSymbol = ( int ) ( SampleRate / Baudrate + 0.5 );
+// Tonespacing has the same value like Baudrate so
+ for ( int i = 0; i < NumberofTones;i++ )
+ {
+ ToneFrequencyr[i] = cos ( PI2 * ( freq + i * Baudrate ) / SampleRate );
+ ToneFrequencyi[i] = sin ( PI2 * ( freq + i * Baudrate ) / SampleRate );
+ }
+ NxSamples = SamplesperSymbol;
+}
+MFSKModulator::~MFSKModulator()
+{
+ if ( Encoder != 0 )
+ delete Encoder;
+ if ( leave != 0 )
+ delete leave;
+ if ( Fec != 0 )
+ delete Fec;
+}
+int MFSKModulator::getToneNumber()
+{
+ int ch;
+ if ( postamblePtr == 1 )
+ return TXOFF_CODE;
+ for ( ;; )
+ {
+ if ( Allbitsgone )
+ {
+ if ( postamblePtr > 1 )
+ {
+ postamblePtr--;
+ ch = 0;
+ }
+ else if ( preamblePtr > 0 )
+ {
+ preamblePtr--;
+ ch = 0;
+ }
+ else
+ {
+ ch = Buffer->getTxChar();
+ if ( ch < 0 )
+ {
+ if ( ch == TXOFF_CODE )
+// {
+ postamblePtr = 10;
+// ch=0;
+// }
+// else
+ ch = 0; // <Nul>
+ }
+ else
+ emit charSend ( ( char ) ch );
+ }
+ varicode = Encoder->encode ( ch );
+ Allbitsgone = false ;
+ bitposition = 0x0800;
+ // find first bit from left
+ while ( ! ( varicode & bitposition ) )
+ bitposition = bitposition >> 1;
+
+ }
+ while ( bitposition && ( bitcounter < 4 ) )
+ {
+ if ( varicode & bitposition )
+ Fec->FECEncode ( 1 , &bit[bitcounter] );
+ else
+ Fec->FECEncode ( 0, &bit[bitcounter] );
+ bitcounter += 2;
+ bitposition = bitposition >> 1;
+ }
+ if ( bitposition == 0 )
+ Allbitsgone = true;
+ if ( bitcounter == 4 )
+ {
+ bitcounter = 0;
+ return grayencode ( leave->interleave ( bit ) );
+ }
+ }
+}
+
+
diff --git a/src/mfskmodulator.h b/src/mfskmodulator.h
new file mode 100644
index 0000000..b6b16b3
--- /dev/null
+++ b/src/mfskmodulator.h
@@ -0,0 +1,67 @@
+/***************************************************************************
+ mfskmodulator.h - description
+ -------------------
+ begin : Fre Feb 28 2003
+ copyright : (C) 2003 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * The PSK part is based on WinPSK 1.0 by Moe Wheatley, AE4JY *
+ ***************************************************************************/
+
+#ifndef MFSKMODULATOR_H
+#define MFSKMODULATOR_H
+
+#include <fskmodulator.h>
+
+
+class MFSKVaricode;
+class CTxBuffer;
+class Interleaver;
+class FECCoder;
+/**
+ *@author Volker Schroer
+ */
+class CTxBuffer;
+class MFSKModulator : public FSKModulator
+ {
+public:
+ MFSKModulator(int,double,CTxBuffer *);
+ ~MFSKModulator();
+int getToneNumber();
+
+
+private:
+MFSKVaricode * Encoder;
+Interleaver * leave;
+FECCoder *Fec;
+bool Allbitsgone;
+unsigned int bitcounter;
+unsigned int bitposition;
+unsigned char bit[4];
+unsigned int varicode;
+int postamblePtr;
+int preamblePtr;
+inline unsigned char grayencode(unsigned char data)
+{
+ unsigned char bits = data;
+
+ bits ^= data >> 1;
+ bits ^= data >> 2;
+ bits ^= data >> 3;
+ bits ^= data >> 4;
+ bits ^= data >> 5;
+ bits ^= data >> 6;
+ bits ^= data >> 7;
+
+ return bits;
+}
+};
+
+#endif
diff --git a/src/mfskvaricode.cpp b/src/mfskvaricode.cpp
new file mode 100644
index 0000000..9c48218
--- /dev/null
+++ b/src/mfskvaricode.cpp
@@ -0,0 +1,71 @@
+/***************************************************************************
+ mfskvaricode.cpp - description
+ -------------------
+ begin : Sam M�r 1 2003
+ copyright : (C) 2003 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * The PSK part is based on WinPSK 1.0 by Moe Wheatly, AE4JY *
+ ***************************************************************************/
+
+#include "mfskvaricode.h"
+const unsigned int MFSKVaricode::varicode[256] = {
+ 0x75C, 0x760, 0x768, 0x76C, 0x770, 0x774, 0x778, 0x77C,
+ 0x0A8, 0x780, 0x7A0, 0x7A8, 0x7AC, 0x0AC, 0x7B0, 0x7B4,
+ 0x7B8, 0x7BC, 0x7C0, 0x7D0, 0x7D4, 0x7D8, 0x7DC, 0x7E0,
+ 0x7E8, 0x7EC, 0x7F0, 0x7F4, 0x7F8, 0x7FC, 0x800, 0xA00,
+ 0x004, 0x1C0, 0x1FC, 0x2D8, 0x2A8, 0x2A0, 0x200, 0x1BC,
+ 0x1F4, 0x1F0, 0x2B4, 0x1E0, 0x0A0, 0x1D8, 0x1D4, 0x1E8,
+ 0x0E0, 0x0F0, 0x140, 0x154, 0x174, 0x160, 0x16C, 0x1A0,
+ 0x180, 0x1AC, 0x1EC, 0x1F8, 0x2C0, 0x1DC, 0x2BC, 0x1D0,
+ 0x280, 0x0BC, 0x100, 0x0D4, 0x0DC, 0x0B8, 0x0F8, 0x150,
+ 0x158, 0x0C0, 0x1B4, 0x17C, 0x0F4, 0x0E8, 0x0FC, 0x0D0,
+ 0x0EC, 0x1B0, 0x0D8, 0x0B4, 0x0B0, 0x15C, 0x1A8, 0x168,
+ 0x170, 0x178, 0x1B8, 0x2E8, 0x2D0, 0x2EC, 0x2D4, 0x2B0,
+ 0x2AC, 0x014, 0x060, 0x038, 0x034, 0x008, 0x050, 0x058,
+ 0x030, 0x018, 0x080, 0x070, 0x02C, 0x040, 0x01C, 0x010,
+ 0x054, 0x078, 0x020, 0x028, 0x00C, 0x03C, 0x06C, 0x068,
+ 0x074, 0x05C, 0x07C, 0x2DC, 0x2B8, 0x2E0, 0x2F0, 0xA80,
+ 0xAA0, 0xAA8, 0xAAC, 0xAB0, 0xAB4, 0xAB8, 0xABC, 0xAC0,
+ 0xAD0, 0xAD4, 0xAD8, 0xADC, 0xAE0, 0xAE8, 0xAEC, 0xAF0,
+ 0xAF4, 0xAF8, 0xAFC, 0xB00, 0xB40, 0xB50, 0xB54, 0xB58,
+ 0xB5C, 0xB60, 0xB68, 0xB6C, 0xB70, 0xB74, 0xB78, 0xB7C,
+ 0x2F4, 0x2F8, 0x2FC, 0x300, 0x340, 0x350, 0x354, 0x358,
+ 0x35C, 0x360, 0x368, 0x36C, 0x370, 0x374, 0x378, 0x37C,
+ 0x380, 0x3A0, 0x3A8, 0x3AC, 0x3B0, 0x3B4, 0x3B8, 0x3BC,
+ 0x3C0, 0x3D0, 0x3D4, 0x3D8, 0x3DC, 0x3E0, 0x3E8, 0x3EC,
+ 0x3F0, 0x3F4, 0x3F8, 0x3FC, 0x400, 0x500, 0x540, 0x550,
+ 0x554, 0x558, 0x55C, 0x560, 0x568, 0x56C, 0x570, 0x574,
+ 0x578, 0x57C, 0x580, 0x5A0, 0x5A8, 0x5AC, 0x5B0, 0x5B4,
+ 0x5B8, 0x5BC, 0x5C0, 0x5D0, 0x5D4, 0x5D8, 0x5DC, 0x5E0,
+ 0x5E8, 0x5EC, 0x5F0, 0x5F4, 0x5F8, 0x5FC, 0x600, 0x680,
+ 0x6A0, 0x6A8, 0x6AC, 0x6B0, 0x6B4, 0x6B8, 0x6BC, 0x6C0,
+ 0x6D0, 0x6D4, 0x6D8, 0x6DC, 0x6E0, 0x6E8, 0x6EC, 0x6F0,
+ 0x6F4, 0x6F8, 0x6FC, 0x700, 0x740, 0x750, 0x754, 0x758
+};
+
+MFSKVaricode::MFSKVaricode()
+{
+}
+MFSKVaricode::~MFSKVaricode()
+{
+}
+int MFSKVaricode::decode(unsigned int symbol)
+{
+ for (int i = 0; i < 256; i++)
+ if (symbol == varicode[i])
+ return i;
+ return -1;
+}
+unsigned int MFSKVaricode::encode(unsigned char c)
+{
+return varicode[c];
+}
+
diff --git a/src/mfskvaricode.h b/src/mfskvaricode.h
new file mode 100644
index 0000000..03f481c
--- /dev/null
+++ b/src/mfskvaricode.h
@@ -0,0 +1,36 @@
+/***************************************************************************
+ mfskvaricode.h - description
+ -------------------
+ begin : Sam M�r 1 2003
+ copyright : (C) 2003 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * The PSK part is based on WinPSK 1.0 by Moe Wheatley, AE4JY *
+ ***************************************************************************/
+
+#ifndef MFSKVARICODE_H
+#define MFSKVARICODE_H
+
+
+/**
+ *@author Volker Schroer
+ */
+
+class MFSKVaricode {
+public:
+ MFSKVaricode();
+ ~MFSKVaricode();
+int decode(unsigned int symbol);
+unsigned int encode(unsigned char c);
+private:
+static const unsigned int varicode[256];
+};
+
+#endif
diff --git a/src/parameter.cpp b/src/parameter.cpp
new file mode 100644
index 0000000..b33e92b
--- /dev/null
+++ b/src/parameter.cpp
@@ -0,0 +1,55 @@
+/***************************************************************************
+ parameter.cpp - description
+ -------------------
+ begin : Sat Apr 1 2000
+ copyright : (C) 2000 by Volker Schroer
+ email : DL1KSV at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * based on the work of Moe Wheatly, AE4JY *
+ ***************************************************************************/
+
+#include "parameter.h"
+
+Parameter::Parameter()
+{
+
+Status = UNDEF;
+
+// Defaultsettings
+
+MinimumWindowWidth=640;
+MinimumWindowHeight=555;
+
+
+callsign="";
+QslData=0;
+
+serial=-1; // Serial none
+SerialDevice="none";
+QSOFileName="QSOData.adif";
+
+timeoffset=-2;
+
+DemoMode=true;
+DemoModeFileType[0]="*.wav";
+DemoModeFileType[1]="*.out";
+DemoTypeNumber=0;
+slashed0=false;
+RxChannels=1;
+ActChannel = 0; // Pointer to the active Channel
+ChannelChain = 0; // Pointer to the Start of the Rx - ChannelChain
+ApplicationFont =0;
+autoCrLf=true;
+
+}
+Parameter::~Parameter()
+{
+}
+
diff --git a/src/parameter.h b/src/parameter.h
new file mode 100644
index 0000000..e7d7239
--- /dev/null
+++ b/src/parameter.h
@@ -0,0 +1,89 @@
+/***************************************************************************
+ parameter.h - description
+ -------------------
+ begin : Sat Apr 1 2000
+ copyright : (C) 2000 by Volker Schroer
+ email : DL1KSV at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifndef PARAMETER_H
+#define PARAMETER_H
+
+#include <qapplication.h>
+#include <qfont.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+
+#include <cledbutton.h>
+#include "constants.h"
+
+class CRxChannel;
+class QString;
+class QFont;
+
+/**Contains parameters for transmitting and receiving
+
+some of them are set by settup
+ *@author Volker Schroer
+ */
+
+class Parameter
+{
+
+public:
+ Parameter();
+ ~Parameter();
+void setupDevices();
+// Variables
+
+/** MinimumWindowWidth */
+int MinimumWindowWidth;
+/** MinimumWindowHeight */
+int MinimumWindowHeight;
+
+
+QString callsign; // Callsign
+QString myLocator;
+QString inputFilename; //Name of Demofile
+QString DemoModeFileType[2]; // File Type of DemoFile
+int DemoTypeNumber; // Index of selected FileType
+int serial; // Filedescriptor for serial Device for PTT
+QString SerialDevice; //Filename for PTT Device
+//Logging
+QString QSOFileName; // Name of the file,where qsodata will be stored
+QString Directory;
+bool fileLog;
+bool LinLog;
+QString Host;
+int Port;
+bool DemoMode; // DemoMode ?
+
+
+int timeoffset; // offset to UTC
+
+/** DeviceSection */
+
+
+bool slashed0; // True if to print 0 slashed
+bool autoCrLf; // True if sending cr lf on enter
+
+unsigned int RxChannels;
+CRxChannel * ChannelChain;
+CRxChannel * ActChannel;
+QsoInfo *QslData;
+BUTTONSTATUS Status;
+QFont *ApplicationFont;
+QString dateFormat;
+
+};
+
+#endif
diff --git a/src/processlogdata.cpp b/src/processlogdata.cpp
new file mode 100644
index 0000000..78a2b1c
--- /dev/null
+++ b/src/processlogdata.cpp
@@ -0,0 +1,150 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Volker Schroer *
+ * dl1ksv at gmx.de *
+ * *
+ * 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 "processlogdata.h"
+#include <QString>
+#include <QLabel>
+#include <QHostAddress>
+#include <QEventLoop>
+#include <QMessageBox>
+#include <QMetaType>
+
+ProcessLogData::ProcessLogData ( QObject *parent )
+ : QThread ( parent )
+{
+ tcpSocket = 0;
+ connectionEstablished = false;
+ connectionError = false;
+}
+
+
+ProcessLogData::~ProcessLogData()
+{
+}
+void ProcessLogData::saveQsoData ( QString s )
+{
+ qDebug ( "Request save" );
+ requestType = Save;
+ actionString = s;
+ doAction();
+}
+void ProcessLogData::requestCallSign ( QLabel **r, QString s )
+{
+ qDebug ( "Request Callsign" );
+ requestType = Request;
+ actionString.clear();
+ actionString.append ( "@@@@" );
+ actionString.append ( s );
+ actionString.append ( "\r\n" );
+
+ for ( int i = 0; i < 6;i++ )
+ results[i] = r[i];
+ doAction();
+}
+void ProcessLogData::run()
+{
+ connectionEstablished = false;
+ connectionError = false;
+ qRegisterMetaType<QAbstractSocket::SocketError> ( "QAbstractSocket::SocketError" );
+ tcpSocket = new QTcpSocket();
+ connect ( tcpSocket, SIGNAL ( disconnected() ), this, SLOT ( connectionClosedbyHost() ) );
+ connect ( tcpSocket, SIGNAL ( readyRead() ), this, SLOT ( readAnswer() ) );
+ connect ( tcpSocket, SIGNAL ( connected() ), this, SLOT ( setConnected() ) );
+ connect ( tcpSocket, SIGNAL ( error ( QAbstractSocket::SocketError ) ), this, SLOT ( setError ( QAbstractSocket::SocketError ) ) );
+ tcpSocket->connectToHost ( QHostAddress::LocalHost, 8080, QIODevice::ReadWrite );
+ exec();
+}
+void ProcessLogData::doAction()
+{
+ if ( !connectionEstablished )
+ usleep ( 6000 );
+ if ( !connectionEstablished && tcpSocket->state() != 3)
+ {
+ qDebug ( "Waiting for Socket timed out: %d",tcpSocket->state() );
+ QMessageBox::StandardButton reply;
+ reply = QMessageBox::question ( 0, "LinPSK", tr ( "Cannot connect to LinLogBook\nTry again later ?" ), QMessageBox::Yes | QMessageBox::No );
+ if ( reply == QMessageBox::No )
+ emit unabletoConnect();
+ if ( tcpSocket != 0 )
+ delete tcpSocket;
+ tcpSocket = 0;
+
+ exit();
+ return;
+ }
+// if ( tcpSocket->state() != QAbstractSocket::ConnectedState )
+// usleep ( 500 );
+
+ qDebug ( "SocketError %d", tcpSocket->state() );
+ if ( tcpSocket->state() == QAbstractSocket::UnconnectedState )
+ {
+ QMessageBox::information ( 0, "LinPSK", tr ( "Cannot connect to LinLogBook" ) );
+ return;
+ }
+ int n = tcpSocket->write ( actionString.toLatin1(), actionString.length() );
+ qDebug ( "Written %d, to be written %d", n, actionString.length() );
+ if ( n < 0 ) // Retry
+ {
+ usleep ( 100 );
+ n = tcpSocket->write ( actionString.toLatin1(), actionString.length() );
+ qDebug ( "Written %d, to be written %d", n, actionString.length() );
+ }
+ tcpSocket->flush();
+}
+void ProcessLogData::connectionClosedbyHost()
+{
+ connectionEstablished = false;
+ if ( tcpSocket != 0 )
+ delete tcpSocket;
+ tcpSocket = 0;
+ quit();
+
+}
+
+void ProcessLogData::readAnswer()
+{
+ qDebug ( "Read Answer" );
+//Has to be improved, to get safer
+ QString s;
+ int i;
+ for ( i = 0; i < 6; i++ )
+ {
+ while ( ! tcpSocket->canReadLine() )
+ usleep ( 100 );
+ s = QLatin1String ( tcpSocket->readLine() );
+ s.remove ( QLatin1Char ( '\n' ) );
+ results[i]->setText ( s );
+ results[i]->show();
+ }
+ qDebug ( "%d Zeilen gelesen", i );
+emit answerAvailable();
+}
+void ProcessLogData::setConnected()
+{
+ connectionEstablished = true;
+}
+void ProcessLogData::setError ( QAbstractSocket::SocketError )
+{
+ connectionEstablished = false;
+ connectionError = true;
+ if ( tcpSocket != 0 )
+ qDebug ( "SocketError %d", tcpSocket->state() );
+}
+
+
diff --git a/src/processlogdata.h b/src/processlogdata.h
new file mode 100644
index 0000000..d430a11
--- /dev/null
+++ b/src/processlogdata.h
@@ -0,0 +1,62 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Volker Schroer *
+ * dl1ksv at gmx.de *
+ * *
+ * 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 PROCESSLOGDATA_H
+#define PROCESSLOGDATA_H
+
+#include <QThread>
+#include <QTcpSocket>
+class QString;
+
+class QLabel;
+/**
+Sends logdata to the linlogbook server and requests infos for a callsign from the linlogbook server
+
+ @author Volker Schroer <dl1ksv at gmx.de>
+*/
+class ProcessLogData : public QThread
+{
+ Q_OBJECT
+ public:
+ ProcessLogData ( QObject *parent = 0 );
+
+ ~ProcessLogData();
+ void saveQsoData ( QString s );
+ void requestCallSign ( QLabel **, QString s );
+ void run();
+ private:
+ enum RequestType {Save = 0, Request};
+ RequestType requestType;
+ QString actionString;
+ QTcpSocket *tcpSocket;
+ QLabel * results[6];
+ bool connectionEstablished;
+ bool connectionError;
+ private slots:
+ void doAction();
+ void connectionClosedbyHost();
+ void readAnswer();
+ void setConnected();
+ void setError ( QAbstractSocket::SocketError );
+signals:
+void unabletoConnect();
+void answerAvailable();
+};
+
+#endif
diff --git a/src/pskmodulator.cpp b/src/pskmodulator.cpp
new file mode 100644
index 0000000..d5714fa
--- /dev/null
+++ b/src/pskmodulator.cpp
@@ -0,0 +1,632 @@
+//////////////////////////////////////////////////////////////////////
+// PSKMod.cpp: implementation of the PSKModulator class.
+//
+//////////////////////////////////////////////////////////////////////
+// PSK31/CW modulator
+// Copyright 1999. Moe Wheatley AE4JY <ae4jy at mindspring.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 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.
+//
+//////////////////////////////////////////////////////////////////////
+//
+// modified by Volker Schroer , DL1KSV for use in LinPsk
+
+#include <math.h>
+#include "psktable.h"
+#include "pskmodulator.h"
+#include "ctxbuffer.h"
+
+
+// local defines.................
+
+#define PHZ_0 0 //specify various signal phase states
+#define PHZ_90 1
+#define PHZ_180 2
+#define PHZ_270 3
+#define PHZ_OFF 4
+
+#define SYM_NOCHANGE 0 //Stay the same phase
+#define SYM_P90 1 //Plus 90 deg
+#define SYM_P180 2 //Plus 180 deg
+#define SYM_M90 3 //Minus 90 deg
+#define SYM_OFF 4 //No output
+#define SYM_ON 5 //constant output
+
+
+#define SYMBOL_RATE 31.25 // 31.25 Symbols per Second
+
+#define MAXRAMP_SIZE (((100*11100)/3125)+1) // max number of envelope ramp steps per symbol
+/** Not needed any longer
+#define TX_CONSTANT 23000.0 // TX Amplitude Factor
+ **/
+#define CW_SPEED 1 //bigger is slower. 1 is fastest.
+
+// The use of static's here preclude having multiple instantiations
+// of this class but should not be an issue since only one soundcard.
+
+
+//Ramp shape tables that are loaded with cosine shaped functions at init
+static double PSKShapeTbl_Z[MAXRAMP_SIZE]; // 0
+static double PSKShapeTbl_P[MAXRAMP_SIZE]; // +1
+static double PSKShapeTbl_M[MAXRAMP_SIZE]; // -1
+static double PSKShapeTbl_ZP[MAXRAMP_SIZE]; // 0 to +1
+static double PSKShapeTbl_PZ[MAXRAMP_SIZE]; // +1 to 0
+static double PSKShapeTbl_MZ[MAXRAMP_SIZE]; // -1 to 0
+static double PSKShapeTbl_PM[MAXRAMP_SIZE]; // +1 to -1
+static double PSKShapeTbl_MP[MAXRAMP_SIZE]; // -1 to +1
+// each character is separated by two zeros. The bits are sent msbit first.
+const unsigned short int PSKModulator::VARICODE_TABLE[] = {
+ 0xAAC0, // ASCII = 0 1010101011
+ 0xB6C0, // ASCII = 1 1011011011
+ 0xBB40, // ASCII = 2 1011101101
+ 0xDDC0, // ASCII = 3 1101110111
+ 0xBAC0, // ASCII = 4 1011101011
+ 0xD7C0, // ASCII = 5 1101011111
+ 0xBBC0, // ASCII = 6 1011101111
+ 0xBF40, // ASCII = 7 1011111101
+ 0xBFC0, // ASCII = 8 1011111111
+ 0xEF00, // ASCII = 9 11101111
+ 0xE800, // ASCII = 10 11101
+ 0xDBC0, // ASCII = 11 1101101111
+ 0xB740, // ASCII = 12 1011011101
+ 0xF800, // ASCII = 13 11111
+ 0xDD40, // ASCII = 14 1101110101
+ 0xEAC0, // ASCII = 15 1110101011
+ 0xBDC0, // ASCII = 16 1011110111
+ 0xBD40, // ASCII = 17 1011110101
+ 0xEB40, // ASCII = 18 1110101101
+ 0xEBC0, // ASCII = 19 1110101111
+ 0xD6C0, // ASCII = 20 1101011011
+ 0xDAC0, // ASCII = 21 1101101011
+ 0xDB40, // ASCII = 22 1101101101
+ 0xD5C0, // ASCII = 23 1101010111
+ 0xDEC0, // ASCII = 24 1101111011
+ 0xDF40, // ASCII = 25 1101111101
+ 0xEDC0, // ASCII = 26 1110110111
+ 0xD540, // ASCII = 27 1101010101
+ 0xD740, // ASCII = 28 1101011101
+ 0xEEC0, // ASCII = 29 1110111011
+ 0xBEC0, // ASCII = 30 1011111011
+ 0xDFC0, // ASCII = 31 1101111111
+ 0x8000, // ASCII = ' ' 1
+ 0xFF80, // ASCII = '!' 111111111
+ 0xAF80, // ASCII = '"' 101011111
+ 0xFA80, // ASCII = '#' 111110101
+ 0xED80, // ASCII = '$' 111011011
+ 0xB540, // ASCII = '%' 1011010101
+ 0xAEC0, // ASCII = '&' 1010111011
+ 0xBF80, // ASCII = ''' 101111111
+ 0xFB00, // ASCII = '(' 11111011
+ 0xF700, // ASCII = ')' 11110111
+ 0xB780, // ASCII = '*' 101101111
+ 0xEF80, // ASCII = '+' 111011111
+ 0xEA00, // ASCII = ',' 1110101
+ 0xD400, // ASCII = '-' 110101
+ 0xAE00, // ASCII = '.' 1010111
+ 0xD780, // ASCII = '/' 110101111
+ 0xB700, // ASCII = '0' 10110111
+ 0xBD00, // ASCII = '1' 10111101
+ 0xED00, // ASCII = '2' 11101101
+ 0xFF00, // ASCII = '3' 11111111
+ 0xBB80, // ASCII = '4' 101110111
+ 0xAD80, // ASCII = '5' 101011011
+ 0xB580, // ASCII = '6' 101101011
+ 0xD680, // ASCII = '7' 110101101
+ 0xD580, // ASCII = '8' 110101011
+ 0xDB80, // ASCII = '9' 110110111
+ 0xF500, // ASCII = ':' 11110101
+ 0xDE80, // ASCII = ';' 110111101
+ 0xF680, // ASCII = '<' 111101101
+ 0xAA00, // ASCII = '=' 1010101
+ 0xEB80, // ASCII = '>' 111010111
+ 0xABC0, // ASCII = '?' 1010101111
+ 0xAF40, // ASCII = '@' 1010111101
+ 0xFA00, // ASCII = 'A' 1111101
+ 0xEB00, // ASCII = 'B' 11101011
+ 0xAD00, // ASCII = 'C' 10101101
+ 0xB500, // ASCII = 'D' 10110101
+ 0xEE00, // ASCII = 'E' 1110111
+ 0xDB00, // ASCII = 'F' 11011011
+ 0xFD00, // ASCII = 'G' 11111101
+ 0xAA80, // ASCII = 'H' 101010101
+ 0xFE00, // ASCII = 'I' 1111111
+ 0xFE80, // ASCII = 'J' 111111101
+ 0xBE80, // ASCII = 'K' 101111101
+ 0xD700, // ASCII = 'L' 11010111
+ 0xBB00, // ASCII = 'M' 10111011
+ 0xDD00, // ASCII = 'N' 11011101
+ 0xAB00, // ASCII = 'O' 10101011
+ 0xD500, // ASCII = 'P' 11010101
+ 0xEE80, // ASCII = 'Q' 111011101
+ 0xAF00, // ASCII = 'R' 10101111
+ 0xDE00, // ASCII = 'S' 1101111
+ 0xDA00, // ASCII = 'T' 1101101
+ 0xAB80, // ASCII = 'U' 101010111
+ 0xDA80, // ASCII = 'V' 110110101
+ 0xAE80, // ASCII = 'W' 101011101
+ 0xBA80, // ASCII = 'X' 101110101
+ 0xBD80, // ASCII = 'Y' 101111011
+ 0xAB40, // ASCII = 'Z' 1010101101
+ 0xFB80, // ASCII = '[' 111110111
+ 0xF780, // ASCII = '\' 111101111
+ 0xFD80, // ASCII = ']' 111111011
+ 0xAFC0, // ASCII = '^' 1010111111
+ 0xB680, // ASCII = '_' 101101101
+ 0xB7C0, // ASCII = '`' 1011011111
+ 0xB000, // ASCII = 'a' 1011
+ 0xBE00, // ASCII = 'b' 1011111
+ 0xBC00, // ASCII = 'c' 101111
+ 0xB400, // ASCII = 'd' 101101
+ 0xC000, // ASCII = 'e' 11
+ 0xF400, // ASCII = 'f' 111101
+ 0xB600, // ASCII = 'g' 1011011
+ 0xAC00, // ASCII = 'h' 101011
+ 0xD000, // ASCII = 'i' 1101
+ 0xF580, // ASCII = 'j' 111101011
+ 0xBF00, // ASCII = 'k' 10111111
+ 0xD800, // ASCII = 'l' 11011
+ 0xEC00, // ASCII = 'm' 111011
+ 0xF000, // ASCII = 'n' 1111
+ 0xE000, // ASCII = 'o' 111
+ 0xFC00, // ASCII = 'p' 111111
+ 0xDF80, // ASCII = 'q' 110111111
+ 0xA800, // ASCII = 'r' 10101
+ 0xB800, // ASCII = 's' 10111
+ 0xA000, // ASCII = 't' 101
+ 0xDC00, // ASCII = 'u' 110111
+ 0xF600, // ASCII = 'v' 1111011
+ 0xD600, // ASCII = 'w' 1101011
+ 0xDF00, // ASCII = 'x' 11011111
+ 0xBA00, // ASCII = 'y' 1011101
+ 0xEA80, // ASCII = 'z' 111010101
+ 0xADC0, // ASCII = '{' 1010110111
+ 0xDD80, // ASCII = '|' 110111011
+ 0xAD40, // ASCII = '}' 1010110101
+ 0xB5C0, // ASCII = '~' 1011010111
+ 0xED40, // ASCII = 127 1110110101
+ 0xEF40, // ASCII = 128 1110111101
+ 0xEFC0, // ASCII = 129 1110111111
+ 0xF540, // ASCII = 130 1111010101
+ 0xF5C0, // ASCII = 131 1111010111
+ 0xF6C0, // ASCII = 132 1111011011
+ 0xF740, // ASCII = 133 1111011101
+ 0xF7C0, // ASCII = 134 1111011111
+ 0xFAC0, // ASCII = 135 1111101011
+ 0xFB40, // ASCII = 136 1111101101
+ 0xFBC0, // ASCII = 137 1111101111
+ 0xFD40, // ASCII = 138 1111110101
+ 0xFDC0, // ASCII = 139 1111110111
+ 0xFEC0, // ASCII = 140 1111111011
+ 0xFF40, // ASCII = 141 1111111101
+ 0xFFC0, // ASCII = 142 1111111111
+ 0xAAA0, // ASCII = 143 10101010101
+ 0xAAE0, // ASCII = 144 10101010111
+ 0xAB60, // ASCII = 145 10101011011
+ 0xABA0, // ASCII = 146 10101011101
+ 0xABE0, // ASCII = 147 10101011111
+ 0xAD60, // ASCII = 148 10101101011
+ 0xADA0, // ASCII = 149 10101101101
+ 0xADE0, // ASCII = 150 10101101111
+ 0xAEA0, // ASCII = 151 10101110101
+ 0xAEE0, // ASCII = 152 10101110111
+ 0xAF60, // ASCII = 153 10101111011
+ 0xAFA0, // ASCII = 154 10101111101
+ 0xAFE0, // ASCII = 155 10101111111
+ 0xB560, // ASCII = 156 10110101011
+ 0xB5A0, // ASCII = 157 10110101101
+ 0xB5E0, // ASCII = 158 10110101111
+ 0xB6A0, // ASCII = 159 10110110101
+ 0xB6E0, // ASCII = 160 10110110111
+ 0xB760, // ASCII = 161 10110111011
+ 0xB7A0, // ASCII = 162 10110111101
+ 0xB7E0, // ASCII = 163 10110111111
+ 0xBAA0, // ASCII = 164 10111010101
+ 0xBAE0, // ASCII = 165 10111010111
+ 0xBB60, // ASCII = 166 10111011011
+ 0xBBA0, // ASCII = 167 10111011101
+ 0xBBE0, // ASCII = 168 10111011111
+ 0xBD60, // ASCII = 169 10111101011
+ 0xBDA0, // ASCII = 170 10111101101
+ 0xBDE0, // ASCII = 171 10111101111
+ 0xBEA0, // ASCII = 172 10111110101
+ 0xBEE0, // ASCII = 173 10111110111
+ 0xBF60, // ASCII = 174 10111111011
+ 0xBFA0, // ASCII = 175 10111111101
+ 0xBFE0, // ASCII = 176 10111111111
+ 0xD560, // ASCII = 177 11010101011
+ 0xD5A0, // ASCII = 178 11010101101
+ 0xD5E0, // ASCII = 179 11010101111
+ 0xD6A0, // ASCII = 180 11010110101
+ 0xD6E0, // ASCII = 181 11010110111
+ 0xD760, // ASCII = 182 11010111011
+ 0xD7A0, // ASCII = 183 11010111101
+ 0xD7E0, // ASCII = 184 11010111111
+ 0xDAA0, // ASCII = 185 11011010101
+ 0xDAE0, // ASCII = 186 11011010111
+ 0xDB60, // ASCII = 187 11011011011
+ 0xDBA0, // ASCII = 188 11011011101
+ 0xDBE0, // ASCII = 189 11011011111
+ 0xDD60, // ASCII = 190 11011101011
+ 0xDDA0, // ASCII = 191 11011101101
+ 0xDDE0, // ASCII = 192 11011101111
+ 0xDEA0, // ASCII = 193 11011110101
+ 0xDEE0, // ASCII = 194 11011110111
+ 0xDF60, // ASCII = 195 11011111011
+ 0xDFA0, // ASCII = 196 11011111101
+ 0xDFE0, // ASCII = 197 11011111111
+ 0xEAA0, // ASCII = 198 11101010101
+ 0xEAE0, // ASCII = 199 11101010111
+ 0xEB60, // ASCII = 200 11101011011
+ 0xEBA0, // ASCII = 201 11101011101
+ 0xEBE0, // ASCII = 202 11101011111
+ 0xED60, // ASCII = 203 11101101011
+ 0xEDA0, // ASCII = 204 11101101101
+ 0xEDE0, // ASCII = 205 11101101111
+ 0xEEA0, // ASCII = 206 11101110101
+ 0xEEE0, // ASCII = 207 11101110111
+ 0xEF60, // ASCII = 208 11101111011
+ 0xEFA0, // ASCII = 209 11101111101
+ 0xEFE0, // ASCII = 210 11101111111
+ 0xF560, // ASCII = 211 11110101011
+ 0xF5A0, // ASCII = 212 11110101101
+ 0xF5E0, // ASCII = 213 11110101111
+ 0xF6A0, // ASCII = 214 11110110101
+ 0xF6E0, // ASCII = 215 11110110111
+ 0xF760, // ASCII = 216 11110111011
+ 0xF7A0, // ASCII = 217 11110111101
+ 0xF7E0, // ASCII = 218 11110111111
+ 0xFAA0, // ASCII = 219 11111010101
+ 0xFAE0, // ASCII = 220 11111010111
+ 0xFB60, // ASCII = 221 11111011011
+ 0xFBA0, // ASCII = 222 11111011101
+ 0xFBE0, // ASCII = 223 11111011111
+ 0xFD60, // ASCII = 224 11111101011
+ 0xFDA0, // ASCII = 225 11111101101
+ 0xFDE0, // ASCII = 226 11111101111
+ 0xFEA0, // ASCII = 227 11111110101
+ 0xFEE0, // ASCII = 228 11111110111
+ 0xFF60, // ASCII = 229 11111111011
+ 0xFFA0, // ASCII = 230 11111111101
+ 0xFFE0, // ASCII = 231 11111111111
+ 0xAAB0, // ASCII = 232 101010101011
+ 0xAAD0, // ASCII = 233 101010101101
+ 0xAAF0, // ASCII = 234 101010101111
+ 0xAB50, // ASCII = 235 101010110101
+ 0xAB70, // ASCII = 236 101010110111
+ 0xABB0, // ASCII = 237 101010111011
+ 0xABD0, // ASCII = 238 101010111101
+ 0xABF0, // ASCII = 239 101010111111
+ 0xAD50, // ASCII = 240 101011010101
+ 0xAD70, // ASCII = 241 101011010111
+ 0xADB0, // ASCII = 242 101011011011
+ 0xADD0, // ASCII = 243 101011011101
+ 0xADF0, // ASCII = 244 101011011111
+ 0xAEB0, // ASCII = 245 101011101011
+ 0xAED0, // ASCII = 246 101011101101
+ 0xAEF0, // ASCII = 247 101011101111
+ 0xAF50, // ASCII = 248 101011110101
+ 0xAF70, // ASCII = 249 101011110111
+ 0xAFB0, // ASCII = 250 101011111011
+ 0xAFD0, // ASCII = 251 101011111101
+ 0xAFF0, // ASCII = 252 101011111111
+ 0xB550, // ASCII = 253 101101010101
+ 0xB570, // ASCII = 254 101101010111
+ 0xB5B0 // ASCII = 255 101101011011
+};
+
+struct PSKStruct {
+ double* iptr;
+ double* qptr;
+
+ int next;
+};
+
+typedef PSKStruct PSKSTATE;
+
+//Lookup table for determining the next ramp shape depending on the
+// next symbol and the present output phase.
+// indexing format is [symbol][presentPhase]
+//returns the PSKSTRUCT containing the next phase and the I and Q
+// ramp table pointers.
+
+static PSKSTATE PSKPhaseLookupTable[6][5] ={
+ // SYMBOL = 0 = SYM_NOCHANGE
+ // I ramp shape Q ramp shape Next Phase
+ {
+ {PSKShapeTbl_P, PSKShapeTbl_P, PHZ_0}, //present PHZ_0
+ {PSKShapeTbl_M, PSKShapeTbl_P, PHZ_90}, //present PHZ_90
+ {PSKShapeTbl_M, PSKShapeTbl_M, PHZ_180}, //present PHZ_180
+ {PSKShapeTbl_P, PSKShapeTbl_M, PHZ_270}, //present PHZ_270
+ {PSKShapeTbl_Z, PSKShapeTbl_Z, PHZ_OFF}}, //present PHZ_OFF
+ // SYMBOL = 1 = SYM_P90 = Advance 90 degrees
+ // I ramp shape Q ramp shape Next Phase
+ {
+ {PSKShapeTbl_PM, PSKShapeTbl_P, PHZ_90}, //present PHZ_0
+ {PSKShapeTbl_M, PSKShapeTbl_PM, PHZ_180}, //present PHZ_90
+ {PSKShapeTbl_MP, PSKShapeTbl_M, PHZ_270}, //present PHZ_180
+ {PSKShapeTbl_P, PSKShapeTbl_MP, PHZ_0}, //present PHZ_270
+ {PSKShapeTbl_ZP, PSKShapeTbl_ZP, PHZ_0}}, //present PHZ_OFF
+ // SYMBOL = 2 = SYM_P180 = Advance 180 degrees
+ // I ramp shape Q ramp shape Next Phase
+ {
+ {PSKShapeTbl_PM, PSKShapeTbl_PM, PHZ_180}, //present PHZ_0
+ {PSKShapeTbl_MP, PSKShapeTbl_PM, PHZ_270}, //present PHZ_90
+ {PSKShapeTbl_MP, PSKShapeTbl_MP, PHZ_0}, //present PHZ_180
+ {PSKShapeTbl_PM, PSKShapeTbl_MP, PHZ_90}, //present PHZ_270
+ {PSKShapeTbl_ZP, PSKShapeTbl_ZP, PHZ_0}}, //present PHZ_OFF
+ // SYMBOL = 3 = SYM_M90 = retard 90 degrees
+ // I ramp shape Q ramp shape Next Phase
+ {
+ {PSKShapeTbl_P, PSKShapeTbl_PM, PHZ_270}, //present PHZ_0
+ {PSKShapeTbl_MP, PSKShapeTbl_P, PHZ_0}, //present PHZ_90
+ {PSKShapeTbl_M, PSKShapeTbl_MP, PHZ_90}, //present PHZ_180
+ {PSKShapeTbl_PM, PSKShapeTbl_M, PHZ_180}, //present PHZ_270
+ {PSKShapeTbl_ZP, PSKShapeTbl_ZP, PHZ_0}}, //present PHZ_OFF
+ // SYMBOL = 4 = SYM_OFF
+ // I ramp shape Q ramp shape Next Phase
+ {
+ {PSKShapeTbl_PZ, PSKShapeTbl_PZ, PHZ_OFF}, //present PHZ_0
+ {PSKShapeTbl_MZ, PSKShapeTbl_PZ, PHZ_OFF}, //present PHZ_90
+ {PSKShapeTbl_MZ, PSKShapeTbl_MZ, PHZ_OFF}, //present PHZ_180
+ {PSKShapeTbl_PZ, PSKShapeTbl_MZ, PHZ_OFF}, //present PHZ_270
+ {PSKShapeTbl_Z, PSKShapeTbl_Z, PHZ_OFF}}, //present PHZ_OFF
+ // SYMBOL = 5 = SYM_ON
+ // I ramp shape Q ramp shape Next Phase
+ {
+ {PSKShapeTbl_P, PSKShapeTbl_P, PHZ_0}, //present PHZ_0
+ {PSKShapeTbl_MP, PSKShapeTbl_P, PHZ_0}, //present PHZ_90
+ {PSKShapeTbl_MP, PSKShapeTbl_MP, PHZ_0}, //present PHZ_180
+ {PSKShapeTbl_P, PSKShapeTbl_MP, PHZ_0}, //present PHZ_270
+ {PSKShapeTbl_ZP, PSKShapeTbl_ZP, PHZ_0}} //present PHZ_OFF
+};
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+PSKModulator::PSKModulator(int FS, double freq, CTxBuffer *TxBuffer) : CModulator(FS, TxBuffer) {
+
+ m_AmblePtr = 0;
+ int RampSize;
+ int i;
+
+ m_PSKPhaseInc = PI2 * freq / (double) SampleRate; //carrier frequency
+
+ m_PSKSecPerSamp = 1.0 / (double) SampleRate;
+ m_PSKTime = 0.0;
+ m_t = 0.0;
+ m_Ramp = 0;
+ m_PSKPeriodUpdate = 1.0 / SYMBOL_RATE; //symbol period
+ m_Lastsymb = SYM_OFF;
+ m_AddEndingZero = true;
+ m_CWState = 0;
+ m_CWtimer = 0;
+ // Generate cosine ramp envelope lookup tables
+ RampSize = (((100 * SampleRate) / 3125) + 1); // number of envelope ramp steps per symbol
+ for (i = 0; i < RampSize; i++) {
+ PSKShapeTbl_Z[i] = 0.0;
+ PSKShapeTbl_P[i] = 1.0;
+ PSKShapeTbl_M[i] = -1.0;
+ PSKShapeTbl_PM[i] = cos((double) i * PI2 / (RampSize * 2));
+ PSKShapeTbl_MP[i] = -PSKShapeTbl_PM[i];
+
+ if (i < RampSize / 2) {
+ PSKShapeTbl_PZ[i] = cos((double) i * PI2 / (RampSize * 2));
+ PSKShapeTbl_MZ[i] = -PSKShapeTbl_PZ[i];
+ PSKShapeTbl_ZP[i] = 0.0;
+ } else {
+ PSKShapeTbl_ZP[i] = -cos((double) i * PI2 / (RampSize * 2));
+ PSKShapeTbl_PZ[i] = 0.0;
+ PSKShapeTbl_MZ[i] = 0.0;
+ }
+
+ }
+ i = 0;
+ while (i < 32) //create post/preamble tables
+ {
+ m_Preamble[i] = TXTOG_CODE;
+ m_Postamble[i++] = TXON_CODE;
+ }
+ m_Preamble[i] = 0; // null terminate these tables
+ m_Postamble[i] = 0;
+
+ m_pPSKtxI = PSKShapeTbl_Z;
+ m_pPSKtxQ = PSKShapeTbl_Z;
+ m_PresentPhase = PHZ_OFF;
+ m_TxShiftReg = 0;
+ status = TX_PREAMBLE_STATE;
+
+}
+
+PSKModulator::~PSKModulator() {
+}
+
+///////////++++++++++++++++++++++++++++++++++////////////////
+/////////// P S K 3 1 M O D U L A T O R ////////////////
+///////////++++++++++++++++++++++++++++++++++////////////////
+
+
+
+/////////////////////////////////////////////////////////////
+// generates n samples of psk31 waveform in data array pData
+/////////////////////////////////////////////////////////////
+
+int PSKModulator::CalcSignal(double *pData, int n)
+ {
+ int symbol;
+ int i;
+
+ // m_RMSConstant = TX_CONSTANT;
+
+ for (i = 0; i < n; i++) //calculate n samples of tx data stream
+ {
+ m_t += m_PSKPhaseInc; // increment radian phase count
+
+ pData[i] = 0.45 * (m_pPSKtxI[m_Ramp] * sin(m_t) + m_pPSKtxQ[m_Ramp++] * cos(m_t));
+
+ m_PSKTime += m_PSKSecPerSamp;
+ if (m_PSKTime >= m_PSKPeriodUpdate)//if time to update envelope ramp index
+ {
+ m_PSKTime -= m_PSKPeriodUpdate; //keep time bounded
+ m_Ramp = 0; // time to update symbol
+ m_t = fmod(m_t, PI2); //keep radian counter bounded
+ if (status == TX_CWID_STATE)
+ symbol = GetNextCWSymbol();
+ else
+ symbol = GetNextSymbol();
+
+ //get new I/Q ramp tables and next phase
+ m_pPSKtxI = PSKPhaseLookupTable[symbol][m_PresentPhase].iptr;
+ m_pPSKtxQ = PSKPhaseLookupTable[symbol][m_PresentPhase].qptr;
+ m_PresentPhase = PSKPhaseLookupTable[symbol][m_PresentPhase].next;
+ }
+ if (status == TX_END_STATE) // We have reached end of Transmission
+ return -i;
+ }
+ return n;
+}
+
+
+/////////////////////////////////////////////////////////////
+// called every symbol time to get next CW symbol and get the
+// next character from the character Queue if no more symbols
+// are left to send.
+/////////////////////////////////////////////////////////////
+
+char PSKModulator::GetNextCWSymbol(void) {
+ char symb;
+ int ch;
+ symb = m_Lastsymb; //use last symbol unless it needs to change
+ if ((m_TxShiftReg == 0) && (m_CWState == 0)) {
+ ch = GetChar(); //get next character to xmit
+ if (ch >= 0) //if is not a control code
+ {
+ ch &= 0xFF;
+ ch = (int) toupper((char) ch); //make upper case
+ if (ch >= ' ' && ch <= 'Z')
+ m_TxShiftReg = CW_TABLE[ ch - ' ']; //look up pattern
+ } else // is a control code
+ {
+ if (ch == TXON_CODE)
+ symb = SYM_ON;
+ else
+ symb = SYM_OFF;
+ return symb;
+ }
+ m_CWState = 0;
+ }
+ switch (m_CWState) // CW timing state machine
+ {
+ case 0: //get next cw symbol state from pattern
+ switch (m_TxShiftReg & 0xC000) {
+ case 0x4000: //dot
+ m_CWState = 1;
+ m_CWtimer = 1 * CW_SPEED;
+ symb = SYM_ON;
+ break;
+ case 0x8000: //dash
+ m_CWState = 1;
+ m_CWtimer = 3 * CW_SPEED;
+ symb = SYM_ON;
+ break;
+ case 0xC000: //inter char space
+ m_CWState = 2;
+ m_CWtimer = 3 * CW_SPEED;
+ symb = SYM_OFF;
+ break;
+ default:
+ symb = SYM_OFF;
+ break;
+ }
+ m_TxShiftReg = m_TxShiftReg << 2; //
+ break;
+ case 1: //On time state
+ if (--m_CWtimer <= 0) {
+ m_CWState = 2;
+ m_CWtimer = 1 * CW_SPEED; //inter symbol time
+ symb = SYM_OFF;
+ } else
+ symb = SYM_NOCHANGE;
+ break;
+ case 2: //Off time state
+ if (--m_CWtimer <= 0)
+ m_CWState = 0;
+ break;
+ }
+ m_Lastsymb = symb;
+ return symb;
+}
+/////////////////////////////////////////////////////////////
+//get next character/symbol depending on TX state.
+/////////////////////////////////////////////////////////////
+
+int PSKModulator::GetChar() {
+ int ch;
+ static int last = 0;
+ switch (status) {
+ case TX_OFF_STATE: //is receiving
+ ch = TXOFF_CODE; //else turn off
+ break;
+ case TX_TUNE_STATE:
+ ch = TXON_CODE; // steady carrier
+ break;
+ case TX_PAUSED_STATE:
+ ch = TXTOG_CODE; // steady idle symbol
+ break;
+ case TX_POSTAMBLE_STATE: // ending sequence
+ /// if( !(ch = m_Postamble[m_AmblePtr++] )) //m_Postamble is 0 terminated
+ ch = m_Postamble[m_AmblePtr++];
+ if (ch == 0) //m_Postamble is 0 terminated
+ {
+ m_AmblePtr = 0;
+ ch = TXOFF_CODE;
+ status = TX_END_STATE;
+ }
+ break;
+ case TX_PREAMBLE_STATE: //starting sequence
+ if (!(ch = m_Preamble[m_AmblePtr++])) {
+ status = TX_SENDING_STATE;
+ m_AmblePtr = 0;
+ ch = TXTOG_CODE;
+ }
+ break;
+ case TX_CWID_STATE: // id sending CW ID
+ /**
+ if( m_AmblePtr >= settings.CWIdString.length() )
+ {
+ m_AmblePtr = 0;
+ ch = TXOFF_CODE;
+ status = TX_END_STATE;
+ }
+ else
+ ch = settings.CWIdString.at(m_AmblePtr++).cell();
+ **/
+ break;
+ case TX_SENDING_STATE: //if sending text from TX window
+ ch = Buffer->getTxChar();
+ if (ch > 0) {
+ emit charSend((char) ch);
+ m_AmblePtr = 0;
+ } else
+ if (ch == TXOFF_CODE)
+ status = TX_POSTAMBLE_STATE;
+ m_AmblePtr = 0;
+ break;
+ case TX_END_STATE:
+ break;
+ }
+ last = ch;
+ return ( ch);
+}
+
diff --git a/src/pskmodulator.h b/src/pskmodulator.h
new file mode 100644
index 0000000..4a2e477
--- /dev/null
+++ b/src/pskmodulator.h
@@ -0,0 +1,111 @@
+//////////////////////////////////////////////////////////////////////
+// PSKMod.h: interface for the CPSKMod class.
+//
+//////////////////////////////////////////////////////////////////////
+// PSK31/CW modulator
+// Copyright 1999. Moe Wheatley AE4JY <ae4jy at mindspring.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 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.
+//
+//////////////////////////////////////////////////////////////////////
+//
+// Modified by Volker Schroer, DL1KSV, for use in LinPsk
+
+#ifndef PSKMOD_H
+#define PSKMOD_H
+
+#include <qobject.h>
+#include <ctype.h>
+
+#include "ctxdisplay.h"
+#include "ctxwindow.h"
+#include "cmodulator.h"
+
+
+
+class CTxBuffer;
+
+class PSKModulator : public CModulator
+{
+ Q_OBJECT
+public:
+ PSKModulator(int,double,CTxBuffer *);
+ virtual ~PSKModulator();
+// PSK31 and CW modulator
+ int CalcSignal( double* pData , int n);
+/** length = CalcSignal (double *pData, int n)
+ Reads tx Buffer and calculates the signal values to be transmitted
+ double *pData pointer to array for computed signal values
+ n length of array
+ length number of calculated values , normally n
+ -length at the end of transmission
+*/
+
+private:
+ QString m_TestString;
+ unsigned int m_AmblePtr;
+ int m_Preamble[33];
+ int m_Postamble[33];
+
+// PSK31 and CW generator variables
+ double m_t;
+ int m_Ramp;
+/// double m_RMSConstant;
+
+ double m_PSKSecPerSamp;
+ double m_PSKTime;
+ double m_PSKPeriodUpdate;
+ double m_PSKPhaseInc;
+
+
+ double* m_pPSKtxI;
+ double* m_pPSKtxQ;
+ int m_PresentPhase;
+ int m_CWState;
+ int m_CWtimer;
+
+
+// PSK31 and CW modulator private functions
+
+// char GetNextBPSKSymbol(void);
+// char GetNextQPSKSymbol(void);
+virtual char GetNextSymbol(void)=0;
+ char GetNextCWSymbol(void);
+protected:
+ char m_Lastsymb;
+ unsigned short int m_TxShiftReg;
+ int GetChar();
+ bool m_AddEndingZero;
+static const unsigned short int VARICODE_TABLE[];
+enum Status
+{
+TX_END_STATE, //Xmitting should be stoped
+TX_OFF_STATE, //TX is off, so we are receiving
+TX_SENDING_STATE, //TX is sending text
+TX_PAUSED_STATE , //TX is paused
+TX_PREAMBLE_STATE, //TX sending starting preamble
+TX_POSTAMBLE_STATE, //TX sending ending posteamble
+TX_CWID_STATE, //TX sending CW ID
+TX_TUNE_STATE //TX is tuning mode
+};
+Status status;
+public slots:
+signals: // Signals
+ /** Tx finished */
+// void finished();
+// void charSend(char);
+};
+
+#endif
diff --git a/src/psktable.h b/src/psktable.h
new file mode 100644
index 0000000..79f187f
--- /dev/null
+++ b/src/psktable.h
@@ -0,0 +1,120 @@
+#if !defined(PSKTablesXYZ)
+#define PSKTablesXYZ
+//////////////////////////////////////////////////////////////////////
+// Copyright 1999. Moe Wheatley AE4JY <ae4jy at mindspring.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 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.
+//
+//////////////////////////////////////////////////////////////////////
+//
+//////////////////// Various constant tabels //////////////////////////
+// The word in the CW table is divided into 8 groups of two bits starting
+// at the msb side. The two bits represent one of four possible states.
+// 00 - end of character
+// 01 - DOT
+// 10 - DASH
+// 11 - SPACE of two dot times
+const unsigned short int CW_TABLE[59]=
+{
+ 0xF000, // 1111 0000 0000 0000b ( 32) WORD SPACE
+ 0x0000, // 0000 0000 0000 0000b ( 33) !
+ 0x0000, // 0000 0000 0000 0000b ( 34) "
+ 0x0000, // 0000 0000 0000 0000b ( 35) #
+ 0x0000, // 0000 0000 0000 0000b ( 36) $
+ 0x0000, // 0000 0000 0000 0000b ( 37) %
+ 0x0000, // 0000 0000 0000 0000b ( 38) &
+ 0x0000, // 0000 0000 0000 0000b ( 39) '
+ 0x0000, // 0000 0000 0000 0000b ( 40) (
+ 0x0000, // 0000 0000 0000 0000b ( 41) )
+ 0x566C, // 0101 0110 0110 1100b ( 42) * ...-.- SK
+ 0x6670, // 0110 0110 0111 0000b ( 43) + .-.-. AR
+ 0xA5AC, // 1010 0101 1010 1100b ( 44) , --..--
+ 0x0000, // 0000 0000 0000 0000b ( 45) -
+ 0x666C, // 0110 0110 0110 1100b ( 46) . .-.-.-
+ 0x9670, // 1001 0110 0111 0000b ( 47) / -..-.
+ 0xAAB0, // 1010 1010 1011 0000b ( 48) 0 -----
+ 0x6AB0, // 0110 1010 1011 0000b ( 49) 1 .----
+ 0x5AB0, // 0101 1010 1011 0000b ( 50) 2 ..---
+ 0x56B0, // 0101 0110 1011 0000b ( 51) 3 ...--
+ 0x55B0, // 0101 0101 1011 0000b ( 52) 4 ....-
+ 0x5570, // 0101 0101 0111 0000b ( 53) 5 .....
+ 0x9570, // 1001 0101 0111 0000b ( 54) 6 -....
+ 0xA570, // 1010 0101 0111 0000b ( 55) 7 --...
+ 0xA970, // 1010 1001 0111 0000b ( 56) 8 ---..
+ 0xAA70, // 1010 1010 0111 0000b ( 57) 9 ----.
+ 0x0000, // 0000 0000 0000 0000b ( 58) :
+ 0x0000, // 0000 0000 0000 0000b ( 59) ;
+ 0x0000, // 0000 0000 0000 0000b ( 60) <
+ 0x95B0, // 1001 0101 1011 0000b ( 61) = -...- BT
+ 0x0000, // 0000 0000 0000 0000b ( 62) >
+ 0x5A5C, // 0101 1010 0101 1100b ( 63) ? ..--..
+ 0x0000, // 0000 0000 0000 0000b ( 64) @
+ 0x6C00, // 0110 1100 0000 0000b ( 65) A .-
+ 0x95C0, // 1001 0101 1100 0000b ( 66) B -...
+ 0x99C0, // 1001 1001 1100 0000b ( 67) C -.-.
+ 0x9700, // 1001 0111 0000 0000b ( 68) D -..
+ 0x7000, // 0111 0000 0000 0000b ( 69) E .
+ 0x59C0, // 0101 1001 1100 0000b ( 70) F ..-.
+ 0xA700, // 1010 0111 0000 0000b ( 71) G --.
+ 0x55C0, // 0101 0101 1100 0000b ( 72) H ....
+ 0x5C00, // 0101 1100 0000 0000b ( 73) I ..
+ 0x6AC0, // 0110 1010 1100 0000b ( 74) J .---
+ 0x9B00, // 1001 1011 0000 0000b ( 75) K -.-
+ 0x65C0, // 0110 0101 1100 0000b ( 76) L .-..
+ 0xAC00, // 1010 1100 0000 0000b ( 77) M --
+ 0x9C00, // 1001 1100 0000 0000b ( 78) N -.
+ 0xAB00, // 1010 1011 0000 0000b ( 79) O ---
+ 0x69C0, // 0110 1001 1100 0000b ( 80) P .--.
+ 0xA6C0, // 1010 0110 1100 0000b ( 81) Q --.-
+ 0x6700, // 0110 0111 0000 0000b ( 82) R .-.
+ 0x5700, // 0101 0111 0000 0000b ( 83) S ...
+ 0xB000, // 1011 0000 0000 0000b ( 84) T -
+ 0x5B00, // 0101 1011 0000 0000b ( 85) U ..-
+ 0x56C0, // 0101 0110 1100 0000b ( 86) V ...-
+ 0x6B00, // 0110 1011 0000 0000b ( 87) W .--
+ 0x96C0, // 1001 0110 1100 0000b ( 88) X -..-
+ 0x9AC0, // 1001 1010 1100 0000b ( 89) Y -.--
+ 0xA5C0 // 1010 0101 1100 0000b ( 90) Z --..
+};
+
+
+
+// For the QPSK modulator/demodulator, rate 1/2 constraint length 5
+// convolutional FEC coding is used.
+// The generator polynomials used are:
+// g1(x) = x^4 + x^3 + 1 = 0x19
+// g0(x) = x^4 + x^2 + x + 1 = 0x17
+//
+// g1(x)
+// /----+--------+--------------------------+
+// / | | |
+// symbol msb --- --- --- --- ---
+// | b4|<---| b3|<---| b2|<---| b1|<---| b0| <-- inverted data in
+// symbol lsb --- --- --- --- ---
+// \ | | | |
+// \----+-----------------+--------+--------+
+// g0(x)
+//
+// Lookup table to get symbol from non-inverted data stream
+/**
+static const unsigned char ConvolutionCodeTable[32] =
+{
+ 2, 1, 3, 0, 3, 0, 2, 1,
+ 0, 3, 1, 2, 1, 2, 0, 3,
+ 1, 2, 0, 3, 0, 3, 1, 2,
+ 3, 0, 2, 1, 2, 1, 3, 0
+};
+**/
+#endif
diff --git a/src/qpskdemodulator.cpp b/src/qpskdemodulator.cpp
new file mode 100644
index 0000000..fca9f0e
--- /dev/null
+++ b/src/qpskdemodulator.cpp
@@ -0,0 +1,156 @@
+/***************************************************************************
+ qpskdemodulator.cpp - description
+ -------------------
+ begin : Sat Jun 2 2001
+ copyright : (C) 2001 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * based on the work of Moe Wheatly, AE4JY *
+ ***************************************************************************/
+
+#include "qpskdemodulator.h"
+#include "viterbi.h"
+
+// phase wraparound correction table for viterbi decoder
+//static const double AngleTbl1[4] = { M_PI_3_2, 0.0, M_PI/2.0, M_PI};
+//static const double AngleTbl2[4] = { M_PI_3_2, PI2, M_PI/2.0, M_PI};
+//static const double AngleTbl1[4] = { M_PI_2, -M_PI, -M_PI_2,0.0};
+//static const double AngleTbl2[4] = { M_PI_2, M_PI, M_PI_3_2,0.0};
+static const double AngleTbl1[4] = { 0.0, -M_PI_2, -M_PI,-M_PI_3_2};
+static const double AngleTbl2[4] = { 0.0, M_PI_3_2, M_PI,M_PI_2};
+
+
+static const double qdistance(double *x,int i)
+{
+
+const double *pAngle;
+
+
+if ( *x >0.0)
+ pAngle = AngleTbl2;
+else
+ pAngle = AngleTbl1;
+//i = (~i) & 0x03;
+
+i= i & 0x03;
+
+return fabs(*x - pAngle[i]);
+}
+
+
+QPskDemodulator::QPskDemodulator():CPskDemodulator()
+{
+
+ave1=1.0;
+ave2=1.0;
+
+v=new Viterbi(5,0x19,0x17,qdistance);
+}
+QPskDemodulator::~QPskDemodulator()
+{
+}
+void QPskDemodulator::DecodeSymbol(double angle)
+
+{
+
+int bit;
+
+char ch =0;
+ CalcQuality(angle);
+ v->decode( &angle);
+ bit = v->getbitinvers(32);
+
+ if( (bit==0) && m_LastBitZero ) //if character delimiter
+ {
+ if(m_BitAcc != 0 )
+ {
+ m_BitAcc >>= 2; //get rid of last zero and one
+ m_BitAcc &= 0x07FF;
+ ch = m_VaricodeDecTbl[m_BitAcc];
+ m_BitAcc = 0;
+ if( (ch!=0) &&
+ ( !Squelch || (Squelch && (fastSquelch || ( ( unsigned int ) m_DevAve > Threshold )))) // Squelch Part
+ )
+ {
+ emit newSymbol(ch);
+ if (fastSquelch && (( unsigned int ) m_DevAve < Threshold) )
+ fastSquelch = false;
+ }
+ }
+ }
+ else
+ {
+ m_BitAcc <<= 1;
+ m_BitAcc |= bit;
+ if(bit==0)
+ m_LastBitZero = true;
+ else
+ m_LastBitZero = false;
+ }
+
+ if (bit)
+ {
+ m_OffCount=0;
+ if (m_OnCount++ >20)
+ fastSquelch=true;
+ }
+ else
+ {
+ m_OnCount=0;
+ if (m_OffCount++ > 20)
+ fastSquelch=false;
+ }
+
+
+}
+
+//////////////////////////////////////////////////////////////////////
+// Calculate signal quality based on the statistics of the phase
+// difference angle. The more dispersion of the "0" and "180" degree
+// phase shifts, the worse the signal quality. This information is used
+// to activate the squelch control. If 20 consecutive "180" degree shifts
+// occur, the squelch is forced on, and if 20 consecutive "0" degree
+// shifts occur, the squelch is forced off quickly.
+//////////////////////////////////////////////////////////////////////
+
+void QPskDemodulator::CalcQuality( double angle )
+{
+
+double temp;
+double absangle;
+
+absangle= fabs(angle);
+if ( absangle < M_PI_4)
+ temp= angle;
+else
+ {
+ if ( absangle < M_PI_3_4 )
+ temp = M_PI_2 - absangle;
+ else
+ temp = M_PI - absangle;
+ }
+if ( angle < 0.0 )
+ temp = -temp;
+m_QFreqError = temp;
+temp = fabs(temp);
+
+
+// m_DevAve =0.47 * ave1 + 0.46 * ave2 + 0.07 *temp;
+m_DevAve =0.5 * ave1 + 0.45 * ave2 + 0.05*temp;
+
+ave2=ave1;
+ave1=m_DevAve;
+
+// And now norm m_DevAve for use in Squelch
+m_DevAve = 100. -m_DevAve *110.;
+
+}
+
+
diff --git a/src/qpskdemodulator.h b/src/qpskdemodulator.h
new file mode 100644
index 0000000..8cbdc1a
--- /dev/null
+++ b/src/qpskdemodulator.h
@@ -0,0 +1,47 @@
+/***************************************************************************
+ qpskdemodulator.h - description
+ -------------------
+ begin : Sat Jun 2 2001
+ copyright : (C) 2001 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * based on the work of Moe Wheatley, AE4JY *
+ ***************************************************************************/
+
+#ifndef QPSKDEMODULATOR_H
+#define QPSKDEMODULATOR_H
+
+#include "cpskdemodulator.h"
+
+/**Implementation of the QPsk demodulator
+ *@author Volker Schroer
+ */
+
+class Viterbi;
+
+class QPskDemodulator : public CPskDemodulator {
+public:
+ QPskDemodulator();
+ ~QPskDemodulator();
+
+protected:
+/** Decodes a QPSK Symbol */
+//void DecodeSymbol( complex<double> newsamp);
+void DecodeSymbol( double);
+
+void CalcQuality(double);
+private:
+ double ave1,ave2;
+Viterbi *v;
+
+
+};
+
+#endif
diff --git a/src/qpskmodulator.cpp b/src/qpskmodulator.cpp
new file mode 100644
index 0000000..bc37876
--- /dev/null
+++ b/src/qpskmodulator.cpp
@@ -0,0 +1,103 @@
+/***************************************************************************
+ qpskmodulator.cpp - description
+ -------------------
+ begin : Don Feb 27 2003
+ copyright : (C) 2003 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * The PSK part is based on WinPSK 1.0 by Moe Wheatly, AE4JY *
+ ***************************************************************************/
+
+#include "qpskmodulator.h"
+#include "constants.h"
+#define SYM_OFF 4 //No output
+#define SYM_ON 5 //constant output
+// For the QPSK modulator/demodulator, rate 1/2 constraint length 5
+// convolutional FEC coding is used.
+// The generator polynomials used are:
+// g1(x) = x^4 + x^3 + 1 = 0x19
+// g0(x) = x^4 + x^2 + x + 1 = 0x17
+//
+// g1(x)
+// /----+--------+--------------------------+
+// / | | |
+// symbol msb --- --- --- --- ---
+// | b4|<---| b3|<---| b2|<---| b1|<---| b0| <-- inverted data in
+// symbol lsb --- --- --- --- ---
+// \ | | | |
+// \----+-----------------+--------+--------+
+// g0(x)
+//
+// Lookup table to get symbol from non-inverted data stream
+static const unsigned char ConvolutionCodeTable[32] =
+{
+ 2, 1, 3, 0, 3, 0, 2, 1,
+ 0, 3, 1, 2, 1, 2, 0, 3,
+ 1, 2, 0, 3, 0, 3, 1, 2,
+ 3, 0, 2, 1, 2, 1, 3, 0
+};
+
+QPskModulator::QPskModulator(int FS,double freq,CTxBuffer *TxBuffer):PSKModulator(FS,freq,TxBuffer)
+{
+m_TxCodeWord = 0;
+}
+QPskModulator::~QPskModulator()
+{
+}
+char QPskModulator::GetNextSymbol(void)
+{
+char symb;
+int ch;
+ symb = ConvolutionCodeTable[m_TxShiftReg&0x1F]; //get next convolution code
+ m_TxShiftReg = m_TxShiftReg<<1;
+ if( m_TxCodeWord == 0 ) //need to get next codeword
+ {
+ if( m_AddEndingZero ) //if need to add a zero
+ {
+ m_AddEndingZero = false; //end with a zero
+ }
+ else
+ {
+ ch = GetChar(); //get next character to xmit
+ if( ch >=0 ) //if not a control code
+ { //get next VARICODE codeword to send
+ m_TxCodeWord = VARICODE_TABLE[ ch&0xFF ];
+ }
+ else //is a control code
+ {
+ switch( ch )
+ {
+ case TXON_CODE:
+ symb = SYM_ON;
+ break;
+ case TXTOG_CODE:
+ m_TxCodeWord = 0;
+ break;
+ case TXOFF_CODE:
+ symb = SYM_OFF;
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ if(m_TxCodeWord&0x8000 )
+ {
+ m_TxShiftReg |= 1;
+ }
+ m_TxCodeWord = m_TxCodeWord<<1;
+ if(m_TxCodeWord == 0)
+ m_AddEndingZero = true; //need to add another zero
+ }
+ return symb;
+}
+
+
diff --git a/src/qpskmodulator.h b/src/qpskmodulator.h
new file mode 100644
index 0000000..13a3556
--- /dev/null
+++ b/src/qpskmodulator.h
@@ -0,0 +1,37 @@
+/***************************************************************************
+ qpskmodulator.h - description
+ -------------------
+ begin : Don Feb 27 2003
+ copyright : (C) 2003 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * The PSK part is based on WinPSK 1.0 by Moe Wheatley, AE4JY *
+ ***************************************************************************/
+
+#ifndef QPSKMODULATOR_H
+#define QPSKMODULATOR_H
+
+#include "pskmodulator.h"
+class CTxBuffer;
+/**
+ *@author Volker Schroer
+ */
+
+class QPskModulator : public PSKModulator {
+public:
+ QPskModulator(int, double, CTxBuffer *);
+ ~QPskModulator();
+char GetNextSymbol(void);
+private:
+
+ unsigned short int m_TxCodeWord;
+};
+
+#endif
diff --git a/src/readonlystringlistmodel.cpp b/src/readonlystringlistmodel.cpp
new file mode 100644
index 0000000..b62da80
--- /dev/null
+++ b/src/readonlystringlistmodel.cpp
@@ -0,0 +1,35 @@
+/***************************************************************************
+ * Copyright (C) 2007 by volker, DL1KSV *
+ * schroer at tux64 *
+ * *
+ * 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 "readonlystringlistmodel.h"
+
+ReadOnlyStringListModel::ReadOnlyStringListModel(QObject *parent)
+ : QStringListModel(parent)
+{
+}
+ReadOnlyStringListModel::ReadOnlyStringListModel ( const QStringList & strings, QObject * parent ):QStringListModel(strings,parent)
+{
+}
+
+
+Qt::ItemFlags ReadOnlyStringListModel::flags ( const QModelIndex & ) const
+{
+return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
+}
+
diff --git a/src/readonlystringlistmodel.h b/src/readonlystringlistmodel.h
new file mode 100644
index 0000000..e03d905
--- /dev/null
+++ b/src/readonlystringlistmodel.h
@@ -0,0 +1,41 @@
+/***************************************************************************
+ * Copyright (C) 2007 by volker, DL1KSV *
+ * schroer at tux64 *
+ * *
+ * 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 READONLYSTRINGLISTMODEL_H
+#define READONLYSTRINGLISTMODEL_H
+
+#include <QStringListModel>
+
+/**
+ReadOnlyStringListModel provides a readonly StringList model, so that views of this model cannot change the model's data
+
+ @author volker, DL1KSV <schroer at tux64>
+*/
+class ReadOnlyStringListModel : public QStringListModel
+{
+Q_OBJECT
+public:
+ ReadOnlyStringListModel(QObject *parent = 0);
+ReadOnlyStringListModel ( const QStringList & strings, QObject * parent = 0 );
+ // ~ReadOnlyStringListModel();
+ Qt::ItemFlags flags ( const QModelIndex & index ) const;
+
+};
+
+#endif
diff --git a/src/rttydemodulator.cpp b/src/rttydemodulator.cpp
new file mode 100644
index 0000000..46314f8
--- /dev/null
+++ b/src/rttydemodulator.cpp
@@ -0,0 +1,611 @@
+/***************************************************************************
+ rttydemodulator.cpp - description
+ -------------------
+ begin : Mon Jun 4 2001
+ copyright : (C) 2001 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#include "rttydemodulator.h"
+#include "firfilter.h"
+#include "constants.h"
+
+
+
+RTTYDemodulator::RTTYDemodulator() : CDemodulator()
+{
+ int i;
+ ShiftOn = false;
+ BufferPointer = 0;
+ BufferCount = 0;
+ StopBitLength = 0;
+ RxFrequency = 0.0; // Will be set correctly in setFrequency !
+//Initialize ExtraParameter
+ extraParameter.stopbits = Onepoint5;
+ extraParameter.parity = None;
+ extraParameter.reverse = true;
+ extraParameter.offset = 170;
+ /** Have to use new with ggc 4, otherwise I get a lot of nan's in fftw_execute, at least on AMD64 **/
+ pIn = new complex<double>[FFTLENGTH];
+ pOutF0 = new complex<double>[FFTLENGTH];
+ pOutF1 = new complex<double>[FFTLENGTH];
+ pFilterF0 = new complex<double>[FFTLENGTH];
+ pFilterF1 = new complex<double>[FFTLENGTH];
+ pFilterIn = new complex<double>[FFTLENGTH];
+ pResultF0 = new complex<double>[FFTLENGTH];
+ pResultF1 = new complex<double>[FFTLENGTH];
+ pOverlapF0 = new complex<double>[FFTFILTERLENGTH-1];
+ pOverlapF1 = new complex<double>[FFTFILTERLENGTH-1];
+
+ pforward = fftw_plan_dft_1d ( FFTLENGTH, ( fftw_complex * ) pIn, ( fftw_complex * ) pOutF0, FFTW_FORWARD, FFTW_ESTIMATE );
+ pbackwardF0 = fftw_plan_dft_1d ( FFTLENGTH, ( fftw_complex * ) pOutF0, ( fftw_complex * ) pResultF0, FFTW_BACKWARD, FFTW_ESTIMATE );
+ pbackwardF1 = fftw_plan_dft_1d ( FFTLENGTH, ( fftw_complex * ) pOutF1, ( fftw_complex * ) pResultF1, FFTW_BACKWARD, FFTW_ESTIMATE );
+ pfilter = fftw_plan_dft_1d ( FFTLENGTH, ( fftw_complex * ) pFilterIn, ( fftw_complex * ) pFilterF0, FFTW_FORWARD, FFTW_ESTIMATE );
+
+
+ for ( i = 0; i < FFTFILTERLENGTH - 1;i++ )
+ {
+ pOverlapF0[i] = complex<double> ( 0., 0. );
+ pOverlapF1[i] = complex<double> ( 0., 0. );
+ }
+ filteredSamples = 0;
+ delayZ = complex<double> ( 0., 0. );
+}
+
+RTTYDemodulator::~RTTYDemodulator()
+{
+ fftw_destroy_plan ( pforward );
+ fftw_destroy_plan ( pbackwardF0 );
+ fftw_destroy_plan ( pbackwardF1 );
+ fftw_destroy_plan ( pfilter );
+ fftw_free ( pIn );
+ fftw_free ( pOutF0 );
+ fftw_free ( pOutF1 );
+ fftw_free ( pFilterF0 );
+ fftw_free ( pFilterF1 );
+ fftw_free ( pFilterIn );
+ fftw_free ( pResultF0 );
+ fftw_free ( pResultF1 );
+ fftw_free ( pOverlapF0 );
+ fftw_free ( pOverlapF1 );
+}
+/** returns the asci char corresponding to the baudot code */
+char RTTYDemodulator::baudot_code ( char data )
+{
+ /** Table of letters */
+
+ static const char letters[32] =
+ {
+ 0x00, 'E', '\r', 'A', ' ', 'S', 'I', 'U',
+ '\n', 'D', 'R', 'J', 'N', 'F', 'C', 'K',
+ 'T', 'Z', 'L', 'W', 'H', 'Y', 'P', 'Q',
+ 'O', 'B', 'G', '^', 'M', 'X', 'V', '^'
+ };
+
+
+ /** Table of symbols */
+ static const char symbols[32] =
+ {
+ 0x00, '3', '\r', '-', ' ', '\'', '8', '7',
+ '\n', '$', '4', '#', ',', '!', ':', '(',
+ '5', '"', ')', '2', '#', '6', '0', '1',
+ '9', '?', '&', '^', '.', '/', '=', '^'
+ };
+
+ char c;
+
+ switch ( data )
+ {
+ case 0x1f :
+ ShiftOn = false; //LTRS
+ c = 0;
+ break;
+ case 0x1b :
+ ShiftOn = true; //FIGS
+ c = 0;
+ break;
+ default:
+ if ( !ShiftOn )
+ c = letters[ ( int ) data];
+ else
+ c = symbols[ ( int ) data];
+ break;
+ }
+
+
+ if ( c == ' ' ) // Unshift on Space
+ ShiftOn = false;
+
+ return c;
+}
+
+bool RTTYDemodulator::Init ( double FS, int )
+{
+ SampleRate = FS;
+ Baudrate = 45.45;
+ NumberOfBits = 5;
+ SymbolLength = int ( FS / Baudrate + 0.5 );
+ Status = WaitingForMark;
+ FrequencyChanged = false;
+ ave1 = 0.5;
+ ave2 = 0.0;
+ setRxFrequency ( 1000. );
+ F0inc = 0.;
+ F1inc = 0.;
+ F0max = 0.;
+ F1max = 0.;
+ return true;
+}
+
+void RTTYDemodulator::ProcessInput ( double *input, double * )
+{
+ char c1;
+ int i, j, count;
+ int StartBitCount, StartBitLength, StartBit2Lead;
+ int StopBit2Count;
+ int actSample;
+// int Filtered[RESULTLENGTH];
+// complex<double> omegaF0[RESULTLENGTH],omegaF1[RESULTLENGTH];
+ int Filtered[RESULTLENGTHDOWN];
+ double omegaF0[RESULTLENGTHDOWN], omegaF1[RESULTLENGTHDOWN];
+ double f0sum, f1sum;
+ double zf0sum, zf1sum, StartBitValue;
+
+ count = 0;
+
+// Calculating StopbitlengthStopBitLength
+ switch ( extraParameter.stopbits )
+ {
+ case One:
+ StopBitLength = NUMBEROFPROBES;
+ break;
+ case Onepoint5:
+ StopBitLength = ( 3 * NUMBEROFPROBES ) / 2;
+ break;
+ case Two:
+ StopBitLength = 2 * NUMBEROFPROBES;
+ break;
+ }
+
+ while ( ( count + RESULTLENGTH ) < BUF_SIZE )
+ {
+ for ( i = filteredSamples;i < RESULTLENGTH;i++ )
+ pIn[i] = complex<double> ( input[count++], 0. );
+ filteredSamples = 0;
+ fftw_execute ( pforward );
+ execFilter();
+ downmix ( pResultF0, pResultF1, RESULTLENGTH, Filtered, omegaF0, omegaF1 );
+ actSample = 0;
+ while ( actSample < RESULTLENGTHDOWN )
+ {
+ if ( ( BufferCount < SAMPLEBUFFERLENGTH ) )
+ {
+ while ( ( BufferCount < SAMPLEBUFFERLENGTH ) && ( actSample < RESULTLENGTHDOWN ) )
+ {
+ BufferCount++;
+ Demod[BufferPointer] = Filtered[actSample];
+ SF0[BufferPointer] = omegaF0[actSample];
+ SF1[BufferPointer] = omegaF1[actSample];
+ if ( !extraParameter.reverse )
+ {
+ Demod[BufferPointer] = -Demod[BufferPointer];
+ SF0[BufferPointer] = omegaF1[actSample];
+ SF1[BufferPointer] = omegaF0[actSample];
+ }
+ BufferPointer++;
+ BufferPointer = BufferPointer % SAMPLEBUFFERLENGTH;
+ actSample ++;
+ } // End of filling CharacterData
+ }
+ while ( BufferCount == SAMPLEBUFFERLENGTH )
+ {
+ switch ( Status ) // Now let's analyze the data
+ {
+ case WaitingForMark: // Waiting for Stopbit, previous state undefined
+ // Check, if we are possibly at the beginning of a stop bit
+ i = 0;
+ while ( ( i < BufferCount ) && ( Demod[ ( BufferPointer + i ) % SAMPLEBUFFERLENGTH] < 0 ) )
+ i++;
+ if ( i == 0 ) // At the beginning
+ {
+ StopBit1Count = 0;
+ f0sum = 0.;
+ f1sum = 0.;
+ StartBitLead = 0;
+ while ( i < StopBitLength )
+ {
+
+ f0sum += SF0[ ( BufferPointer + i ) % SAMPLEBUFFERLENGTH];
+ f1sum += SF1[ ( BufferPointer + i ) % SAMPLEBUFFERLENGTH];
+ if ( Demod[ ( BufferPointer + i++ ) % SAMPLEBUFFERLENGTH] > 0 )
+ {
+ StopBit1Count++;
+ StartBitLead = 0;
+ }
+ else
+ StartBitLead++;
+ }
+ zf0sum = abs ( f0sum );
+ zf1sum = abs ( f1sum );
+ StopBit1Value = zf1sum - zf0sum;
+ if ( StartBitLead > 2 )
+ StartBitLead = 2;
+ if ( ( StopBit1Count > StopBitLength / 2 ) || ( StopBit1Value > 0 ) )
+ Status = WaitingForSpace;
+ else
+ BufferCount -= ( StopBitLength - StopBit1Count );
+ }
+ else // Refill the buffer
+ BufferCount -= i;
+ break;
+
+ case WaitingForSpace: // Stopbit seems to be found, now waiting for transition
+ // i = StopBitLength ;
+ i = StopBitLength - StartBitLead;
+ while ( ( i < SAMPLEBUFFERLENGTH ) && ( Demod[ ( BufferPointer + i ) % SAMPLEBUFFERLENGTH ] > 0 ) )
+ i++;
+ if ( i == SAMPLEBUFFERLENGTH )
+ {
+ BufferCount = StopBitLength; // No Space found, keep only StopBitLength Samples
+ CalcQuality((float)0.);
+ }
+ else
+ {
+ Status = CheckingStartBit;
+ // i = i - StopBitLength;
+ // i = i - StopBit1Count;
+ i = i - StopBitLength + StartBitLead;
+ if ( ( StartBitLead == 0 ) && ( i > 2 ) )
+ i--;
+ BufferCount -= i; // Refill buffer
+ }
+ break;
+
+ case CheckingStartBit:
+ // j = StopBitLength + BufferPointer;
+ j = StopBitLength - StartBitLead + BufferPointer;
+ StartBitCount = 0;
+ StartBitLength = NUMBEROFPROBES;
+ f0sum = 0.;
+ f1sum = 0.;
+ for ( i = 0; i < NUMBEROFPROBES; i++ )
+ {
+ f0sum += SF0[ ( i + j ) % SAMPLEBUFFERLENGTH];
+ f1sum += SF1[ ( i + j ) % SAMPLEBUFFERLENGTH];
+ if ( Demod[ ( i + j ) % SAMPLEBUFFERLENGTH] < 0 )
+ StartBitCount++;
+ }
+ zf0sum = abs ( f0sum );
+ zf1sum = abs ( f1sum );
+ StartBitValue = zf1sum - zf0sum;
+ CalcQuality(abs(StartBitValue)/(zf0sum+zf1sum));
+ Status = CheckingStopBits;
+ /**
+ if ( (StartBitCount > NUMBEROFPROBES/2) || ( zf0sum > zf1sum))
+ Status = CheckingStopBits;
+ else
+ {
+ Status = WaitingForMark; // Was'nt the correct start bit
+ BufferCount -= StopBitLength;
+ }
+ **/
+ break;
+
+ case CollectingByte:
+ c1 = 0;
+ for ( i = 0;i < NumberOfBits; i++ )
+ {
+ int j1, BitCount;
+ j = ( BufferPointer + StopBitLength - StartBitLead + StartBitLength + i * NUMBEROFPROBES ) % SAMPLEBUFFERLENGTH;
+ // j=(BufferPointer + StopBit1Count + StartBitLength + i * NUMBEROFPROBES ) % SAMPLEBUFFERLENGTH;
+ BitCount = 0;
+ f0sum = 0.;
+ f1sum = 0.;
+ for ( j1 = j;j1 < j + NUMBEROFPROBES; j1++ )
+ {
+
+ if ( Demod[j1 % SAMPLEBUFFERLENGTH] > 0 )
+ BitCount++;
+ f1sum += SF1[ j1 % SAMPLEBUFFERLENGTH];
+ f0sum += SF0[ j1 % SAMPLEBUFFERLENGTH];
+
+ }
+ zf0sum = abs ( f0sum );
+ zf1sum = abs ( f1sum );
+ CalcQuality(abs(zf0sum-zf1sum)/(zf0sum+zf1sum));
+ // if ( BitCount > NUMBEROFPROBES/2 )
+ // if ( (zf1sum > zf0sum) || ( BitCount > NUMBEROFPROBES/2 ) )
+ if ( zf1sum > zf0sum )
+ c1 |= ( 1 << i );
+ }
+ if ( ( c1 > 0 ) && ( !Squelch || ( Squelch && ( ( unsigned int ) ( 100.*ave1 ) > CDemodulator::Threshold ) ) ) )
+ {
+ c1 = baudot_code ( c1 );
+ if ( c1 > 0 ) // FIGS or LTRS result in c1 = 0 !
+ emit newSymbol ( c1 );
+ }
+
+
+ if ( extraParameter.parity != None )
+ Status = CheckingParity;
+ else
+ {
+ StopBit1Value = zf1sum - zf0sum;
+ /**
+ if ( (StopBit2Count > (StopBitLength*2)/3)
+ ||(StopBit1Count > (StopBitLength*2)/3)
+ ||(StartBitCount > (StartBitLength*2)/3) )
+ **/
+ if ( ( StopBit2Count > ( StopBitLength*2 ) / 3 ) || ( StopBit1Value > 0 ) )
+ Status = WaitingForSpace;
+ else
+ // Status=WaitingForMark;
+ Status = CheckingStartBit;
+ BufferCount -= ( StopBitLength + StartBitLength - StartBitLead + 5 * NUMBEROFPROBES );
+ StartBitLead = StartBit2Lead;
+ StopBit1Count = StopBit2Count;
+
+ }
+ break;
+
+ case CheckingParity: // Here we need BitsInData
+ break;
+
+ case CheckingStopBits:
+ f0sum = 0.;
+ f1sum = 0.;
+
+ StopBit2Count = 0;
+ StartBit2Lead = 0;
+ j = BufferPointer + StopBitLength + StartBitLength - StartBitLead + NumberOfBits * NUMBEROFPROBES;
+ // j = BufferPointer+StopBit1Count + StartBitLength + NumberOfBits*NUMBEROFPROBES;
+ for ( i = 0; i < StopBitLength;i++ )
+ {
+ f0sum += SF0[ ( j + i ) % SAMPLEBUFFERLENGTH];
+ f1sum += SF1[ ( j + i ) % SAMPLEBUFFERLENGTH];
+
+ if ( Demod[ ( j+i ) %SAMPLEBUFFERLENGTH] > 0 )
+ {
+ StopBit2Count++;
+ StartBit2Lead = 0;
+ }
+ else
+ StartBit2Lead++;
+ }
+ if ( StartBit2Lead > 2 )
+ StartBit2Lead = 2;
+ zf1sum = abs ( f1sum );
+ zf0sum = abs ( f0sum );
+ CalcQuality(abs(zf0sum-zf1sum)/(zf0sum+zf1sum));
+ if ( ( ( ( StopBit1Count > ( 2* StopBitLength ) / 3 ) || ( StopBit1Value > 0 ) )
+ &&
+ ( ( StartBitCount > ( 2* NUMBEROFPROBES ) / 3 ) || ( StartBitValue < 0 ) ) )
+ ||
+ ( ( ( StartBitCount > ( 2* NUMBEROFPROBES ) / 3 ) || ( StartBitValue < 0 ) )
+ &&
+ ( ( StopBit2Count > ( 2* StopBitLength ) / 3 ) || ( zf1sum > zf0sum ) ) ) )
+ Status = CollectingByte;
+ else
+ {
+ Status = WaitingForMark;
+ BufferCount -= ( StopBitLength - StopBit1Count + 1 );
+ }
+ break;
+ } // end of switch
+ }
+ }
+ }
+ if ( count < BUF_SIZE )
+ {
+ filteredSamples = 0;
+ for ( i = count;i < BUF_SIZE;i++ )
+ pIn[filteredSamples++] = complex<double> ( input[i], 0. );
+ }
+ else filteredSamples = 0;
+
+}
+void RTTYDemodulator::setRxFrequency ( double freq )
+{
+ if ( freq != RxFrequency )
+ {
+ RxFrequency = freq;
+ F0 = PI2 * ( RxFrequency ) / SampleRate;
+ F1 = PI2 * ( RxFrequency + extraParameter.offset ) / SampleRate;
+ setFilter ( RxFrequency, RxFrequency + extraParameter.offset );
+ }
+}
+void RTTYDemodulator::CalcQuality ( float x )
+{
+ ave2 = ave1;
+ ave1 = 0.95 * ave1 + 0.05 * x;
+// ave1 = 0.7*ave1 + 0.25 *ave2 + 0.05 *x;
+}
+///void RTTYDemodulator::CalcQuality ( int pointer )
+///{
+/// ave2 = ave1;
+/// float sum, diff;
+/// pointer = pointer % SAMPLEBUFFERLENGTH;
+///
+/////if ( sum > 0.1 )
+/// ave1 = 0.7 * ave1 + 0.25 * ave2 + 0.05 * diff / sum;
+/////else
+///// ave1 = 0.5*ave1 + 0.3 *ave2;
+///}
+
+int RTTYDemodulator::getSquelchValue()
+{
+ return ( int ) ( 100.*ave1 );
+}
+
+double RTTYDemodulator::get2RxFrequency()
+{
+ return RxFrequency + extraParameter.offset;
+
+}
+void RTTYDemodulator::setParameter ( RxTxParameterType Type, void *Value )
+{
+ switch ( Type )
+ {
+ case Reverse:
+ extraParameter.reverse = * ( bool * ) Value;
+ break;
+ case Offset:
+ extraParameter.offset = * ( int * ) Value;
+ break;
+ case Parity:
+ extraParameter.parity = * ( Paritaet * ) Value;
+ break;
+ case Extra:
+ extraParameter = * ( ExtraParameter * ) Value;
+ break;
+ default:
+ break;
+ }
+}
+void *RTTYDemodulator::getParameter ( RxTxParameterType Type )
+{
+ switch ( Type )
+ {
+ case Reverse:
+ return ( void * ) &extraParameter.reverse;
+ break;
+ case Offset:
+ return ( void * ) &extraParameter.offset;
+ break;
+ case Parity:
+ return ( void * ) &extraParameter.parity;
+ break;
+ case Extra:
+ return ( void * ) &extraParameter;
+ break;
+ default:
+ return 0;
+ break;
+ }
+}
+void *RTTYDemodulator::getBuffer()
+{
+ return ( void * ) 0;
+}
+AfcMode RTTYDemodulator::AfcProperties()
+{
+ return Wide;
+}
+void RTTYDemodulator::setFilter ( double freq0, double freq1 )
+{
+ double x0, norm;
+ int FilterLength, i;
+ FilterLength = FFTFILTERLENGTH;
+ double coeffs[FFTLENGTH];
+
+// x0 = ( PI2 * 15. ) / SampleRate;
+ x0 = ( PI2 * 30. ) / SampleRate;
+ for ( i = FilterLength;i < FFTLENGTH;i++ )
+ coeffs[i] = 0.;
+ for ( i = 0; i < FilterLength; i++ )
+ {
+ if ( i != ( FilterLength - 1 ) / 2 )
+ coeffs[i] = sin ( x0 * ( i - ( FilterLength - 1 ) / 2 ) ) / ( i - ( FilterLength - 1 ) / 2 );
+ else
+ coeffs[i] = x0;
+ coeffs[i] *= ( 0.42 - 0.5 * cos ( ( PI2 * i ) / ( FilterLength - 1 ) )
+ + 0.08 * cos ( ( PI2 * ( i + i ) ) / ( FilterLength - 1 ) ) );
+ }
+ norm = 0.;
+ for ( i = 0;i < FilterLength;i++ )
+ norm += coeffs[i];
+ norm = ( norm * FilterLength ) / 10.;
+ for ( i = 0;i < FilterLength;i++ )
+ coeffs[i] /= norm;
+ for ( i = 0;i < FFTLENGTH;i++ )
+ pFilterIn[i] = coeffs[i] * exp ( complex<double> ( 0., PI2 * freq1 / SampleRate * ( i - ( FilterLength - 1 ) / 2 ) ) );
+ for ( i = FilterLength;i < FFTLENGTH;i++ )
+ pFilterIn[i] = complex<double> ( 0., 0. );
+
+ fftw_execute ( pfilter );
+ memcpy ( pFilterF1, pFilterF0, FFTLENGTH*sizeof ( complex<double> ) );
+
+ for ( i = 0;i < FFTLENGTH;i++ )
+ pFilterIn[i] = coeffs[i] * exp ( complex<double> ( 0., PI2 * freq0 / SampleRate * ( i - ( FilterLength - 1 ) / 2 ) ) );
+ fftw_execute ( pfilter );
+}
+void RTTYDemodulator::execFilter()
+{
+ int i, overlapLength;
+ overlapLength = FFTFILTERLENGTH - 1;
+
+ for ( i = 0; i < FFTLENGTH;i++ )
+ {
+ pOutF1[i] = pOutF0[i] * pFilterF1[i];
+ pOutF0[i] *= pFilterF0[i];
+ }
+ fftw_execute ( pbackwardF0 );
+ fftw_execute ( pbackwardF1 );
+ for ( i = 0;i < overlapLength;i++ )
+ {
+ pResultF0[i] += pOverlapF0[i];
+ pResultF1[i] += pOverlapF1[i];
+ }
+ memcpy ( pOverlapF0, &pResultF0[RESULTLENGTH], sizeof ( fftw_complex ) * overlapLength );
+ memcpy ( pOverlapF1, &pResultF1[RESULTLENGTH], sizeof ( fftw_complex ) * overlapLength );
+}
+void RTTYDemodulator::downmix ( complex<double> * z0, complex<double> *z1, int anzahl, int *y,
+ double *omegaF0, double *omegaF1 )
+{
+ int i, j, k;
+ complex<double> sumf0, sumf1, zz0, zz1;
+#define C1 0.8 /// 1. 0.1 0.7 , 0.775 0.1 0.7 , 0.8 0.08 0.575
+//#define C3 0.05
+#define C3 0.01
+ double norm;
+ k = 0;
+ for ( i = 0;i < anzahl; i += DISTANCE )
+ {
+ sumf0 = 0.;
+ sumf1 = 0.;
+ for ( j = i;j < i + DISTANCE;j++ )
+ {
+ norm = abs ( z0[j] + z1[j] );
+// zz0 = ( z0[j] * exp ( complex<double> ( 0., -F0inc ) ) / norm ) ;
+// zz1 = ( z1[j] * exp ( complex<double> ( 0., -F1inc ) ) / norm ) ;
+ z0[j] *= exp ( complex<double> ( 0., -F0inc ));
+ zz0 = z0[j]/ norm ;
+ sumf0 += zz0;
+ z1[j] *= exp ( complex<double> ( 0., -F1inc ));
+ zz1 = z1[j]/ norm ;
+ sumf1 += zz1;
+
+ F0inc += F0;
+ if ( F0inc > PI2 )
+ F0inc -= PI2;
+ F1inc += F1;
+ if ( F1inc > PI2 )
+ F1inc -= PI2;
+ }
+ if ( F0max < abs ( zz0 ) )
+ F0max = ( 1. - C1 ) * F0max + C1 * abs ( zz0 );
+ else
+ F0max = ( 1. - C3 ) * F0max - C3 * abs ( zz0 );
+ if ( F1max < abs ( zz1 ) )
+ F1max = ( 1. - C1 ) * F1max + C1 * abs ( zz1 );
+ else
+ F1max = ( 1. - C3 ) * F1max - C3 * abs ( zz1 );
+ if ( ( abs ( sumf0 ) - 0.5 * F0max ) > ( abs ( sumf1 ) - 0.5*F1max ) )
+ y[k] = -1;
+ else
+ y[k] = 1;
+
+ omegaF0[k] = ( abs ( sumf0 ) - 0.5 * F0max );
+ omegaF1[k++] = ( abs ( sumf1 ) - 0.5 * F1max );
+ }
+}
+
+
diff --git a/src/rttydemodulator.h b/src/rttydemodulator.h
new file mode 100644
index 0000000..aa9965a
--- /dev/null
+++ b/src/rttydemodulator.h
@@ -0,0 +1,120 @@
+/***************************************************************************
+ rtty2demodulator.h - description
+ -------------------
+ begin : Mon Jun 4 2001
+ copyright : (C) 2001 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifndef RTTYDEMODULATOR_H
+#define RTTYDEMODULATOR_H
+
+#define DISTANCE 22
+#define NUMBEROFPROBES 11 //242 // (11025 / 45.45 )
+
+#define SAMPLEBUFFERLENGTH 120 // Mindestens (1.5 Stop + 1Start + NumberOfBits Data +1.5 Stop) * NUMBEROFPROBES
+#define MaxSamplestoProcess 4096 // >=4096 / Distance
+
+#define FFTLENGTH 4096 //2048
+#define FFTFILTERLENGTH 511 //255
+#define RESULTLENGTH 3586 //1794 // 5382 FFTLENGTH-FFTFILTERLENGTH+1
+#define RESULTLENGTHDOWN 163 // RESULTLENGTH/DISTANCE
+
+#include "cdemodulator.h"
+#include <complex>
+#include "constants.h"
+#include "fftw3.h"
+using namespace std;
+/**Decodes RTTY
+ *@author Volker Schroer
+ */
+
+class RTTYDemodulator : public CDemodulator {
+public:
+ RTTYDemodulator();
+ ~RTTYDemodulator();
+
+/** Prozess the input */
+ void ProcessInput(double * input, double *);
+ int getSquelchValue();
+ bool Init(double,int);
+ virtual double get2RxFrequency();
+ virtual void setParameter(RxTxParameterType,void * );
+ virtual void *getParameter(RxTxParameterType);
+ virtual void *getBuffer();
+ AfcMode AfcProperties();
+ void setFilter(double freq, double bandwidth);
+ void execFilter();
+ void downmix(complex<double> *,complex<double> *, int,int *,double *,double *);
+
+public slots: // Public slots
+/** Set RxFrequencies for RTTY */
+ void setRxFrequency(double);
+
+private: //Private Variables
+ enum StateOfReception { WaitingForMark,WaitingForSpace,
+ CheckingStartBit,CollectingByte,
+ CheckingParity, CheckingStopBits};
+
+int Demod[SAMPLEBUFFERLENGTH];
+double SF0[SAMPLEBUFFERLENGTH],SF1[SAMPLEBUFFERLENGTH];
+
+double F0,F1,F0inc,F1inc;
+double F0max,F1max;
+
+int BufferPointer;
+int BufferCount;
+/** Pointer for storing Data in the ellipse Display **/
+
+
+/** Status of Shift */
+bool ShiftOn;
+
+/** Baudrate */
+float Baudrate;
+
+/** Samples per bit */
+
+unsigned int NumberOfBits;
+/** Length of first Stopbit can't be local, as it might cross
+ input buffer boundary **/
+int StopBitLength,StopBit1Count,StartBitLead;
+double StopBit1Value;
+/** Status of reception*/
+StateOfReception Status;
+
+
+/** Look at FSKDemodulator **/
+unsigned int SymbolLength;
+
+/** has detected Frequency changed ? */
+bool FrequencyChanged;
+
+/** Variables for Squelch computing */
+float ave1,ave2;
+ // Some extra paramters
+ ExtraParameter extraParameter;
+
+/** Variables for Fast FFT Filtering ( BP ) **/
+fftw_plan pforward,pbackwardF0,pbackwardF1,pfilter;
+complex<double> *pIn,*pOutF0,*pOutF1,*pFilterF0,*pFilterF1,*pFilterIn,*pResultF0,*pResultF1,*pOverlapF0,*pOverlapF1;
+int filteredSamples;
+private: // Private methods
+ /** returns the asci char coresponding to the baudot code */
+ char baudot_code(char);
+
+ /** Calc the quality of the signal for squelch */
+ ///void CalcQuality(int);
+ void CalcQuality(float);
+ complex<double> delayZ;
+ };
+
+#endif
diff --git a/src/rttymodulator.cpp b/src/rttymodulator.cpp
new file mode 100644
index 0000000..58c26a3
--- /dev/null
+++ b/src/rttymodulator.cpp
@@ -0,0 +1,470 @@
+/***************************************************************************
+ rttymodulator.cpp - description
+ -------------------
+ begin : Tue Aug 21 2001
+ copyright : (C) 2001 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * based on the work of Moe Wheatly, AE4JY *
+ ***************************************************************************/
+
+#include "rttymodulator.h"
+//#include "parameter.h"
+#include "ctxbuffer.h"
+
+extern Parameter settings;
+
+RTTYModulator::RTTYModulator(int FS,double frequency,CTxBuffer *TxBuffer) : CModulator(FS,TxBuffer)
+
+{
+Baudrate=45;
+NumberofStopBits=Onepoint5;
+SamplesPerBit=SampleRate/Baudrate;
+f0=frequency;
+f1=frequency+170.;
+xr=1.0;
+xi=0.0;
+dr[0]=cos(f0*2.0*M_PI/SampleRate);
+di[0]=sin(f0*2.0*M_PI/SampleRate);
+dr[1]=cos(f1*2.0*M_PI/SampleRate);
+di[1]=sin(f1*2.0*M_PI/SampleRate);
+
+
+
+NxSamples=SamplesPerBit;
+actBit=0; // Startbit
+BitsPerChar = 5;
+BitinChar=0;
+actChar=0;
+status=TX_PREAMBLE_STATE;
+
+actCharacterStatus=IGNORE;
+secondchar =0;
+
+//Initialize ExtraParameter
+extraParameter.stopbits=Onepoint5;
+extraParameter.parity=None;
+extraParameter.reverse=true;
+extraParameter.offset=170;
+}
+RTTYModulator::~RTTYModulator()
+{
+
+}
+
+int RTTYModulator::CalcSignal(double *data,int BUFSIZE)
+{
+int i;
+for(i=0;i<BUFSIZE;i++)
+{
+ if ( NxSamples >= SamplesPerBit) // get next bit , NxSamples will be reset in getNextBit
+ actBit = getNextBit();
+ if ( status == TX_END_STATE)
+ {
+ if (i >0) i--;
+ return -i;
+ }
+ // Calculate next Sample
+ data[i] = calcNextSample(actBit);
+ NxSamples++;
+}
+return BUFSIZE;
+}
+
+int RTTYModulator::getNextBit()
+{
+int bit;
+
+NxSamples =0;
+switch(status)
+ {
+ case TX_PREAMBLE_STATE:
+ bit = 1;
+// if (BitinChar++ >= Baudrate)
+ if (BitinChar++ >= 1)
+ {
+ status = TX_SENDING_STATE;
+ TX_Status = Startbit;
+ actChar = getChar();
+ if (actChar < 0 )
+ {
+ if ( actChar == TXOFF_CODE )
+ status = TX_END_STATE;
+ else // No character to transmit at the moment
+ TX_Status = WaitingforChar;
+ }
+ }
+ break;
+ case TX_SENDING_STATE:
+ switch(TX_Status)
+ {
+ case WaitingforChar:
+ actChar = getChar();
+ bit = 1;
+ if ( actChar < 0 )
+ {
+ if ( actChar == TXOFF_CODE )
+ status = TX_END_STATE;
+ else
+ TX_Status = Startbit;
+ actChar = 0;
+ break;
+ }
+ else
+ TX_Status = Startbit; // We got a char to transmit, so start with startbit
+ // direct
+ case Startbit:
+ bit=0;
+ BitinChar = 0;
+ TX_Status = SendChar;
+ break;
+ case SendChar:
+ if (BitinChar < BitsPerChar )
+ {
+ bit = actChar & 1;
+ BitinChar++;
+ actChar >>=1;
+ }
+ if (BitinChar == BitsPerChar)
+ TX_Status = Stopbit;
+ break;
+ case Stopbit:
+ switch (NumberofStopBits)
+ {
+ case One:
+ NxSamples=0;
+ break;
+ case Onepoint5:
+ NxSamples=-SamplesPerBit/2;
+ break;
+ case Two:
+ NxSamples= - SamplesPerBit;
+ break;
+ }
+/// actChar = getChar();
+ bit = 1;
+/// if ( actChar == TXOFF_CODE )
+/// status = TX_END_STATE;
+/// else
+/// TX_Status = Startbit;
+ TX_Status = WaitingforChar;
+
+ break;
+ }
+ break;
+// case TX_POSTAMBLE_STATE:
+// break;
+ case TX_TUNE_STATE:
+ actChar = getChar();
+ bit =0;
+ if ( actChar == TXOFF_CODE)
+ status = TX_END_STATE;
+ break;
+ case TX_END_STATE:
+ bit=1;
+ break;
+
+
+ }
+
+
+return bit;
+}
+double RTTYModulator::calcNextSample(unsigned int bit)
+{
+double temp;
+temp = xr *dr[bit] - xi*di[bit];
+xi = xr *di[bit] + xi*dr[bit];
+xr = temp;
+temp = 2.0 -(xr*xr+xi*xi);
+xr *=temp;
+xi *=temp;
+
+return xr;
+}
+
+int RTTYModulator::Char2Baudot(int character)
+{
+int value;
+static const char symbols[128]=
+ {
+ 0x00, // NULL 0
+ 0x00, // SOH undefined 1
+ 0x00, // STX " 2
+ 0x00, // ETX " 3
+ 0x00, // EOT " 4
+ 0x09, // ENQ 5
+ 0x00, // ACK undefined 6
+ 0x0A, // BEL 7
+ 0x08, // BS ? 8
+ 0x00, // HT undefined 9
+ 0x02, // LF 10
+ 0x00, // VT undefined 11
+ 0x00, // FF " 12
+ 0x08, // CR 13
+ 0x00, // SO undefined 14
+ 0x00, // SI " 15
+ 0x00, // DLE undefined 16
+ 0x00, // DC1 " 17
+ 0x00, // DC2 " 18
+ 0x00, // DC3 " 19
+ 0x00, // DC4 " 20
+ 0x00, // NAK " 21
+ 0x00, // SYN " 22
+ 0x00, // ETB " 23
+ 0x00, // CAN " 24
+ 0x00, // EM " 25
+ 0x00, // SUB " 26
+ 0x00, // ESC " 27
+ 0x00, // FS " 28
+ 0x00, // GS " 29
+ 0x00, // RS " 30
+ 0x00, // US " 31
+ 0x04, // SPACE 32
+ 0x00, // ! undefined 33
+ 0x11, // " 34
+ 0x14, // # 35
+ 0x09, // $ 36
+ 0x00, // % undefinded 37
+ 0x00, // & " 38
+ 0x05, // ' " 39
+ 0x0f, // ( 40
+ 0x12, // ) 41
+ 0x00, // * undefined 42
+ 0x11, // + 43
+ 0x0c, // , 44
+ 0x03, // - 45
+ 0x1A, // . 46
+ 0x1d, // / 47
+ 0x16, // 0 48
+ 0x17, // 1 49
+ 0x13, // 2 50
+ 0x01, // 3 51
+ 0x0A, // 4 52
+ 0x10, // 5 53
+ 0x15, // 6 54
+ 0x07, // 7 55
+ 0x06, // 8 56
+ 0x18, // 9 57
+ 0x0E, // : 58
+ 0x1e, // ; 59
+ 0x00, // < undefined 60
+ 0x1e, // = ? 61
+ 0x00, // > undefined 62
+ 0x19, // ? 63
+ 0x00, // @ undefined 64
+ 0x03, // A 65
+ 0x19, // B 66
+ 0x0E, // C 67
+ 0x09, // D 68
+ 0x01, // E 69
+ 0x0D, // F 70
+ 0x1A, // G 71
+ 0x14, // H 72
+ 0x06, // I 73
+ 0x0b, // J 74
+ 0x0F, // K 75
+ 0x12, // L 76
+ 0x1C, // M 77
+ 0x0C, // N 78
+ 0x18, // O 79
+ 0x16, // P 80
+ 0x17, // Q 81
+ 0x0A, // R 82
+ 0x05, // S 83
+ 0x10, // T 84
+ 0x07, // U 85
+ 0x1E, // V 86
+ 0x13, // W 87
+ 0x1D, // X 88
+ 0x15, // Y 89
+ 0x11, // Z 90
+ 0x00, // [ undefined 91
+ 0x00, // \ " 92
+ 0x00, // ] " 93
+ 0x00, // ^ " 94
+ 0x00, // _ " 95
+ 0x00, // ' " 96
+ 0x03, // A 97
+ 0x19, // B 98
+ 0x0E, // C 99
+ 0x09, // D 100
+ 0x01, // E 101
+ 0x0D, // F 102
+ 0x1A, // G 103
+ 0x14, // H 104
+ 0x06, // I 105
+ 0x0b, // J 106
+ 0x0F, // K 107
+ 0x12, // L 108
+ 0x1C, // M 109
+ 0x0C, // N 110
+ 0x18, // O 111
+ 0x16, // P 112
+ 0x17, // Q 113
+ 0x0A, // R 114
+ 0x05, // S 115
+ 0x10, // T 116
+ 0x07, // U 117
+ 0x1E, // V 118
+ 0x13, // W 119
+ 0x1D, // X 120
+ 0x15, // Y 121
+ 0x11, // Z 122
+ 0x00, // { undefined 123
+ 0x00, // \ " 124
+ 0x00, // } " 125
+ 0x00, // ~ " 126
+ 0x00 // DEL " 127
+ };
+static const CharacterStatus shift[128] =
+ {
+
+ IGNORE,IGNORE,IGNORE,IGNORE, // 4* IGNORE
+ FIGS,
+ IGNORE,
+ FIGS,
+ IGNORE,IGNORE,IGNORE,IGNORE, // 26 * IGNORE
+ IGNORE,IGNORE,IGNORE,IGNORE,
+ IGNORE,IGNORE,IGNORE,IGNORE,
+ IGNORE,IGNORE,IGNORE,IGNORE,
+ IGNORE,IGNORE,IGNORE,IGNORE,
+ IGNORE,IGNORE,IGNORE,IGNORE,
+ IGNORE,IGNORE,
+ FIGS,FIGS,FIGS, // 3 * FIGS
+ IGNORE,
+ FIGS,FIGS,FIGS,FIGS, // 4 * FIGS
+ IGNORE,
+ FIGS,FIGS,FIGS,FIGS,FIGS, // 17 * FIGS
+ FIGS,FIGS,FIGS,FIGS,FIGS,
+ FIGS,FIGS,FIGS,FIGS,FIGS,
+ FIGS,FIGS,
+ IGNORE,
+ FIGS,
+ IGNORE,
+ FIGS,
+ IGNORE,
+ LTRS,LTRS,LTRS,LTRS, //26 * LTRS
+ LTRS,LTRS,LTRS,LTRS,
+ LTRS,LTRS,LTRS,LTRS,
+ LTRS,LTRS,LTRS,LTRS,
+ LTRS,LTRS,LTRS,LTRS,
+ LTRS,LTRS,LTRS,LTRS,
+ LTRS,LTRS,
+ IGNORE,IGNORE,IGNORE,IGNORE, // 6* IGNORE
+ IGNORE,IGNORE,
+ LTRS,LTRS,LTRS,LTRS, // 26 * LTRS
+ LTRS,LTRS,LTRS,LTRS,
+ LTRS,LTRS,LTRS,LTRS,
+ LTRS,LTRS,LTRS,LTRS,
+ LTRS,LTRS,LTRS,LTRS,
+ LTRS,LTRS,LTRS,LTRS,
+ LTRS,LTRS,
+ IGNORE,IGNORE,IGNORE,IGNORE, // 5 * IGNORE
+ IGNORE
+
+ };
+switch (shift[character])
+ {
+ case IGNORE:
+ value = symbols[character];
+ break;
+ case LTRS:
+ if ( actCharacterStatus != LTRS)
+ {
+ value = 0x1f;
+ secondchar = symbols[character];
+ actCharacterStatus = LTRS;
+ }
+ else
+ value = symbols[character];
+ break;
+ case FIGS:
+ if ( actCharacterStatus != FIGS)
+ {
+ value = 0x1b;
+ secondchar = symbols[character];
+ actCharacterStatus = FIGS;
+ }
+ else
+ value = symbols[character];
+ break;
+
+ }
+return value;
+}
+
+int RTTYModulator::getChar()
+{
+int value;
+char ch;
+
+ch = 0;
+
+if (secondchar != 0)
+ {
+ value = secondchar;
+ secondchar = 0;
+ }
+else
+ do
+ {
+ value = Buffer->getTxChar();
+ if ( value > 0 )
+ {
+ ch = value;
+ if ( value > 127 )
+ value = value -128;
+ value = Char2Baudot(value);
+ }
+ } while ( value == 0 );
+if (ch > 0)
+ emit charSend(ch);
+return value;
+}
+
+void RTTYModulator::setParameter(RxTxParameterType Type,void *Value)
+{
+ switch (Type)
+ {
+ case Reverse:
+ extraParameter.reverse = * (bool *) Value;
+ break;
+ case Offset:
+ extraParameter.offset = * (int *) Value;
+ break;
+ case Parity:
+ extraParameter.parity = * (Paritaet *) Value;
+ break;
+ case Extra:
+ extraParameter = * (ExtraParameter *) Value;
+ break;
+ default:
+ break;
+ }
+ init();
+}
+void RTTYModulator::init()
+{
+ f1=f0+extraParameter.offset;
+ if (!extraParameter.reverse)
+ {
+ float x; //Change Mark and Space Frequency
+ x=f0;
+ f0=f1;
+ f1=x;
+ }
+ xr=1.0;
+ xi=0.0;
+ dr[0]=cos(f0*2.0*M_PI/SampleRate);
+ di[0]=sin(f0*2.0*M_PI/SampleRate);
+ dr[1]=cos(f1*2.0*M_PI/SampleRate);
+ di[1]=sin(f1*2.0*M_PI/SampleRate);
+}
diff --git a/src/rttymodulator.h b/src/rttymodulator.h
new file mode 100644
index 0000000..98960b7
--- /dev/null
+++ b/src/rttymodulator.h
@@ -0,0 +1,68 @@
+/***************************************************************************
+ rttymodulator.h - description
+ -------------------
+ begin : Tue Aug 21 2001
+ copyright : (C) 2001 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifndef RTTYMODULATOR_H
+#define RTTYMODULATOR_H
+
+#include "cmodulator.h"
+#include "parameter.h"
+#include "constants.h"
+
+/**Implementation of the RTTY Modulator
+ *@author Volker Schroer
+ */
+enum CharacterStatus {IGNORE,LTRS,FIGS};
+enum RTTYStates {Startbit,SendChar,Stopbit,WaitingforChar};
+class CTxBuffer;
+class RTTYModulator : public CModulator
+{
+Q_OBJECT
+public:
+ RTTYModulator(int FS,double freq,CTxBuffer *);
+ ~RTTYModulator();
+int CalcSignal(double *data,int BufferSize);
+virtual void setParameter(RxTxParameterType,void * );
+
+private:
+enum Status {TX_PREAMBLE_STATE,TX_SENDING_STATE,TX_END_STATE,TX_TUNE_STATE};
+
+Status status;
+unsigned int Baudrate;
+StopBits NumberofStopBits;
+int SamplesPerBit;
+unsigned int BitsPerChar;
+int NxSamples;
+unsigned int actBit;
+int actChar;
+unsigned int BitinChar;
+double xr,xi;
+double dr[2],di[2];
+
+double f0,f1; // Mark and Space frequencies
+ExtraParameter extraParameter;
+CharacterStatus actCharacterStatus;
+RTTYStates TX_Status;
+int secondchar;
+int getNextBit();
+/** int getNextBit() returns the next bit to be transmitted */
+double calcNextSample(unsigned int bit);
+/** calculates the next Sample value depending on bit */
+int Char2Baudot(int);
+int getChar();
+void init();
+};
+
+#endif
diff --git a/src/spectrumdisplay.cpp b/src/spectrumdisplay.cpp
new file mode 100644
index 0000000..00a39f7
--- /dev/null
+++ b/src/spectrumdisplay.cpp
@@ -0,0 +1,354 @@
+/***************************************************************************
+ spectrumdisplay.cpp - description
+ -------------------
+ begin : Fr March 19 2004
+ copyright : (C) 2004 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ ***************************************************************************/
+
+
+#include <QRadioButton>
+#include <QSpinBox>
+#include <QPainter>
+#include <QPixmap>
+#include <QMouseEvent>
+#include <QSplitter>
+#include "spectrumdisplay.h"
+#include "crxchannel.h"
+#include "parameter.h"
+#include "color.h"
+
+#define SPECTRUMHEIGHT 70
+#define WATERFALLHEIGHT 20
+#define LABELHEIGHT 10
+#define DISTANCE 3
+
+extern Parameter settings;
+
+SpectrumDisplay::SpectrumDisplay ( QWidget* parent ) : QFrame ( parent )
+{
+ setFrameShape( QFrame::StyledPanel);
+setFrameShadow(QFrame::Sunken );
+
+
+ MaxFreq = new QSpinBox ( parent );
+ MaxFreq->setMaximum ( 2500 );
+ MaxFreq->setMinimum ( 1300 );
+ MaxFreq->setValue ( 2500 );
+ MaxFreq->setSingleStep ( 100 );
+
+ MinFreq = new QSpinBox ( parent );
+ MinFreq->setButtonSymbols ( QSpinBox::UpDownArrows );
+ MinFreq->setMaximum ( 1200 );
+ MinFreq->setMinimum ( 100 );
+ MinFreq->setSingleStep ( 100 );
+
+Smooth=new QRadioButton(tr("Smooth"),parent);
+ languageChange();
+
+
+ inputdata = 0;
+
+
+ Phase = 0;
+ Farbe=0;
+// Connections
+ connect ( this, SIGNAL ( frequencyChanged ( int ) ), this, SLOT ( setnewFrequency ( int ) ) );
+for(int i=0; i< 1024;i++)
+ smoothedfft[i]=0.;
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+SpectrumDisplay::~SpectrumDisplay()
+{
+ // no need to delete child widgets, Qt does it all for us
+}
+
+/*
+ * Sets the strings of the subwidgets using the current
+ * language.
+ */
+void SpectrumDisplay::languageChange()
+{
+
+ MaxFreq->setSuffix ( " Hz" );
+ MinFreq->setSuffix ( " Hz" );
+}
+void SpectrumDisplay::resizeEvent ( QResizeEvent * )
+{
+
+ calculateSizeofComponents();
+ translate();
+ calcFFT();
+ plotspectrum ( false );
+
+}
+
+void SpectrumDisplay::calculateSizeofComponents()
+{
+ int xpos, ypos, width, height, innerheight, innerwidth;
+ width = this->width();
+ height =this->height();
+ /** Display **/
+ xpos = 0;
+ ypos = height * DISTANCE / 100;
+ innerwidth=width-2*this->frameWidth();
+
+ innerheight = height * SPECTRUMHEIGHT / 100;
+pdisplay =QPixmap ( innerwidth,innerheight);
+pwaterfall=QPixmap(innerwidth,height-innerheight);
+pwaterfall.fill(Qt::black);
+ /** Controlelements of the display **/
+ ypos = ypos + height + DISTANCE * height / 100;
+ innerheight = height * LABELHEIGHT / 100;
+ innerwidth = ( width - 2 * xpos ) / 4;
+ xpos = x();
+ MinFreq->setGeometry ( xpos, ypos, innerwidth, innerheight );
+//xpos=this->width()-innerwidth;
+Smooth->setGeometry(xpos+width/2-innerwidth/2,ypos,innerwidth, innerheight );
+ xpos = xpos + width - innerwidth;
+ MaxFreq->setGeometry ( xpos, ypos, innerwidth, innerheight );
+
+}
+
+// Plot Spectrum of decimated Input
+void SpectrumDisplay::plotspectrum ( bool overload )
+{
+
+
+ QPainter p;
+
+
+ int dist, y1, y2, z, ymax, xmax;
+ int minfreq, maxfreq;
+
+ double scale;
+
+ scale = ( pdisplay.height() - 15 ) / 100.;
+ minfreq = MinFreq->value();
+ maxfreq = MaxFreq->value();
+ ymax = pdisplay.height()-4; // Subtract Frame
+ dist = ymax / 10;
+ xmax = pdisplay.width();
+
+ pdisplay.fill();
+ p.begin ( &pdisplay );
+ p.setBrush ( Qt::white );
+
+//Plot Frequencylines for the different Rx- Windows
+
+ for (CRxChannel *pRx=settings.ChannelChain;pRx != 0;pRx= pRx->getNextChannel())
+ {
+
+ if ( Farbe->size() > 0)
+ {
+ int ID = pRx->getID();
+ if ( ID >= 0 && ID < Farbe->size() )
+ p.setPen(Farbe->at(ID));
+ }
+
+ // Calculate Centerfrequency Coordinates
+ z=(int)((( pRx->getRxFrequency()-minfreq)*xmax)/(maxfreq-minfreq)+0.5);
+ p.drawLine(z,0,z,ymax);
+
+ if ( (z = pRx->get2RxFrequency()) != 0 ) // RTTY demands to lines
+ {
+ z=(( z-minfreq)*xmax)/(maxfreq-minfreq);
+ p.drawLine(z,0,z,ymax);
+ }
+ }
+
+
+ if ( overload )
+ p.setPen ( Qt::red );
+ else
+ p.setPen ( Qt::blue );
+// Plot Lineal and grid
+ p.setPen ( Qt::black );
+ paintLineal ( &p, xmax, ymax );
+
+ if ( inputdata != 0 )
+ {
+ for ( int i = 1;i < xmax;i++ )
+ {
+
+ y1 = ymax - ( int ) ( scale * fftdata[i-1] ) - 15;
+ y2 = ymax - ( int ) ( scale * fftdata[i] ) - 15;
+
+ p.drawLine ( i - 1, y1, i, y2 );
+ }
+
+ if ( Phase != 0 )
+ plotVector ( &p );
+ }
+
+p.end();
+ if ( inputdata != 0 )
+ {
+ xmax = pwaterfall.width();
+
+ p.begin(&pwaterfall);
+ p.drawPixmap(0,2,pwaterfall,0,0,pwaterfall.width(),pwaterfall.height()-2);
+ for (int i=0;i<xmax;i++)
+ {
+ y1=4*fftdata[i];
+ if ( y1 > 255)
+ y1 = 255;
+ else if ( y1 < 0 )
+ y1= 0;
+ p.setPen(color[y1]);
+ p.drawPoint(i,0);
+ p.drawPoint(i,1);
+ }
+
+ p.end();
+}
+update();
+}
+void SpectrumDisplay::calcFFT()
+{
+
+ if ( inputdata == 0 )
+ return; // No data available
+ for ( int i = 0;i < pdisplay.width();i++ )
+ if( Smooth->isChecked())
+ {
+float x=( log10 ( inputdata[xtranslate[i]] + 100. ) - 2. );
+ float gain=(1. - exp(-(0.2 * x)));
+ smoothedfft[i]=smoothedfft[i]*(1.-gain) + gain *x;
+ fftdata[i] = ( int ) (20.*smoothedfft[i]);
+ }
+else
+//18.4 scales to a range from 0 - 100, as max(inputdata ) = fft_length/4 ^ 2
+ fftdata[i] = ( int ) ( 18.4 * ( log10 ( inputdata[xtranslate[i]] + 100. ) - 2. ) );
+// For Color scale should be 18.4 *2.55
+}
+
+void SpectrumDisplay::translate ( void )
+{
+ int i, to, minfreq, maxfreq, displaywidth;
+ minfreq = MinFreq->value();
+ maxfreq = MaxFreq->value();
+ to = int ( maxfreq * 1024 / 2756.25 );
+ displaywidth = pdisplay.width();
+ for ( i = 0;i < displaywidth;i++ )
+ xtranslate[i] = ( ( ( maxfreq - minfreq ) * i * to / displaywidth ) + minfreq * to ) / maxfreq;
+}
+
+void SpectrumDisplay::startPlot ( double *x, bool overload )
+{
+ inputdata = x;
+ translate();
+ calcFFT();
+ plotspectrum ( overload );
+}
+
+void SpectrumDisplay::setnewFrequency ( int position )
+{
+
+ double freq;
+ int ii;
+ ii = pdisplay.width();
+ freq = ( position * ( MaxFreq->value() - MinFreq->value() ) ) / ii + MinFreq->value();
+ settings.ActChannel->setRxFrequency ( freq );
+ emit FrequencyChanged ( freq );
+}
+
+void SpectrumDisplay::paintLineal ( QPainter* p, int xmax, int ymax )
+{
+
+ int stepfrequency;
+ float stepwidth;
+ int i, ix, NumberofFreqs, diff;
+ int y;
+ QString frequency;
+ QFontMetrics fm ( this->font() );
+ int minfreq = MinFreq->value();
+// Calcalute Frequency- Steps
+ diff = ( MaxFreq->value() - minfreq );
+ NumberofFreqs = 7;
+ while ( NumberofFreqs > 4 )
+ {
+ stepfrequency = diff / NumberofFreqs;
+ if ( (stepfrequency * NumberofFreqs) != diff )
+ NumberofFreqs--;
+ else
+ break;
+ }
+ stepwidth = float ( xmax ) / NumberofFreqs;
+
+ diff = ymax / 10;
+ y = ymax - diff;
+
+
+ for ( i = 1; i < NumberofFreqs; i++ )
+ {
+ ix = ( int ) ( i * stepwidth + 0.5 );
+ p->drawLine ( ix, y, ix, y - 3 );
+ frequency.setNum ( minfreq + stepfrequency*i );
+ ix = ix - fm.width ( frequency ) / 2;
+ p->drawText ( ix, ymax, frequency );
+
+ }
+
+// Plot Grid
+ for ( i = 1;i < 10; i++ )
+ {
+
+ p->drawLine ( 0, y, xmax, y );
+ y -= diff;
+ }
+}
+
+void SpectrumDisplay::plotVector ( QPainter *p )
+{
+ int xc, yc;
+ double mag;
+
+ xc = pdisplay.width() / 8;
+ yc = pdisplay.height() / 8;
+ p->drawEllipse ( xc, yc, 40, 40 );
+ xc = xc + 20;
+ yc = yc + 20;
+ p->setPen ( Qt::green );
+
+ for(int i=0; i< 11; i++)
+ {
+ mag=abs(Phase[i]);
+ if ( mag > 0.001)
+ p->drawLine(xc,yc,xc - (int)(20.*Phase[i].imag()/mag), yc - (int)(20.*Phase[i].real()/mag) );
+ }
+
+}
+
+void SpectrumDisplay::setPhasePointer ( std::complex<float> *p )
+{
+ Phase = p;
+}
+void SpectrumDisplay::setColorList ( QList<QColor> *c )
+{
+ Farbe=c;
+}
+void SpectrumDisplay::mousePressEvent ( QMouseEvent *e )
+
+{
+ emit frequencyChanged ( e->x() - lineWidth() );
+}
+void SpectrumDisplay::paintEvent(QPaintEvent *e)
+{
+QFrame::paintEvent(e);
+QPainter p(this);
+p.drawPixmap(frameWidth(),frameWidth(),pdisplay);
+p.drawPixmap(frameWidth(),frameWidth()+pdisplay.height()-4,pwaterfall);
+}
+
diff --git a/src/spectrumdisplay.h b/src/spectrumdisplay.h
new file mode 100644
index 0000000..d79cb11
--- /dev/null
+++ b/src/spectrumdisplay.h
@@ -0,0 +1,96 @@
+/***************************************************************************
+ spectrumdisplay.h - description
+ -------------------
+ begin : Fr March 19 2004
+ copyright : (C) 2004 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifndef SPECTRUMDISPLAY_H
+#define SPECTRUMDISPLAY_H
+
+
+
+#include <QFrame>
+#include <complex>
+#include <QColor>
+#include <QList>
+using namespace std;
+
+class QRadioButton;
+class QSpinBox;
+class QPixmap;
+class QWidget;
+
+/**
+ *@author Volker Schroer
+ */
+
+class SpectrumDisplay : public QFrame {
+ Q_OBJECT
+public:
+ SpectrumDisplay( QWidget* parent = 0);
+ ~SpectrumDisplay();
+
+ void setColorList(QList<QColor> *c);
+
+ void mousePressEvent(QMouseEvent *);
+
+
+
+public slots:
+ void startPlot(double *,bool);
+ void setPhasePointer(std::complex<float> *);
+
+
+
+protected:
+ void resizeEvent( QResizeEvent * );
+ void paintEvent(QPaintEvent *);
+
+protected slots:
+ virtual void languageChange();
+ void setnewFrequency(int);
+private:
+ void calculateSizeofComponents();
+ QSpinBox* MaxFreq;
+ QSpinBox* MinFreq;
+QRadioButton *Smooth;
+
+
+ void plotspectrum(bool);
+ /** Pointer to the Input for the FFT **/
+ double *inputdata;
+ complex<float> *Phase;
+ void translate(void);
+ void paintLineal(QPainter* ,int,int);
+ void plotVector(QPainter *p);
+ /** Results of FFT */
+ void calcFFT();
+
+ int fftdata[1024]; // Not all elements are used, it differs
+ int xtranslate[1024]; // depending on the display width
+ float smoothedfft[1024];
+// Pointer to the different Colors
+QList<QColor> *Farbe;
+
+QPixmap pdisplay; // Pixmap for Display for double buffering
+QPixmap pwaterfall; // Pixmap for Waterfall Display
+//QPixmap *pellipse; // Pixmap for crossed ellipse in RTTY(2) Mode
+
+signals:
+void FrequencyChanged(double);
+
+void frequencyChanged(int);
+
+};
+
+#endif
diff --git a/src/src.pro b/src/src.pro
new file mode 100644
index 0000000..7a284b8
--- /dev/null
+++ b/src/src.pro
@@ -0,0 +1,130 @@
+SOURCES += linpsk.cpp \
+ main.cpp \
+ macros.cpp \
+ macrowindow.cpp \
+ bpskdemodulator.cpp \
+ bpskmodulator.cpp \
+ cdemodulator.cpp \
+ cledbutton.cpp \
+ cmodulator.cpp \
+ controlpanel.cpp \
+ cpskdemodulator.cpp \
+ crecording.cpp \
+ crxchannel.cpp \
+ crxdisplay.cpp \
+ crxwindow.cpp \
+ csound.cpp \
+ csquelch.cpp \
+ ctrigger.cpp \
+ ctxbuffer.cpp \
+ ctxdisplay.cpp \
+ ctxwindow.cpp \
+ deinterleaver.cpp \
+ feccoder.cpp \
+ firfilter.cpp \
+ frequencyselect.cpp \
+ fskmodulator.cpp \
+ input.cpp \
+ interleaver.cpp \
+ mfskdemodulator.cpp \
+ mfskmodulator.cpp \
+ mfskvaricode.cpp \
+ parameter.cpp \
+ pskmodulator.cpp \
+ qpskdemodulator.cpp \
+ qpskmodulator.cpp \
+ rttydemodulator.cpp \
+ rttymodulator.cpp \
+ textinput.cpp \
+ viterbi.cpp \
+ waveinput.cpp \
+ spectrumdisplay.cpp \
+ readonlystringlistmodel.cpp \
+ processlogdata.cpp
+HEADERS += linpsk.h \
+ bpskdemodulator.h \
+ bpskmodulator.h \
+ cdemodulator.h \
+ cledbutton.h \
+ cmodulator.h \
+ color.h \
+ constants.h \
+ controlpanel.h \
+ cpskdemodulator.h \
+ crecording.h \
+ crxchannel.h \
+ crxdisplay.h \
+ crxwindow.h \
+ csound.h \
+ csquelch.h \
+ ctrigger.h \
+ ctxbuffer.h \
+ ctxdisplay.h \
+ ctxwindow.h \
+ deinterleaver.h \
+ feccoder.h \
+ fircoeffs.h \
+ firfilter.h \
+ frequencyselect.h \
+ input.h \
+ interleaver.h \
+ macros.h \
+ macrowindow.h \
+ mfskdemodulator.h \
+ mfskmodulator.h \
+ mfskvaricode.h \
+ parameter.h \
+ pskmodulator.h \
+ psktable.h \
+ qpskdemodulator.h \
+ qpskmodulator.h \
+ rttydemodulator.h \
+ rttymodulator.h \
+ textinput.h \
+ viterbi.h \
+ waveinput.h \
+ spectrumdisplay.h \
+ readonlystringlistmodel.h \
+ fskmodulator.h \
+ processlogdata.h
+TEMPLATE = app
+CONFIG += warn_on \
+ thread \
+ qt \
+ debug
+TARGET = ../bin/linpsk
+RESOURCES = application.qrc
+DESTDIR = .
+
+
+
+QMAKE_CXXFLAGS_DEBUG += -g3 \
+-O0
+QMAKE_CXXFLAGS_RELEASE += -O2
+
+
+
+QT += network
+
+INCLUDEPATH += ../gui
+
+LIBS += ../gui/libgui.a \
+-L/usr/lib64 \
+-L/usr/lib \
+-lasound \
+-lfftw3
+TARGETDEPS += ../gui/libgui.a
+
+DISTFILES += ../README ../COPYING \
+ ../ChangeLog \
+ ../asoundrc \
+ ../images/linpsk.png
+
+
+
+INSTALLS += target
+
+target.path = /usr/local/bin
+
+CONFIG -= debug
+
diff --git a/src/textinput.cpp b/src/textinput.cpp
new file mode 100644
index 0000000..93dbf5f
--- /dev/null
+++ b/src/textinput.cpp
@@ -0,0 +1,129 @@
+/***************************************************************************
+ textinput.cpp - description
+ -------------------
+ begin : Sat May 5 2001
+ copyright : (C) 2001 by Volker Schroer
+ email : DL1KSV at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#include "textinput.h"
+#include <qobject.h>
+#include <errno.h>
+#include "parameter.h"
+
+extern Parameter settings;
+extern int errno;
+
+TextInput::TextInput ( int ptt = -1 ) : Input ( ptt )
+{
+}
+TextInput::~TextInput()
+{
+}
+
+/** Opens the Device for writting, for Textfiles this means write nothing ! */
+bool TextInput::open_Device_write ( QString *errorstring )
+{
+
+ const char name[] = "Demo.out";
+ fd = open ( name, O_RDWR | O_CREAT | O_TRUNC, S_IRWXU );
+ if ( fd >= 0 )
+ return true;
+ else
+ {
+ *errorstring = QString ( QObject::tr ( "Could not open Demo.out" ) );
+ return false;
+ }
+}
+
+/** gets the samples from the device */
+int TextInput::getSamples ( double *sample, int anzahl )
+{
+ static char Buf[128];
+ int pos;
+ int i, j;
+ double x;
+
+ pos = 0;
+ j = 0;
+ while ( j < anzahl )
+ {
+ do
+ i = read ( fd, &Buf[pos], sizeof ( Buf[0] ) );
+ while ( ( i == 1 ) && ( Buf[pos++] != '\n' ) && ( pos < 128 ) );
+ if ( i == 1 )
+ {
+ if ( pos >= 127 )
+ qWarning ( "Input file has strange lines\n" );
+ pos--;
+ Buf[pos] = 0;
+ x = atof ( Buf );
+ * ( sample++ ) = x;
+ j++;
+ pos = 0;
+ }
+ else
+
+
+ lseek ( fd, 0, SEEK_SET );
+
+ } // End while
+ return j;
+}
+
+/** puts the Samples onto the Device, for a Textmode Device nothing happens */
+int TextInput::putSamples ( double *sample, int anzahl )
+{
+ int i;
+ char c;
+ QString s;
+ for ( i = 0;i < anzahl;i++ )
+ {
+
+ s.setNum ( sample[i], 'f', 6 );
+ write ( fd, s.toAscii(), s.length() );
+ c = '\n';
+ write ( fd, &c, 1 );
+ }
+ return anzahl;
+}
+
+/** Dummy */
+void TextInput::PTT ( bool )
+{
+}
+/** Dummy */
+bool TextInput::open_Device_read ( QString *errorstring )
+{
+ *errorstring = QString ( "" );
+ if ( settings.inputFilename == "" )
+ {
+ *errorstring = QString ( QObject::tr ( "Error, no Demofile selected" ) );
+ return false;
+ }
+ fd = open ( settings.inputFilename.toAscii(), O_RDONLY );
+ if ( fd > 0 )
+ return true;
+ else
+ {
+ *errorstring = QString ( QObject::tr ( "Error, Could not open Demofile " ) );
+ return false;
+ }
+
+}
+bool TextInput::close_Device()
+{
+ if ( fd >= 0 )
+ close ( fd );
+ fd = -1;
+ return true;
+}
+
diff --git a/src/textinput.h b/src/textinput.h
new file mode 100644
index 0000000..3870065
--- /dev/null
+++ b/src/textinput.h
@@ -0,0 +1,53 @@
+/***************************************************************************
+ textinput.h - description
+ -------------------
+ begin : Sat May 5 2001
+ copyright : (C) 2001 by Volker Schroer
+ email : DL1KSV at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * based on the work of Moe Wheatley, AE4JY *
+ ***************************************************************************/
+
+#ifndef TEXTINPUT_H
+#define TEXTINPUT_H
+
+#include "input.h"
+#include <stdlib.h>
+#include <sys/stat.h>
+/**Implementation of the Input Class for textfiles
+ *@author Volker Schroer
+ */
+
+class TextInput : public Input
+{
+ Q_OBJECT
+ public:
+ TextInput ( int ptt );
+ ~TextInput();
+
+ /** Opens the Device for writting **/
+ bool open_Device_write ( QString * );
+ /** Opens the Device for Reading **/
+ bool open_Device_read ( QString * );
+ /** Close the Device **/
+ virtual bool close_Device();
+ /** gets the samples from the device */
+ int getSamples ( double *sample, int anzahl );
+ /** puts the Samples onto the Device, for a Textmode Device nothing happens */
+ int putSamples ( double *sample, int anzahl );
+ /** Dummy */
+ void PTT ( bool mode );
+ /** Dummy */
+ bool setParams ( QString *errorstring );
+ private:
+ int fd;
+};
+
+#endif
diff --git a/src/viterbi.cpp b/src/viterbi.cpp
new file mode 100644
index 0000000..90b89ac
--- /dev/null
+++ b/src/viterbi.cpp
@@ -0,0 +1,135 @@
+/***************************************************************************
+ viterbi.cpp - description
+ -------------------
+ begin : Sam M�r 8 2003
+ copyright : (C) 2003 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#include "viterbi.h"
+#include <iostream>
+using namespace std;
+
+Viterbi::Viterbi(int K,unsigned int PolyA, unsigned int PolyB,const double (*d)(double *,int))
+{
+int i;
+dist = d;
+NumberofStates= 1 << K; // 2 ** K
+Metric = new double[NumberofStates/2];
+PathMem= new long long int [NumberofStates/2];
+StateTable = new unsigned int[NumberofStates];
+
+distance = new double[NumberofStates];
+bitestimate = new long long int [NumberofStates];
+
+Metric[0]=0.0;
+
+for(i=1; i < NumberofStates/2; i++)
+ Metric[i]=10000.;
+for(i=0; i < NumberofStates/2;i++)
+ {
+ PathMem[i]=0;
+ bitestimate[i]=0;
+ }
+
+/** Calculate State Table **/
+for(i=0; i < NumberofStates; i++)
+ {
+ unsigned int k,count;
+ k = PolyA & i;
+
+ count = 0;
+ while ( k > 0)
+ {
+ if ( k & 1) count ++;
+ k = k >>1;
+ }
+ StateTable[i]= (count &1) << 1;
+
+ k = PolyB & i;
+ count = 0;
+ while ( k > 0)
+ {
+ if ( k & 1) count ++;
+ k = k >>1;
+ }
+ StateTable[i]= StateTable[i] | (count & 1 ) ;
+
+ }
+CoderState=0;
+}
+Viterbi::~Viterbi()
+{
+if ( Metric !=0 )
+ delete Metric;
+if ( PathMem !=0 )
+ delete PathMem;
+if ( StateTable != 0)
+ delete StateTable;
+if (distance !=0 )
+ delete distance;
+if (bitestimate !=0 )
+ delete bitestimate;
+
+}
+int Viterbi::encode(int i)
+{
+CoderState= (( CoderState << 1 ) | ( i & 0x03)) & (NumberofStates - 1);
+
+return StateTable[CoderState];
+}
+
+void Viterbi::decode(double *c)
+{
+double min;
+int i;
+min=1.0E99;
+MinimumPath=0;
+
+
+for(i=0; i <NumberofStates; i++)
+ {
+
+ distance[i]=Metric[i/2]+(*dist)(c,StateTable[i]);
+ if ( distance[i] < min )
+ {
+ min=distance[i];
+ MinimumPath=i;
+ }
+ bitestimate[i]= (PathMem[i/2] <<1) + ( i & 1);
+ }
+MinimumPath = MinimumPath % (NumberofStates/2);
+for(i=0;i < NumberofStates/2;i++)
+ {
+ if (distance[i] < distance[i+NumberofStates/2])
+ {
+ Metric[i] = distance[i] - min;
+ PathMem[i]= bitestimate[i];
+ }
+ else
+ {
+ Metric[i] = distance[NumberofStates/2+i] - min;
+ PathMem[i]= bitestimate[NumberofStates/2+i];
+
+ }
+ }
+
+}
+int Viterbi::getbit(unsigned int i)
+{
+return ( PathMem[MinimumPath] >> i ) & 1;
+}
+int Viterbi::getbitinvers(unsigned int i)
+{
+return (~( PathMem[MinimumPath] >> i )) & 1;
+}
+
diff --git a/src/viterbi.h b/src/viterbi.h
new file mode 100644
index 0000000..5de9cc5
--- /dev/null
+++ b/src/viterbi.h
@@ -0,0 +1,50 @@
+/***************************************************************************
+ viterbi.h - description
+ -------------------
+ begin : Sam M�r 8 2003
+ copyright : (C) 2003 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef VITERBI_H
+#define VITERBI_H
+
+
+/**
+ *@author Volker Schroer
+ */
+
+class Viterbi {
+public:
+ Viterbi(int,unsigned int,unsigned int,const double (*)(double *,int));
+ ~Viterbi();
+ int encode(int);
+ void decode(double *);
+
+ int getbit(unsigned int i);
+ int getbitinvers(unsigned int i);
+
+private:
+unsigned *StateTable;
+long long int *PathMem;
+double *Metric;
+double * distance;
+long long int * bitestimate;
+int NumberofStates;
+int MinimumPath;
+unsigned int CoderState;
+const double (*dist)(double *,int);
+
+
+};
+
+#endif
diff --git a/src/viterbisoft.cpp b/src/viterbisoft.cpp
new file mode 100644
index 0000000..8a9f6a7
--- /dev/null
+++ b/src/viterbisoft.cpp
@@ -0,0 +1,953 @@
+/***************************************************************************
+ viterbi.cpp - description
+ -------------------
+ begin : Sam M�r 8 2003
+ copyright : (C) 2003 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#include "viterbisoft.h"
+#include <iostream>
+using namespace std;
+
+
+ViterbiSoft::ViterbiSoft ( const double ( *d ) ( double *, int ) )
+{
+ int i;
+ dist = d;
+ NumberofStates = NumberOfRTTYSampleStates;
+
+
+ for ( i = 0; i < NumberofStates ; i++ )
+ {
+ Metric[i] = 10000.;
+ PathMem[i][0] = Stop16;
+// bitestimate[i][0] = Stop3;
+// bitestimate[i+NumberofStates][0]=Stop3;
+ }
+ Metric[Stop16] = 0.0;
+ pathPointer = 1;
+ /** Set State Table **/
+ StateTable[0][Start1] = Start2;
+ StateTable[1][Start1] = Start2; // ??
+ StateTable[0][Start2] = Start3;
+ StateTable[1][Start2]= Start3;
+ StateTable[0][Start3]= Start4;
+ StateTable[1][Start3]= Start4;
+ StateTable[0][Start4]= Start5;
+ StateTable[1][Start4]= Start5;
+ StateTable[0][Start5]= Start6;
+ StateTable[1][Start5]= Start6;
+ StateTable[0][Start6]= Start7;
+ StateTable[1][Start6]= Start7;
+ StateTable[0][Start7]= Start8;
+ StateTable[1][Start7]= Start8;
+ StateTable[0][Start8]= Start9;
+ StateTable[1][Start8]= Start9;
+ StateTable[0][Start9]= Start10;
+ StateTable[1][Start9]= Start10;
+ StateTable[0][Start10]= Start11;
+ StateTable[1][Start10]= Start11;
+ StateTable[0][Start11] = D1_0_1;
+ StateTable[1][Start11] = D1_1_1;
+ StateTable[0][Stop1] = Stop2; // ??
+ StateTable[1][Stop1] = Stop2;
+ StateTable[0][Stop2] = Stop3; // ??
+ StateTable[1][Stop2] = Stop3;
+ StateTable[0][Stop3] = Stop4;
+ StateTable[1][Stop3] = Stop4;
+ StateTable[0][Stop4] = Stop5;
+ StateTable[1][Stop4] = Stop5;
+ StateTable[0][Stop5] = Stop6;
+ StateTable[1][Stop5] = Stop6;
+ StateTable[0][Stop6] = Stop7;
+ StateTable[1][Stop6] = Stop7;
+ StateTable[0][Stop7] = Stop8;
+ StateTable[1][Stop7] = Stop8;
+ StateTable[0][Stop8] = Stop9;
+ StateTable[1][Stop8] = Stop9;
+ StateTable[0][Stop9] = Stop10;
+ StateTable[1][Stop9] = Stop10;
+ StateTable[0][Stop10] = Stop11;
+ StateTable[1][Stop10] = Stop11;
+ StateTable[0][Stop11] = Stop12;
+ StateTable[1][Stop11] = Stop12;
+ StateTable[0][Stop12] = Stop13;
+ StateTable[1][Stop12] = Stop13;
+ StateTable[0][Stop13] = Stop14;
+ StateTable[1][Stop13] = Stop14;
+ StateTable[0][Stop14] = Stop15;
+ StateTable[1][Stop14] = Stop15;
+ StateTable[0][Stop15] = Stop16;
+ StateTable[1][Stop15] = Stop16;
+ StateTable[0][Stop16] = Start1;
+ StateTable[1][Stop16] = Stop16;
+ StateTable[0][D1_0_1] = D1_0_2;
+ StateTable[1][D1_0_1] = D1_0_2; //??
+ StateTable[0][D1_0_2] = D1_0_3;
+ StateTable[1][D1_0_2] = D1_0_3;
+ StateTable[0][D1_0_3] = D1_0_4;
+ StateTable[1][D1_0_3] = D1_0_4;
+ StateTable[0][D1_0_4] = D1_0_5;
+ StateTable[1][D1_0_4] = D1_0_5;
+ StateTable[0][D1_0_5] = D1_0_6;
+ StateTable[1][D1_0_5] = D1_0_6;
+ StateTable[0][D1_0_6] = D1_0_7;
+ StateTable[1][D1_0_6] = D1_0_7;
+ StateTable[0][D1_0_7] = D1_0_8;
+ StateTable[1][D1_0_7] = D1_0_8;
+ StateTable[0][D1_0_8] = D1_0_9;
+ StateTable[1][D1_0_8] = D1_0_9;
+ StateTable[0][D1_0_9] = D1_0_10;
+ StateTable[1][D1_0_9] = D1_0_10;
+ StateTable[0][D1_0_10] = D1_0_11;
+ StateTable[1][D1_0_10] = D1_0_11;
+StateTable[0][D1_0_11] = D2_0_1;
+StateTable[1][D1_0_11] = D2_1_1;
+ StateTable[0][D1_1_1] = D1_1_2;
+ StateTable[1][D1_1_1] = D1_1_2;
+ StateTable[0][D1_1_2] = D1_1_3;
+ StateTable[1][D1_1_2] = D1_1_3;
+ StateTable[0][D1_1_3] = D1_1_4;
+ StateTable[1][D1_1_3] = D1_1_4;
+ StateTable[0][D1_1_4] = D1_1_5;
+ StateTable[1][D1_1_4] = D1_1_5;
+ StateTable[0][D1_1_5] = D1_1_6;
+ StateTable[1][D1_1_5] = D1_1_6;
+ StateTable[0][D1_1_6] = D1_1_7;
+ StateTable[1][D1_1_6] = D1_1_7;
+ StateTable[0][D1_1_7] = D1_1_8;
+ StateTable[1][D1_1_7] = D1_1_8;
+ StateTable[0][D1_1_8] = D1_1_9;
+ StateTable[1][D1_1_8] = D1_1_9;
+ StateTable[0][D1_1_9] = D1_1_10;
+ StateTable[1][D1_1_9] = D1_1_10;
+ StateTable[0][D1_1_10] = D1_1_11;
+ StateTable[1][D1_1_10] = D1_1_11;
+StateTable[0][D1_1_11] = D2_0_1;
+StateTable[1][D1_1_11] = D2_1_1;
+ StateTable[0][D2_0_1] = D2_0_2;
+ StateTable[1][D2_0_1] = D2_0_2;
+ StateTable[0][D2_0_2] = D2_0_3;
+ StateTable[1][D2_0_2] = D2_0_3;
+ StateTable[0][D2_0_3] = D2_0_4;
+ StateTable[1][D2_0_3] = D2_0_4;
+ StateTable[0][D2_0_4] = D2_0_5;
+ StateTable[1][D2_0_4] = D2_0_5;
+ StateTable[0][D2_0_5] = D2_0_6;
+ StateTable[1][D2_0_5] = D2_0_6;
+ StateTable[0][D2_0_6] = D2_0_7;
+ StateTable[1][D2_0_6] = D2_0_7;
+ StateTable[0][D2_0_7] = D2_0_8;
+ StateTable[1][D2_0_7] = D2_0_8;
+ StateTable[0][D2_0_8] = D2_0_9;
+ StateTable[1][D2_0_8] = D2_0_9;
+ StateTable[0][D2_0_9] = D2_0_10;
+ StateTable[1][D2_0_9] = D2_0_10;
+ StateTable[0][D2_0_10] = D2_0_11;
+ StateTable[1][D2_0_10] = D2_0_11;
+StateTable[0][D2_0_11] = D3_0_1;
+StateTable[1][D2_0_11] = D3_1_1;
+ StateTable[0][D2_1_1] = D2_1_2;
+ StateTable[1][D2_1_1] = D2_1_2;
+ StateTable[0][D2_1_2] = D2_1_3;
+ StateTable[1][D2_1_2] = D2_1_3;
+ StateTable[0][D2_1_3] = D2_1_4;
+ StateTable[1][D2_1_3] = D2_1_4;
+ StateTable[0][D2_1_4] = D2_1_5;
+ StateTable[1][D2_1_4] = D2_1_5;
+ StateTable[0][D2_1_5] = D2_1_6;
+ StateTable[1][D2_1_5] = D2_1_6;
+ StateTable[0][D2_1_6] = D2_1_7;
+ StateTable[1][D2_1_6] = D2_1_7;
+ StateTable[0][D2_1_7] = D2_1_8;
+ StateTable[1][D2_1_7] = D2_1_8;
+ StateTable[0][D2_1_8] = D2_1_9;
+ StateTable[1][D2_1_8] = D2_1_9;
+ StateTable[0][D2_1_9] = D2_1_10;
+ StateTable[1][D2_1_9] = D2_1_10;
+ StateTable[0][D2_1_10] = D2_1_11;
+ StateTable[1][D2_1_10] = D2_1_11;
+StateTable[0][D2_1_11] = D3_0_1;
+StateTable[1][D2_1_11] = D3_1_1;
+ StateTable[0][D3_0_1] = D3_0_2;
+ StateTable[1][D3_0_1] = D3_0_2; // ??
+ StateTable[0][D3_0_2] = D3_0_3;
+ StateTable[1][D3_0_2] = D3_0_3;
+ StateTable[0][D3_0_3] = D3_0_4;
+ StateTable[1][D3_0_3] = D3_0_4;
+ StateTable[0][D3_0_4] = D3_0_5;
+ StateTable[1][D3_0_4] = D3_0_5;
+ StateTable[0][D3_0_5] = D3_0_6;
+ StateTable[1][D3_0_5] = D3_0_6;
+ StateTable[0][D3_0_6] = D3_0_7;
+ StateTable[1][D3_0_6] = D3_0_7;
+ StateTable[0][D3_0_7] = D3_0_8;
+ StateTable[1][D3_0_7] = D3_0_8;
+ StateTable[0][D3_0_8] = D3_0_9;
+ StateTable[1][D3_0_8] = D3_0_9;
+ StateTable[0][D3_0_9] = D3_0_10;
+ StateTable[1][D3_0_9] = D3_0_10;
+ StateTable[0][D3_0_10] = D3_0_11;
+ StateTable[1][D3_0_10] = D3_0_11;
+StateTable[0][D3_0_11] = D4_0_1; // ??
+StateTable[1][D3_0_11] = D4_1_1;
+ StateTable[0][D3_1_1] = D3_1_2;
+ StateTable[1][D3_1_1] = D3_1_2;
+ StateTable[0][D3_1_2] = D3_1_3;
+ StateTable[1][D3_1_2] = D3_1_3;
+ StateTable[0][D3_1_3] = D3_1_4;
+ StateTable[1][D3_1_3] = D3_1_4;
+ StateTable[0][D3_1_4] = D3_1_5;
+ StateTable[1][D3_1_4] = D3_1_5;
+ StateTable[0][D3_1_5] = D3_1_6;
+ StateTable[1][D3_1_5] = D3_1_6;
+ StateTable[0][D3_1_6] = D3_1_7;
+ StateTable[1][D3_1_6] = D3_1_7;
+ StateTable[0][D3_1_7] = D3_1_8;
+ StateTable[1][D3_1_7] = D3_1_8;
+ StateTable[0][D3_1_8] = D3_1_9;
+ StateTable[1][D3_1_8] = D3_1_9;
+ StateTable[0][D3_1_9] = D3_1_10;
+ StateTable[1][D3_1_9] = D3_1_10;
+ StateTable[0][D3_1_10] = D3_1_11;
+ StateTable[1][D3_1_10] = D3_1_11;
+StateTable[0][D3_1_11] = D4_0_1;
+StateTable[1][D3_1_11] = D4_1_1;
+ StateTable[0][D4_0_1] = D4_0_2;
+ StateTable[1][D4_0_1] = D4_0_2; // ??
+ StateTable[0][D4_0_2] = D4_0_3;
+ StateTable[1][D4_0_2] = D4_0_3;
+ StateTable[0][D4_0_3] = D4_0_4;
+ StateTable[1][D4_0_3] = D4_0_4;
+ StateTable[0][D4_0_4] = D4_0_5;
+ StateTable[1][D4_0_4] = D4_0_5;
+ StateTable[0][D4_0_5] = D4_0_6;
+ StateTable[1][D4_0_5] = D4_0_6;
+ StateTable[0][D4_0_6] = D4_0_7;
+ StateTable[1][D4_0_6] = D4_0_7;
+ StateTable[0][D4_0_7] = D4_0_8;
+ StateTable[1][D4_0_7] = D4_0_8;
+ StateTable[0][D4_0_8] = D4_0_9;
+ StateTable[1][D4_0_8] = D4_0_9;
+ StateTable[0][D4_0_9] = D4_0_10;
+ StateTable[1][D4_0_9] = D4_0_10;
+ StateTable[0][D4_0_10] = D4_0_11;
+ StateTable[1][D4_0_10] = D4_0_11;
+StateTable[0][D4_0_11] = D5_0_1;
+StateTable[1][D4_0_11] = D5_1_1;
+ StateTable[0][D4_1_1] = D4_1_2; // ??
+ StateTable[1][D4_1_1] = D4_1_2;
+ StateTable[0][D4_1_2] = D4_1_3;
+ StateTable[1][D4_1_2] = D4_1_3;
+ StateTable[0][D4_1_3] = D4_1_4;
+ StateTable[1][D4_1_3] = D4_1_4;
+ StateTable[0][D4_1_4] = D4_1_5;
+ StateTable[1][D4_1_4] = D4_1_5;
+ StateTable[0][D4_1_5] = D4_1_6;
+ StateTable[1][D4_1_5] = D4_1_6;
+ StateTable[0][D4_1_6] = D4_1_7;
+ StateTable[1][D4_1_6] = D4_1_7;
+ StateTable[0][D4_1_7] = D4_1_8;
+ StateTable[1][D4_1_7] = D4_1_8;
+ StateTable[0][D4_1_8] = D4_1_9;
+ StateTable[1][D4_1_8] = D4_1_9;
+ StateTable[0][D4_1_9] = D4_1_10;
+ StateTable[1][D4_1_9] = D4_1_10;
+ StateTable[0][D4_1_10] = D4_1_11;
+ StateTable[1][D4_1_10] = D4_1_11;
+StateTable[0][D4_1_11] = D5_0_1;
+StateTable[1][D4_1_11] = D5_1_1;
+ StateTable[0][D5_0_1] = D5_0_2;
+ StateTable[1][D5_0_1] = D5_0_2; // ??
+ StateTable[0][D5_0_2] = D5_0_3;
+ StateTable[1][D5_0_2] = D5_0_3;
+ StateTable[0][D5_0_3] = D5_0_4;
+ StateTable[1][D5_0_3] = D5_0_4;
+ StateTable[0][D5_0_4] = D5_0_5;
+ StateTable[1][D5_0_4] = D5_0_5;
+ StateTable[0][D5_0_5] = D5_0_6;
+ StateTable[1][D5_0_5] = D5_0_6;
+ StateTable[0][D5_0_6] = D5_0_7;
+ StateTable[1][D5_0_6] = D5_0_7;
+ StateTable[0][D5_0_7] = D5_0_8;
+ StateTable[1][D5_0_7] = D5_0_8;
+ StateTable[0][D5_0_8] = D5_0_9;
+ StateTable[1][D5_0_8] = D5_0_9;
+ StateTable[0][D5_0_9] = D5_0_10;
+ StateTable[1][D5_0_9] = D5_0_10;
+ StateTable[0][D5_0_10] = D5_0_11;
+ StateTable[1][D5_0_10] = D5_0_11;
+StateTable[0][D5_0_11] = D6_0_1; // ??
+StateTable[1][D5_0_11] = D6_1_1;
+ StateTable[0][D5_1_1] = D5_1_2; // ??
+ StateTable[1][D5_1_1] = D5_1_2;
+ StateTable[0][D5_1_2] = D5_1_3;
+ StateTable[1][D5_1_2] = D5_1_3;
+ StateTable[0][D5_1_3] = D5_1_4;
+ StateTable[1][D5_1_3] = D5_1_4;
+ StateTable[0][D5_1_4] = D5_1_5;
+ StateTable[1][D5_1_4] = D5_1_5;
+ StateTable[0][D5_1_5] = D5_1_6;
+ StateTable[1][D5_1_5] = D5_1_6;
+ StateTable[0][D5_1_6] = D5_1_7;
+ StateTable[1][D5_1_6] = D5_1_7;
+ StateTable[0][D5_1_7] = D5_1_8;
+ StateTable[1][D5_1_7] = D5_1_8;
+ StateTable[0][D5_1_8] = D5_1_9;
+ StateTable[1][D5_1_8] = D5_1_9;
+ StateTable[0][D5_1_9] = D5_1_10;
+ StateTable[1][D5_1_9] = D5_1_10;
+ StateTable[0][D5_1_10] = D5_1_11;
+ StateTable[1][D5_1_10] = D5_1_11;
+StateTable[0][D5_1_11] = D6_0_1; // ??
+StateTable[1][D5_1_11] = D6_1_1;
+
+ StateTable[0][D6_0_1] = D6_0_2;
+ StateTable[1][D6_0_1] = D6_0_2; // ??
+ StateTable[0][D6_0_2] = D6_0_3;
+ StateTable[1][D6_0_2] = D6_0_3;
+ StateTable[0][D6_0_3] = D6_0_4;
+ StateTable[1][D6_0_3] = D6_0_4;
+ StateTable[0][D6_0_4] = D6_0_5;
+ StateTable[1][D6_0_4] = D6_0_5;
+ StateTable[0][D6_0_5] = D6_0_6;
+ StateTable[1][D6_0_5] = D6_0_6;
+ StateTable[0][D6_0_6] = D6_0_7;
+ StateTable[1][D6_0_6] = D6_0_7;
+ StateTable[0][D6_0_7] = D6_0_8;
+ StateTable[1][D6_0_7] = D6_0_8;
+ StateTable[0][D6_0_8] = D6_0_9;
+ StateTable[1][D6_0_8] = D6_0_9;
+ StateTable[0][D6_0_9] = D6_0_10;
+ StateTable[1][D6_0_9] = D6_0_10;
+ StateTable[0][D6_0_10] = D6_0_11;
+ StateTable[1][D6_0_10] = D6_0_11;
+StateTable[0][D6_0_11] = D7_0_1; // ??
+StateTable[1][D6_0_11] = D7_1_1;
+ StateTable[0][D6_1_1] = D6_1_2; // ??
+ StateTable[1][D6_1_1] = D6_1_2;
+ StateTable[0][D6_1_2] = D6_1_3;
+ StateTable[1][D6_1_2] = D6_1_3;
+ StateTable[0][D6_1_3] = D6_1_4;
+ StateTable[1][D6_1_3] = D6_1_4;
+ StateTable[0][D6_1_4] = D6_1_5;
+ StateTable[1][D6_1_4] = D6_1_5;
+ StateTable[0][D6_1_5] = D6_1_6;
+ StateTable[1][D6_1_5] = D6_1_6;
+ StateTable[0][D6_1_6] = D6_1_7;
+ StateTable[1][D6_1_6] = D6_1_7;
+ StateTable[0][D6_1_7] = D6_1_8;
+ StateTable[1][D6_1_7] = D6_1_8;
+ StateTable[0][D6_1_8] = D6_1_9;
+ StateTable[1][D6_1_8] = D6_1_9;
+ StateTable[0][D6_1_9] = D6_1_10;
+ StateTable[1][D6_1_9] = D6_1_10;
+ StateTable[0][D6_1_10] = D6_1_11;
+ StateTable[1][D6_1_10] = D6_1_11;
+StateTable[0][D6_1_11] = D7_0_1; // ??
+StateTable[1][D6_1_11] = D7_1_1;
+
+ StateTable[0][D7_0_1] = D7_0_2;
+ StateTable[1][D7_0_1] = D7_0_2; // ??
+ StateTable[0][D7_0_2] = D7_0_3;
+ StateTable[1][D7_0_2] = D7_0_3;
+ StateTable[0][D7_0_3] = D7_0_4;
+ StateTable[1][D7_0_3] = D7_0_4;
+ StateTable[0][D7_0_4] = D7_0_5;
+ StateTable[1][D7_0_4] = D7_0_5;
+ StateTable[0][D7_0_5] = D7_0_6;
+ StateTable[1][D7_0_5] = D7_0_6;
+ StateTable[0][D7_0_6] = D7_0_7;
+ StateTable[1][D7_0_6] = D7_0_7;
+ StateTable[0][D7_0_7] = D7_0_8;
+ StateTable[1][D7_0_7] = D7_0_8;
+ StateTable[0][D7_0_8] = D7_0_9;
+ StateTable[1][D7_0_8] = D7_0_9;
+ StateTable[0][D7_0_9] = D7_0_10;
+ StateTable[1][D7_0_9] = D7_0_10;
+ StateTable[0][D7_0_10] = D7_0_11;
+ StateTable[1][D7_0_10] = D7_0_11;
+StateTable[0][D7_0_11] = D8_0_1; // ??
+StateTable[1][D7_0_11] = D8_1_1;
+ StateTable[0][D7_1_1] = D7_1_2; // ??
+ StateTable[1][D7_1_1] = D7_1_2;
+ StateTable[0][D7_1_2] = D7_1_3;
+ StateTable[1][D7_1_2] = D7_1_3;
+ StateTable[0][D7_1_3] = D7_1_4;
+ StateTable[1][D7_1_3] = D7_1_4;
+ StateTable[0][D7_1_4] = D7_1_5;
+ StateTable[1][D7_1_4] = D7_1_5;
+ StateTable[0][D7_1_5] = D7_1_6;
+ StateTable[1][D7_1_5] = D7_1_6;
+ StateTable[0][D7_1_6] = D7_1_7;
+ StateTable[1][D7_1_6] = D7_1_7;
+ StateTable[0][D7_1_7] = D7_1_8;
+ StateTable[1][D7_1_7] = D7_1_8;
+ StateTable[0][D7_1_8] = D7_1_9;
+ StateTable[1][D7_1_8] = D7_1_9;
+ StateTable[0][D7_1_9] = D7_1_10;
+ StateTable[1][D7_1_9] = D7_1_10;
+ StateTable[0][D7_1_10] = D7_1_11;
+ StateTable[1][D7_1_10] = D7_1_11;
+StateTable[0][D7_1_11] = D8_0_1; // ??
+StateTable[1][D7_1_11] = D8_1_1;
+
+ StateTable[0][D8_0_1] = D8_0_2;
+ StateTable[1][D8_0_1] = D8_0_2; // ??
+ StateTable[0][D8_0_2] = D8_0_3;
+ StateTable[1][D8_0_2] = D8_0_3;
+ StateTable[0][D8_0_3] = D8_0_4;
+ StateTable[1][D8_0_3] = D8_0_4;
+ StateTable[0][D8_0_4] = D8_0_5;
+ StateTable[1][D8_0_4] = D8_0_5;
+ StateTable[0][D8_0_5] = D8_0_6;
+ StateTable[1][D8_0_5] = D8_0_6;
+ StateTable[0][D8_0_6] = D8_0_7;
+ StateTable[1][D8_0_6] = D8_0_7;
+ StateTable[0][D8_0_7] = D8_0_8;
+ StateTable[1][D8_0_7] = D8_0_8;
+ StateTable[0][D8_0_8] = D8_0_9;
+ StateTable[1][D8_0_8] = D8_0_9;
+ StateTable[0][D8_0_9] = D8_0_10;
+ StateTable[1][D8_0_9] = D8_0_10;
+ StateTable[0][D8_0_10] = D8_0_11;
+ StateTable[1][D8_0_10] = D8_0_11;
+StateTable[0][D8_0_11] = D9_0_1; // ??
+StateTable[1][D8_0_11] = D9_1_1;
+ StateTable[0][D8_1_1] = D8_1_2; // ??
+ StateTable[1][D8_1_1] = D8_1_2;
+ StateTable[0][D8_1_2] = D8_1_3;
+ StateTable[1][D8_1_2] = D8_1_3;
+ StateTable[0][D8_1_3] = D8_1_4;
+ StateTable[1][D8_1_3] = D8_1_4;
+ StateTable[0][D8_1_4] = D8_1_5;
+ StateTable[1][D8_1_4] = D8_1_5;
+ StateTable[0][D8_1_5] = D8_1_6;
+ StateTable[1][D8_1_5] = D8_1_6;
+ StateTable[0][D8_1_6] = D8_1_7;
+ StateTable[1][D8_1_6] = D8_1_7;
+ StateTable[0][D8_1_7] = D8_1_8;
+ StateTable[1][D8_1_7] = D8_1_8;
+ StateTable[0][D8_1_8] = D8_1_9;
+ StateTable[1][D8_1_8] = D8_1_9;
+ StateTable[0][D8_1_9] = D8_1_10;
+ StateTable[1][D8_1_9] = D8_1_10;
+ StateTable[0][D8_1_10] = D8_1_11;
+ StateTable[1][D8_1_10] = D8_1_11;
+StateTable[0][D8_1_11] = D9_0_1; // ??
+StateTable[1][D8_1_11] = D9_1_1;
+
+ StateTable[0][D9_0_1] = D9_0_2;
+ StateTable[1][D9_0_1] = D9_0_2; // ??
+ StateTable[0][D9_0_2] = D9_0_3;
+ StateTable[1][D9_0_2] = D9_0_3;
+ StateTable[0][D9_0_3] = D9_0_4;
+ StateTable[1][D9_0_3] = D9_0_4;
+ StateTable[0][D9_0_4] = D9_0_5;
+ StateTable[1][D9_0_4] = D9_0_5;
+ StateTable[0][D9_0_5] = D9_0_6;
+ StateTable[1][D9_0_5] = D9_0_6;
+ StateTable[0][D9_0_6] = D9_0_7;
+ StateTable[1][D9_0_6] = D9_0_7;
+ StateTable[0][D9_0_7] = D9_0_8;
+ StateTable[1][D9_0_7] = D9_0_8;
+ StateTable[0][D9_0_8] = D9_0_9;
+ StateTable[1][D9_0_8] = D9_0_9;
+ StateTable[0][D9_0_9] = D9_0_10;
+ StateTable[1][D9_0_9] = D9_0_10;
+ StateTable[0][D9_0_10] = D9_0_11;
+ StateTable[1][D9_0_10] = D9_0_11;
+StateTable[0][D9_0_11] = D10_0_1; // ??
+StateTable[1][D9_0_11] = D10_1_1;
+ StateTable[0][D9_1_1] = D9_1_2; // ??
+ StateTable[1][D9_1_1] = D9_1_2;
+ StateTable[0][D9_1_2] = D9_1_3;
+ StateTable[1][D9_1_2] = D9_1_3;
+ StateTable[0][D9_1_3] = D9_1_4;
+ StateTable[1][D9_1_3] = D9_1_4;
+ StateTable[0][D9_1_4] = D9_1_5;
+ StateTable[1][D9_1_4] = D9_1_5;
+ StateTable[0][D9_1_5] = D9_1_6;
+ StateTable[1][D9_1_5] = D9_1_6;
+ StateTable[0][D9_1_6] = D9_1_7;
+ StateTable[1][D9_1_6] = D9_1_7;
+ StateTable[0][D9_1_7] = D9_1_8;
+ StateTable[1][D9_1_7] = D9_1_8;
+ StateTable[0][D9_1_8] = D9_1_9;
+ StateTable[1][D9_1_8] = D9_1_9;
+ StateTable[0][D9_1_9] = D9_1_10;
+ StateTable[1][D9_1_9] = D9_1_10;
+ StateTable[0][D9_1_10] = D9_1_11;
+ StateTable[1][D9_1_10] = D9_1_11;
+StateTable[0][D9_1_11] = D10_0_1; // ??
+StateTable[1][D9_1_11] = D10_1_1;
+
+ StateTable[0][D10_0_1] = D10_0_2;
+ StateTable[1][D10_0_1] = D10_0_2; // ??
+ StateTable[0][D10_0_2] = D10_0_3;
+ StateTable[1][D10_0_2] = D10_0_3;
+ StateTable[0][D10_0_3] = D10_0_4;
+ StateTable[1][D10_0_3] = D10_0_4;
+ StateTable[0][D10_0_4] = D10_0_5;
+ StateTable[1][D10_0_4] = D10_0_5;
+ StateTable[0][D10_0_5] = D10_0_6;
+ StateTable[1][D10_0_5] = D10_0_6;
+ StateTable[0][D10_0_6] = D10_0_7;
+ StateTable[1][D10_0_6] = D10_0_7;
+ StateTable[0][D10_0_7] = D10_0_8;
+ StateTable[1][D10_0_7] = D10_0_8;
+ StateTable[0][D10_0_8] = D10_0_9;
+ StateTable[1][D10_0_8] = D10_0_9;
+ StateTable[0][D10_0_9] = D10_0_10;
+ StateTable[1][D10_0_9] = D10_0_10;
+ StateTable[0][D10_0_10] = D10_0_11;
+ StateTable[1][D10_0_10] = D10_0_11;
+StateTable[0][D10_0_11] = D11_0_1; // ??
+StateTable[1][D10_0_11] = D11_1_1;
+ StateTable[0][D10_1_1] = D10_1_2; // ??
+ StateTable[1][D10_1_1] = D10_1_2;
+ StateTable[0][D10_1_2] = D10_1_3;
+ StateTable[1][D10_1_2] = D10_1_3;
+ StateTable[0][D10_1_3] = D10_1_4;
+ StateTable[1][D10_1_3] = D10_1_4;
+ StateTable[0][D10_1_4] = D10_1_5;
+ StateTable[1][D10_1_4] = D10_1_5;
+ StateTable[0][D10_1_5] = D10_1_6;
+ StateTable[1][D10_1_5] = D10_1_6;
+ StateTable[0][D10_1_6] = D10_1_7;
+ StateTable[1][D10_1_6] = D10_1_7;
+ StateTable[0][D10_1_7] = D10_1_8;
+ StateTable[1][D10_1_7] = D10_1_8;
+ StateTable[0][D10_1_8] = D10_1_9;
+ StateTable[1][D10_1_8] = D10_1_9;
+ StateTable[0][D10_1_9] = D10_1_10;
+ StateTable[1][D10_1_9] = D10_1_10;
+ StateTable[0][D10_1_10] = D10_1_11;
+ StateTable[1][D10_1_10] = D10_1_11;
+StateTable[0][D10_1_11] = D11_0_1; // ??
+StateTable[1][D10_1_11] = D11_1_1;
+
+ StateTable[0][D11_0_1] = D11_0_2;
+ StateTable[1][D11_0_1] = D11_0_2; // ??
+ StateTable[0][D11_0_2] = D11_0_3;
+ StateTable[1][D11_0_2] = D11_0_3;
+ StateTable[0][D11_0_3] = D11_0_4;
+ StateTable[1][D11_0_3] = D11_0_4;
+ StateTable[0][D11_0_4] = D11_0_5;
+ StateTable[1][D11_0_4] = D11_0_5;
+ StateTable[0][D11_0_5] = D11_0_6;
+ StateTable[1][D11_0_5] = D11_0_6;
+ StateTable[0][D11_0_6] = D11_0_7;
+ StateTable[1][D11_0_6] = D11_0_7;
+ StateTable[0][D11_0_7] = D11_0_8;
+ StateTable[1][D11_0_7] = D11_0_8;
+ StateTable[0][D11_0_8] = D11_0_9;
+ StateTable[1][D11_0_8] = D11_0_9;
+ StateTable[0][D11_0_9] = D11_0_10;
+ StateTable[1][D11_0_9] = D11_0_10;
+ StateTable[0][D11_0_10] = D11_0_11;
+ StateTable[1][D11_0_10] = D11_0_11;
+StateTable[0][D11_0_11] = Stop1; // ??
+StateTable[1][D11_0_11] = Stop1;
+ StateTable[0][D11_1_1] = D11_1_2; // ??
+ StateTable[1][D11_1_1] = D11_1_2;
+ StateTable[0][D11_1_2] = D11_1_3;
+ StateTable[1][D11_1_2] = D11_1_3;
+ StateTable[0][D11_1_3] = D11_1_4;
+ StateTable[1][D11_1_3] = D11_1_4;
+ StateTable[0][D11_1_4] = D11_1_5;
+ StateTable[1][D11_1_4] = D11_1_5;
+ StateTable[0][D11_1_5] = D11_1_6;
+ StateTable[1][D11_1_5] = D11_1_6;
+ StateTable[0][D11_1_6] = D11_1_7;
+ StateTable[1][D11_1_6] = D11_1_7;
+ StateTable[0][D11_1_7] = D11_1_8;
+ StateTable[1][D11_1_7] = D11_1_8;
+ StateTable[0][D11_1_8] = D11_1_9;
+ StateTable[1][D11_1_8] = D11_1_9;
+ StateTable[0][D11_1_9] = D11_1_10;
+ StateTable[1][D11_1_9] = D11_1_10;
+ StateTable[0][D11_1_10] = D11_1_11;
+ StateTable[1][D11_1_10] = D11_1_11;
+StateTable[0][D11_1_11] = Stop1; // ??
+StateTable[1][D11_1_11] = Stop1;
+
+ BitCount = 0;
+// StopBitCount = SAMPLESPERSTOPBIT;
+
+ BitTable[Start1] = 0;
+ BitTable[Start2] = 0;
+ BitTable[Start3]=0;
+ BitTable[Start4]=0;
+ BitTable[Start5]=0;
+ BitTable[Start6]=0;
+ BitTable[Start7]=0;
+ BitTable[Start8]=0;
+ BitTable[Start9]=0;
+ BitTable[Start10]=0;
+ BitTable[Start11]=0;
+
+ BitTable[ Stop1] = 1;
+ BitTable[Stop2] = 1;
+ BitTable[Stop3] = 1;
+ BitTable[Stop4] = 1;
+ BitTable[Stop5] = 1;
+ BitTable[Stop6] = 1;
+ BitTable[Stop7] = 1;
+ BitTable[Stop8] = 1;
+ BitTable[Stop9] = 1;
+ BitTable[Stop10] = 1;
+ BitTable[Stop11] = 1;
+ BitTable[Stop12] = 1;
+ BitTable[Stop13] = 1;
+ BitTable[Stop14] = 1;
+ BitTable[Stop15] = 1;
+ BitTable[Stop16] = 1;
+
+ BitTable[ D1_0_1] = 0;
+ BitTable[D1_0_2] = 0;
+ BitTable[D1_0_3] = 0;
+ BitTable[D1_0_4] = 0;
+ BitTable[D1_0_5] = 0;
+ BitTable[D1_0_6] = 0;
+ BitTable[D1_0_7] = 0;
+ BitTable[D1_0_8] = 0;
+ BitTable[D1_0_9] = 0;
+ BitTable[D1_0_10] = 0;
+ BitTable[D1_0_11] = 0;
+
+ BitTable[ D1_1_1] = 1;
+ BitTable[D1_1_2] = 1;
+ BitTable[ D1_1_3] = 1;
+ BitTable[ D1_1_4] = 1;
+ BitTable[ D1_1_5] = 1;
+ BitTable[ D1_1_6] = 1;
+ BitTable[ D1_1_7] = 1;
+ BitTable[ D1_1_8] = 1;
+ BitTable[ D1_1_9] = 1;
+ BitTable[ D1_1_10] = 1;
+ BitTable[ D1_1_11] = 1;
+
+ BitTable[ D2_0_1] = 0;
+ BitTable[D2_0_2] = 0;
+ BitTable[D2_0_3] = 0;
+ BitTable[D2_0_4] = 0;
+ BitTable[D2_0_5] = 0;
+ BitTable[D2_0_6] = 0;
+ BitTable[D2_0_7] = 0;
+ BitTable[D2_0_8] = 0;
+ BitTable[D2_0_9] = 0;
+ BitTable[D2_0_10] = 0;
+ BitTable[D2_0_11] = 0;
+
+ BitTable[ D2_1_1] = 1;
+ BitTable[D2_1_2] = 1;
+ BitTable[D2_1_3] = 1;
+ BitTable[D2_1_4] = 1;
+ BitTable[D2_1_5] = 1;
+ BitTable[D2_1_6] = 1;
+ BitTable[D2_1_7] = 1;
+ BitTable[D2_1_8] = 1;
+ BitTable[D2_1_9] = 1;
+ BitTable[D2_1_10] = 1;
+ BitTable[D2_1_11] = 1;
+
+ BitTable[ D3_0_1] = 0;
+ BitTable[D3_0_2] = 0;
+ BitTable[D3_0_3] = 0;
+ BitTable[D3_0_4] = 0;
+ BitTable[D3_0_5] = 0;
+ BitTable[D3_0_6] = 0;
+ BitTable[D3_0_7] = 0;
+ BitTable[D3_0_8] = 0;
+ BitTable[D3_0_9] = 0;
+ BitTable[D3_0_10] = 0;
+ BitTable[D3_0_11] = 0;
+
+ BitTable[ D3_1_1] = 1;
+ BitTable[D3_1_2] = 1;
+ BitTable[D3_1_3] = 1;
+ BitTable[D3_1_4] = 1;
+ BitTable[D3_1_5] = 1;
+ BitTable[D3_1_6] = 1;
+ BitTable[D3_1_7] = 1;
+ BitTable[D3_1_8] = 1;
+ BitTable[D3_1_9] = 1;
+ BitTable[D3_1_10] = 1;
+ BitTable[D3_1_11] = 1;
+
+ BitTable[D4_0_1] = 0;
+ BitTable[D4_0_2] = 0;
+ BitTable[D4_0_3] = 0;
+ BitTable[D4_0_4] = 0;
+ BitTable[D4_0_5] = 0;
+ BitTable[D4_0_6] = 0;
+ BitTable[D4_0_7] = 0;
+ BitTable[D4_0_8] = 0;
+ BitTable[D4_0_9] = 0;
+ BitTable[D4_0_10] = 0;
+ BitTable[D4_0_11] = 0;
+
+ BitTable[ D4_1_1] = 1;
+ BitTable[D4_1_2] = 1;
+ BitTable[D4_1_3] = 1;
+ BitTable[D4_1_4] = 1;
+ BitTable[D4_1_5] = 1;
+ BitTable[D4_1_6] = 1;
+ BitTable[D4_1_7] = 1;
+ BitTable[D4_1_8] = 1;
+ BitTable[D4_1_9] = 1;
+ BitTable[D4_1_10] = 1;
+ BitTable[D4_1_11] = 1;
+
+ BitTable[ D5_0_1] = 0;
+ BitTable[D5_0_2] = 0;
+ BitTable[D5_0_3] = 0;
+ BitTable[D5_0_4] = 0;
+ BitTable[D5_0_5] = 0;
+ BitTable[D5_0_6] = 0;
+ BitTable[D5_0_7] = 0;
+ BitTable[D5_0_8] = 0;
+ BitTable[D5_0_9] = 0;
+ BitTable[D5_0_10] = 0;
+ BitTable[D5_0_11] = 0;
+
+ BitTable[ D5_1_1] = 1;
+ BitTable[D5_1_2] = 1;
+ BitTable[D5_1_3] = 1;
+ BitTable[D5_1_4] = 1;
+ BitTable[D5_1_5] = 1;
+ BitTable[D5_1_6] = 1;
+ BitTable[D5_1_7] = 1;
+ BitTable[D5_1_8] = 1;
+ BitTable[D5_1_9] = 1;
+ BitTable[D5_1_10] = 1;
+ BitTable[D5_1_11] = 1;
+
+ BitTable[ D6_0_1] = 0;
+ BitTable[D6_0_2] = 0;
+ BitTable[D6_0_3] = 0;
+ BitTable[D6_0_4] = 0;
+ BitTable[D6_0_5] = 0;
+ BitTable[D6_0_6] = 0;
+ BitTable[D6_0_7] = 0;
+ BitTable[D6_0_8] = 0;
+ BitTable[D6_0_9] = 0;
+ BitTable[D6_0_10] = 0;
+ BitTable[D6_0_11] = 0;
+
+ BitTable[ D6_1_1] = 1;
+ BitTable[D6_1_2] = 1;
+ BitTable[D6_1_3] = 1;
+ BitTable[D6_1_4] = 1;
+ BitTable[D6_1_5] = 1;
+ BitTable[D6_1_6] = 1;
+ BitTable[D6_1_7] = 1;
+ BitTable[D6_1_8] = 1;
+ BitTable[D6_1_9] = 1;
+ BitTable[D6_1_10] = 1;
+ BitTable[D6_1_11] = 1;
+
+
+ BitTable[ D7_0_1] = 0;
+ BitTable[D7_0_2] = 0;
+ BitTable[D7_0_3] = 0;
+ BitTable[D7_0_4] = 0;
+ BitTable[D7_0_5] = 0;
+ BitTable[D7_0_6] = 0;
+ BitTable[D7_0_7] = 0;
+ BitTable[D7_0_8] = 0;
+ BitTable[D7_0_9] = 0;
+ BitTable[D7_0_10] = 0;
+ BitTable[D7_0_11] = 0;
+
+ BitTable[ D7_1_1] = 1;
+ BitTable[D7_1_2] = 1;
+ BitTable[D7_1_3] = 1;
+ BitTable[D7_1_4] = 1;
+ BitTable[D7_1_5] = 1;
+ BitTable[D7_1_6] = 1;
+ BitTable[D7_1_7] = 1;
+ BitTable[D7_1_8] = 1;
+ BitTable[D7_1_9] = 1;
+ BitTable[D7_1_10] = 1;
+ BitTable[D7_1_11] = 1;
+
+ BitTable[ D8_0_1] = 0;
+ BitTable[D8_0_2] = 0;
+ BitTable[D8_0_3] = 0;
+ BitTable[D8_0_4] = 0;
+ BitTable[D8_0_5] = 0;
+ BitTable[D8_0_6] = 0;
+ BitTable[D8_0_7] = 0;
+ BitTable[D8_0_8] = 0;
+ BitTable[D8_0_9] = 0;
+ BitTable[D8_0_10] = 0;
+ BitTable[D8_0_11] = 0;
+
+ BitTable[ D8_1_1] = 1;
+ BitTable[D8_1_2] = 1;
+ BitTable[D8_1_3] = 1;
+ BitTable[D8_1_4] = 1;
+ BitTable[D8_1_5] = 1;
+ BitTable[D8_1_6] = 1;
+ BitTable[D8_1_7] = 1;
+ BitTable[D8_1_8] = 1;
+ BitTable[D8_1_9] = 1;
+ BitTable[D8_1_10] = 1;
+ BitTable[D8_1_11] = 1;
+
+ BitTable[ D9_0_1] = 0;
+ BitTable[D9_0_2] = 0;
+ BitTable[D9_0_3] = 0;
+ BitTable[D9_0_4] = 0;
+ BitTable[D9_0_5] = 0;
+ BitTable[D9_0_6] = 0;
+ BitTable[D9_0_7] = 0;
+ BitTable[D9_0_8] = 0;
+ BitTable[D9_0_9] = 0;
+ BitTable[D9_0_10] = 0;
+ BitTable[D9_0_11] = 0;
+
+ BitTable[ D9_1_1] = 1;
+ BitTable[D9_1_2] = 1;
+ BitTable[D9_1_3] = 1;
+ BitTable[D9_1_4] = 1;
+ BitTable[D9_1_5] = 1;
+ BitTable[D9_1_6] = 1;
+ BitTable[D9_1_7] = 1;
+ BitTable[D9_1_8] = 1;
+ BitTable[D9_1_9] = 1;
+ BitTable[D9_1_10] = 1;
+ BitTable[D9_1_11] = 1;
+
+ BitTable[ D10_0_1] = 0;
+ BitTable[D10_0_2] = 0;
+ BitTable[D10_0_3] = 0;
+ BitTable[D10_0_4] = 0;
+ BitTable[D10_0_5] = 0;
+ BitTable[D10_0_6] = 0;
+ BitTable[D10_0_7] = 0;
+ BitTable[D10_0_8] = 0;
+ BitTable[D10_0_9] = 0;
+ BitTable[D10_0_10] = 0;
+ BitTable[D10_0_11] = 0;
+
+ BitTable[ D10_1_1] = 1;
+ BitTable[D10_1_2] = 1;
+ BitTable[D10_1_3] = 1;
+ BitTable[D10_1_4] = 1;
+ BitTable[D10_1_5] = 1;
+ BitTable[D10_1_6] = 1;
+ BitTable[D10_1_7] = 1;
+ BitTable[D10_1_8] = 1;
+ BitTable[D10_1_9] = 1;
+ BitTable[D10_1_10] = 1;
+ BitTable[D10_1_11] = 1;
+
+ BitTable[ D11_0_1] = 0;
+ BitTable[D11_0_2] = 0;
+ BitTable[D11_0_3] = 0;
+ BitTable[D11_0_4] = 0;
+ BitTable[D11_0_5] = 0;
+ BitTable[D11_0_6] = 0;
+ BitTable[D11_0_7] = 0;
+ BitTable[D11_0_8] = 0;
+ BitTable[D11_0_9] = 0;
+ BitTable[D11_0_10] = 0;
+ BitTable[D11_0_11] = 0;
+
+ BitTable[ D11_1_1] = 1;
+ BitTable[D11_1_2] = 1;
+ BitTable[D11_1_3] = 1;
+ BitTable[D11_1_4] = 1;
+ BitTable[D11_1_5] = 1;
+ BitTable[D11_1_6] = 1;
+ BitTable[D11_1_7] = 1;
+ BitTable[D11_1_8] = 1;
+ BitTable[D11_1_9] = 1;
+ BitTable[D11_1_10] = 1;
+ BitTable[D11_1_11] = 1;
+}
+ViterbiSoft::~ViterbiSoft()
+{}
+
+void ViterbiSoft::decode ( double dibit[2] )
+{
+ double min;
+ int i, k;
+ min = 1.0E99;
+ MinimumPath = 0;
+ double d[2];
+ d[0] = dibit[0];
+ d[1] = dibit[1];
+ double x;
+ RTTYSampleStates s;
+ double distance[2*NumberOfRTTYSampleStates];
+ RTTYSampleStates bitestimate[2*NumberOfRTTYSampleStates][MEMORYLENGTH];
+
+ for ( i = 0;i < 2*NumberOfRTTYSampleStates;i++ )
+ distance[i] = 10000.;
+ for ( i = 0; i < NumberofStates; i++ )
+ {
+ for ( int j = 0; j < 2;j++ )
+ {
+ s = StateTable[j][i];
+
+// x = Metric[i] + ( *dist ) ( dibit,BitTable[StateTable[j][i]] );
+ x = Metric[i] + ( *dist ) ( dibit, j );
+ if ( x < distance[s+j*NumberofStates] )
+ {
+ distance[s+j*NumberofStates] = x;
+
+ if ( x < min )
+ {
+ min = x;
+ MinimumPath = s;
+ }
+ for ( k = 0;k < MEMORYLENGTH;k++ )
+ bitestimate[s+j*NumberofStates][k] = PathMem[i][k];
+ bitestimate[s+j*NumberofStates][pathPointer] = StateTable[j][i];
+ }
+ }
+ }
+ for ( i = 0;i < NumberofStates ;i++ )
+ {
+ if ( distance[i] < distance[i+NumberofStates] )
+ {
+ Metric[i] = distance[i] - min;
+ for ( k = 0;k < MEMORYLENGTH;k++ )
+ PathMem[i][k] = bitestimate[i][k];
+ }
+ else
+ {
+ Metric[i] = distance[NumberofStates+i] - min;
+ for ( k = 0;k < MEMORYLENGTH;k++ )
+ PathMem[i][k] = bitestimate[NumberofStates+i][k];
+
+ }
+ }
+ pathPointer = ( pathPointer + 1 ) % MEMORYLENGTH;
+}
+int ViterbiSoft::getBit ( unsigned int i )
+{
+ int pos;
+ pos = ( pathPointer + 127 - i ) % MEMORYLENGTH;
+ return ( BitTable[ PathMem[MinimumPath][pos]] );
+}
+ViterbiSoft::RTTYSampleStates ViterbiSoft::getState(unsigned int i)
+{
+ int pos;
+ pos = ( pathPointer + 127 - i ) % MEMORYLENGTH;
+ return ( PathMem[MinimumPath][pos] );
+}
diff --git a/src/viterbisoft.h b/src/viterbisoft.h
new file mode 100644
index 0000000..aebcfc6
--- /dev/null
+++ b/src/viterbisoft.h
@@ -0,0 +1,75 @@
+/***************************************************************************
+ viterbisoft.h - description
+ -------------------
+ begin : Sam M�r 8 2003
+ copyright : (C) 2003 by Volker Schroer
+ email : dl1ksv at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef viterbisoft_H
+#define viterbisoft_H
+
+#define MEMORYLENGTH 256
+#define NumberOfRTTYSampleStates 269
+/**
+ *@author Volker Schroer
+ */
+
+class ViterbiSoft
+{
+ public:
+ ViterbiSoft ( const double ( * ) ( double *, int ) );
+ ~ViterbiSoft();
+// void decode(int,const double (*)(int,int));
+ void decode ( double * );
+
+ int getBit ( unsigned int i );
+ enum RTTYSampleStates {Start1 = 0,Start2,Start3,Start4,Start5,Start6,Start7,Start8,Start9,Start10,Start11,
+Stop1,Stop2,Stop3,Stop4,Stop5,Stop6,Stop7,Stop8,Stop9,Stop10,Stop11,Stop12,Stop13,Stop14,Stop15,Stop16,
+ D1_0_1,D1_0_2,D1_0_3,D1_0_4,D1_0_5,D1_0_6,D1_0_7,D1_0_8,D1_0_9,D1_0_10,D1_0_11,
+ D1_1_1,D1_1_2,D1_1_3,D1_1_4,D1_1_5,D1_1_6,D1_1_7,D1_1_8,D1_1_9,D1_1_10,D1_1_11,
+ D2_0_1,D2_0_2,D2_0_3,D2_0_4,D2_0_5,D2_0_6,D2_0_7,D2_0_8,D2_0_9,D2_0_10,D2_0_11,
+ D2_1_1,D2_1_2,D2_1_3,D2_1_4,D2_1_5,D2_1_6,D2_1_7,D2_1_8,D2_1_9,D2_1_10,D2_1_11,
+ D3_0_1,D3_0_2,D3_0_3,D3_0_4,D3_0_5,D3_0_6,D3_0_7,D3_0_8,D3_0_9,D3_0_10,D3_0_11,
+ D3_1_1,D3_1_2,D3_1_3,D3_1_4,D3_1_5,D3_1_6,D3_1_7,D3_1_8,D3_1_9,D3_1_10,D3_1_11,
+ D4_0_1,D4_0_2,D4_0_3,D4_0_4,D4_0_5,D4_0_6,D4_0_7,D4_0_8,D4_0_9,D4_0_10,D4_0_11,
+ D4_1_1,D4_1_2,D4_1_3,D4_1_4,D4_1_5,D4_1_6,D4_1_7,D4_1_8,D4_1_9,D4_1_10,D4_1_11,
+ D5_0_1,D5_0_2,D5_0_3,D5_0_4,D5_0_5,D5_0_6,D5_0_7,D5_0_8,D5_0_9,D5_0_10,D5_0_11,
+ D5_1_1,D5_1_2,D5_1_3,D5_1_4,D5_1_5,D5_1_6,D5_1_7,D5_1_8,D5_1_9,D5_1_10,D5_1_11,
+ D6_0_1,D6_0_2,D6_0_3,D6_0_4,D6_0_5,D6_0_6,D6_0_7,D6_0_8,D6_0_9,D6_0_10,D6_0_11,
+ D6_1_1,D6_1_2,D6_1_3,D6_1_4,D6_1_5,D6_1_6,D6_1_7,D6_1_8,D6_1_9,D6_1_10,D6_1_11,
+ D7_0_1,D7_0_2,D7_0_3,D7_0_4,D7_0_5,D7_0_6,D7_0_7,D7_0_8,D7_0_9,D7_0_10,D7_0_11,
+ D7_1_1,D7_1_2,D7_1_3,D7_1_4,D7_1_5,D7_1_6,D7_1_7,D7_1_8,D7_1_9,D7_1_10,D7_1_11,
+ D8_0_1,D8_0_2,D8_0_3,D8_0_4,D8_0_5,D8_0_6,D8_0_7,D8_0_8,D8_0_9,D8_0_10,D8_0_11,
+ D8_1_1,D8_1_2,D8_1_3,D8_1_4,D8_1_5,D8_1_6,D8_1_7,D8_1_8,D8_1_9,D8_1_10,D8_1_11,
+ D9_0_1,D9_0_2,D9_0_3,D9_0_4,D9_0_5,D9_0_6,D9_0_7,D9_0_8,D9_0_9,D9_0_10,D9_0_11,
+ D9_1_1,D9_1_2,D9_1_3,D9_1_4,D9_1_5,D9_1_6,D9_1_7,D9_1_8,D9_1_9,D9_1_10,D9_1_11,
+ D10_0_1,D10_0_2,D10_0_3,D10_0_4,D10_0_5,D10_0_6,D10_0_7,D10_0_8,D10_0_9,D10_0_10,D10_0_11,
+ D10_1_1,D10_1_2,D10_1_3,D10_1_4,D10_1_5,D10_1_6,D10_1_7,D10_1_8,D10_1_9,D10_1_10,D10_1_11,
+ D11_0_1,D11_0_2,D11_0_3,D11_0_4,D11_0_5,D11_0_6,D11_0_7,D11_0_8,D11_0_9,D11_0_10,D11_0_11,
+ D11_1_1,D11_1_2,D11_1_3,D11_1_4,D11_1_5,D11_1_6,D11_1_7,D11_1_8,D11_1_9,D11_1_10,D11_1_11};
+ RTTYSampleStates getState(unsigned int i);
+ private:
+ int BitCount;
+ int StopBitCount;
+ int NumberofStates;
+ int MinimumPath;
+int BitTable[NumberOfRTTYSampleStates];
+RTTYSampleStates StateTable[2][NumberOfRTTYSampleStates];
+ const double ( *dist ) ( double [], int );
+ double Metric[NumberOfRTTYSampleStates];
+ RTTYSampleStates PathMem[NumberOfRTTYSampleStates][MEMORYLENGTH];
+ int pathPointer;
+
+};
+
+#endif
diff --git a/src/waveinput.cpp b/src/waveinput.cpp
new file mode 100644
index 0000000..bc9beb1
--- /dev/null
+++ b/src/waveinput.cpp
@@ -0,0 +1,297 @@
+/***************************************************************************
+ waveinput.cpp - description
+ -------------------
+ begin : Sat May 5 2001
+ copyright : (C) 2001 by Volker Schroer
+ email : DL1KSV at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#include "waveinput.h"
+#include "parameter.h"
+
+extern Parameter settings;
+
+WaveInput::WaveInput(int ptt = -1): Input(ptt)
+{
+ EightBits=false;
+}
+WaveInput::~WaveInput(){
+}
+
+/** Opens the Device for writting, for Wavefiles this means write nothing ! */
+bool WaveInput::open_Device_write(QString *)
+{
+return true;
+}
+/** Open Device for reading **/
+/** puts the Samples onto the Device, for a Wavemode Device nothing happens */
+int WaveInput::putSamples(double *,int anzahl)
+{
+return anzahl;
+}
+
+/** Dummy */
+void WaveInput::PTT(bool )
+{
+}
+
+ /** Opens the Device named Device for reading */
+
+bool WaveInput::open_Device_read(QString *errorstring)
+{
+ char header[5];
+ unsigned char header1[3];
+ char c;
+ QString s;
+ int i;
+ *errorstring=QString("");
+ if (settings.inputFilename == "" )
+ {
+ *errorstring= QString(QObject::tr("Error, no Demofile selected"));
+ return false;
+ }
+ fd = open(settings.inputFilename.toAscii(),O_RDONLY);
+ if ( fd < 0)
+ {
+ *errorstring= QString(QObject::tr("Error, Could not open Demofile "));
+ return false;
+ }
+
+
+// Check for RIFF
+i =read(fd,&header[0],4*sizeof(header[0]));
+if ( i != 4)
+ {
+ close(fd);
+ *errorstring= QString(QObject::tr("Header mismatch"));
+ return false;
+ }
+header[4]=0;
+s=QString(header);
+
+if ( s != "RIFF")
+ {
+ close(fd);
+ *errorstring = settings.inputFilename + QString(QObject::tr( " is not a RIFF File\n"));
+ return false;
+ }
+
+//Check for Wave
+lseek(fd,8,SEEK_SET);
+i =read(fd,&header[0],4*sizeof(header[0]));
+header[4]=0;
+if ( i != 4)
+ {
+ close(fd);
+ *errorstring= QString(QObject::tr("SubType mismatch\n"));
+ return false;
+ }
+s=QString(header);
+
+if ( s != "WAVE")
+ {
+ close(fd);
+ *errorstring =settings.inputFilename + QString(QObject::tr(" is not a WAVE File\n"));
+ return false;
+ }
+//Check for fmt
+
+i =read(fd,&header[0],4*sizeof(header[0]));
+header[4]=0;
+if ( i != 4)
+{
+ close(fd);
+ *errorstring= QString(QObject::tr("File is too short\n"));
+ return false;
+}
+s=QString(header);
+if ( s != "fmt ")
+{
+ close(fd);
+ *errorstring =settings.inputFilename + QString(QObject::tr(" does not have a fmt chunk\n"));
+ return false;
+}
+// Read length of fmt chunk
+i=read(fd,&header[0],4*sizeof(header[0]));
+if ( i != 4)
+{
+ close(fd);
+ *errorstring= QString(QObject::tr("File is too short, while reading fmt chunk\n"));
+ return false;
+}
+Length=header[0] | (header[1] << 8) |(header[2] << 16) | (header[3] << 24 );
+// To distinguish between the two versions of wav ( canonical and new)
+if ((Length -16) >0)
+ offset = Length-16;
+else
+ offset = 0;
+//Check for format
+lseek(fd,20,SEEK_SET);
+i=read(fd,&header[0],2*sizeof(header[0]));
+if ( i != 2)
+ {
+ close(fd);
+ *errorstring= QString(QObject::tr("File is too short, while reading format info in fmt chunk\n"));
+ return false;
+ }
+ Length=header[0] | ( header[1] << 8 );
+ if (Length != 1 )
+ {
+ close(fd);
+ *errorstring= QString(QObject::tr("File is too short, while reading format info in fmt chunk\n"));
+ return false;
+ }
+
+//check for mono
+lseek(fd,22,SEEK_SET);
+i=read(fd,&header[0],2*sizeof(header[0]));
+if ( i != 2)
+ {
+ close(fd);
+ *errorstring= QString(QObject::tr("File is too short, while reading channel info in fmt chunk\n"));
+ return false;
+ }
+Length=header[0] | ( header[1] << 8 );
+if ( Length != 1)
+{
+ close(fd);
+ *errorstring= QString(QObject::tr("Only mono is supported at the moment\n"));
+ return false;
+}
+// Check for sample rate
+lseek(fd,24,SEEK_SET);
+i=read(fd,&header[0],4*sizeof(header[0]));
+if ( i != 4)
+ {
+ close(fd);
+ *errorstring= QString(QObject::tr("File is too short, while reading sample rate in fmt chunk\n"));
+ return false;
+ }
+Length=header[0] | ( header[1] << 8 ) | (header[2] << 16) | (header[3] << 24 );
+
+if ( Length != 11025)
+{
+ close(fd);
+ *errorstring= QString(QObject::tr("Only a sample rate of 11025Hz is supported at the moment\n"));
+ return false;
+}
+//let's check for 8 / 16 bit samples
+lseek(fd,34,SEEK_SET);
+i=read(fd,&c,1);
+if (c == 8)
+ EightBits=true;
+else
+ EightBits=false;
+offset +=36;
+// Now find data
+lseek(fd,offset,SEEK_SET);
+i=read(fd,&header[0],4*sizeof(header[0]));
+
+header[5]=0;
+s=QString(header);
+// Checking for fact chunk
+if ( s == "fact")
+{
+ lseek(fd,8,SEEK_CUR);
+ i=read(fd,&header[0],4*sizeof(header[0]));
+ header[5]=0;
+ s=QString(header);
+
+}
+if ( (i != 4) || s != "data" )
+{
+ close(fd);
+ *errorstring= QString(QObject::tr("No data found\n"));
+ return false;
+}
+
+// got it
+// Read 4 byte Length info
+i=read(fd,&header1[0],4*sizeof(header1[0]));
+if ( i != 4)
+{
+ close(fd);
+ *errorstring= QString(QObject::tr("File is too short, while reading length of data chunk\n"));
+ return false;
+}
+Length=0;
+Length=header1[0] | (header1[1] << 8) |(header1[2] << 16) | (header1[3] << 24 );
+Bytesread=0;
+offset = lseek(fd,0,SEEK_CUR);
+i=lseek(fd,offset,SEEK_SET);
+return true;
+}
+
+int WaveInput::getSamples(double *sample,int anzahl)
+{
+unsigned char c[2];
+int i,j;
+j=0;
+double x;
+
+while (j<anzahl)
+ {
+ if (!EightBits)
+ {
+ i= read(fd,&c[0],2*sizeof(c[0]));
+ if (i == 2)
+ {
+ if ( c[1] < 128 )
+ i = c[0]+ c[1]* 256 ;
+ else
+ i = ( c[1]- 256) *256 +c[0];
+ x= i;
+ *(sample++)=x/32767.;
+ j++;
+ Bytesread +=2;
+ }
+ else
+ // lseek(fd,offset,SEEK_SET);
+ printf("Error reading data chunk\n");
+ }
+ else
+ {
+ i=read(fd,&c[0],sizeof(c[0]));
+ if ( i==1 )
+ {
+ if ( c[0] < 128 )
+ x = float(c[0])/128.;
+ else
+ x = float(c[0]-256)/128;
+ *(sample++)=x;
+ j++;
+ Bytesread++;
+ }
+ else
+ // lseek(fd,offset,SEEK_SET);
+ printf("Error reading data chunk\n");
+ }
+ if (Bytesread >= Length )
+ {
+ lseek(fd,offset,SEEK_SET);
+ Bytesread=0;
+ }
+
+ } // End while
+return j;
+
+}
+
+bool WaveInput::close_Device()
+{
+return true;
+}
+/**
+void WaveInput::samplesAvailable()
+{
+ emit Input::samplesAvailable();
+}
+**/
diff --git a/src/waveinput.h b/src/waveinput.h
new file mode 100644
index 0000000..ca21cbb
--- /dev/null
+++ b/src/waveinput.h
@@ -0,0 +1,61 @@
+/***************************************************************************
+ waveinput.h - description
+ -------------------
+ begin : Sat May 5 2001
+ copyright : (C) 2001 by Volker Schroer
+ email : DL1KSV at gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifndef WAVEINPUT_H
+#define WAVEINPUT_H
+
+#include "input.h"
+#include <stdlib.h>
+
+/**Implementation of the Input Class for wave - files
+The implementation is simplified . But it can process the two sample files
+for mfsk16 and psk31.
+The class doesn't produce output at the moment
+ *@author Volker Schroer
+ */
+
+class WaveInput : public Input
+{
+Q_OBJECT
+ public:
+ WaveInput ( int ptt );
+ ~WaveInput();
+ /** Opens the Device for writting **/
+ bool open_Device_write ( QString * );
+ /** Opens the Device for reading **/
+ bool open_Device_read ( QString * );
+ /** Close the Device **/
+ virtual bool close_Device();
+ /** gets the samples from the device */
+ int getSamples ( double *sample, int anzahl );
+ /** puts the Samples onto the Device, for a Textmode Device nothing happens */
+ int putSamples ( double *sample, int anzahl );
+ /** Dummy */
+ void PTT ( bool mode );
+ /** Dummy */
+ bool setParams ( QString *errorstring );
+ signals:
+// void samplesAvailable();
+
+ private:
+
+ int offset;
+ unsigned long int Length, Bytesread;
+ bool EightBits;
+ int fd;
+};
+
+#endif
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-hamradio/linpsk.git
More information about the pkg-hamradio-commits
mailing list