pax_global_header00006660000000000000000000000064130463615670014525gustar00rootroot0000000000000052 comment=c538bddf44dcb0c0109fc97df62becd7b95b384c linpsk-1.3.5/000077500000000000000000000000001304636156700130335ustar00rootroot00000000000000linpsk-1.3.5/.gitignore000066400000000000000000000000271304636156700150220ustar00rootroot00000000000000build* linpsk.pro.user linpsk-1.3.5/COPYING000066400000000000000000000431311304636156700140700ustar00rootroot00000000000000 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. Copyright (C) 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. , 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. linpsk-1.3.5/ChangeLog000066400000000000000000000101051304636156700146020ustar00rootroot00000000000000LinPsk ChangeLog 1.3.5 Adding PSK63 mode Fixing wrong scaling in Spectrum display 1.3.1 Building with qt4 or qt5 depending on qmake. If qmake detects hamlib, LinPSK will be build with hamlib support. Now you can define bands and a preferred frequency to use. On startup the frequency and the tx-power setting is read from the tx and inserted in the qso tab. Changing the entry in the tab will will change the tx - settings. You have to setup the communication parameter in the general settings menu. Removing textfile input for demo mode. Only wav files are supported in the future. 1.2.5 Now building in build directory. Switching to qt5. 1.2.2 As I got some usb3 problems when transmitting - the same macro was executed several times though only clicked once I introduced a timer that assures a minum click time of one second. More rapid clicks are ignored. Introducing explicit mode - switching to receive. In this state you see the letter "A" ( Abort ) in the rx/tx button and you can abort the transmission. This might help if the transmission does not stop. ( Probably a bug, but I didn' find the reason. )This avoids killing the program. In debug mode: showing the properties of the sound device. Enabling usb2serial converters. Activate/ deactivate macros 1.2.1 Modified RxWindow to enable horizontal scrollbar correctly. Enable/disable date/time data in qsowindow. This fields can be set automatically on saving qso data. Copy data of rx window to clipboard. 1.2 Modified gui to fit on small screens. Improved soundcard detection. Introduced Dok field to qsodata. Predefined frequency values for use with linlogbook. Introduced language parameter for use with macros. 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 . 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" linpsk-1.3.5/README000066400000000000000000000026401304636156700137150ustar00rootroot00000000000000Important: This versionan be build with qt4 or qt5!!! Which version of qt is used depends on the qmake version. For those who use LinPSK on a PI in a headless environment: Due to a bug in tightvnc build LinPSK against qt4, otherwise you'll get garbeld text in LinPSK transmit box or in the qso fields !!!! To build LinPsk, untar the tar archiv and switch to the linpsk directory. You need fftw3. Now you can define a list of bands, which is used in the setup of the qso data. If you select a band and LinPSK is build with hamlib support your rig is tuned to the preferred frequency of this band. LinPSK is build with hamlib support, if qmake finds the hamlib library (by pkg-config). Additionaly you can control the Tx power by the qsodata settings, if your rig supports this feature. Band name and Tx power can be used to log with LinLogbook. run: mkdir -p build cd build qmake -o Makefile ../linpsk.pro make sudo make install This will install the binary into usr/local/bin and the desktop file into /usr/share/pixmaps/ and the icon file into /usr/share/pixmaps/ . As LinPSK uses the alsa sound system, you can use valid alsa devices like plughw:1 in the settings dialog Also using the card name can be used now. In this case LinPSK searches the cardnumber and opens plughw:[cardnumber] In case of problems you can define ( more complex ) devices in your .asoundrc file. The should be named LinPSK_Record and LinPSK_Play. linpsk-1.3.5/asoundrc000066400000000000000000000006321304636156700145750ustar00rootroot00000000000000pcm.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" } } linpsk-1.3.5/data/000077500000000000000000000000001304636156700137445ustar00rootroot00000000000000linpsk-1.3.5/data/linpsk.appdata.xml000066400000000000000000000016001304636156700173740ustar00rootroot00000000000000 linpsk.desktop CC0-1.0

LinPSK is a hamradio application for different digital modes. Suported modes:

  • BPSK31
  • QPSK31
  • RTTY
  • MFSK16

The main features:

  • Decoding multiple signals simultaneously
  • Macro definition for transmit
  • Sending qso data to LinLogbook
  • Requesting callsign data from LinLogbook
http://a.fsdn.com/con/app/proj/linpsk/screenshots/LinPskbig.png http://linpsk.sf.net a@sf.net
linpsk-1.3.5/data/linpsk.desktop000066400000000000000000000004241304636156700166370ustar00rootroot00000000000000[Desktop Entry] Type=Application Name=LinPSK GenericName=A Modem for PSK31, RTTY and MFSK16 ( experimental ) Comment=A modem for some digital Ham modes # FIXME add comments in other languages Exec=linpsk Categories=Qt;HamRadio; Terminal=false Icon=linpsk Keywords=Radio;HAM; linpsk-1.3.5/gui/000077500000000000000000000000001304636156700136175ustar00rootroot00000000000000linpsk-1.3.5/gui/activatemacros.cpp000066400000000000000000000074341304636156700173400ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2014 by Volker Schroer, DL1KSV * * * * 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 "activatemacros.h" #include "ui_activatemacros.h" #include "readonlystringlistmodel.h" ActivateMacros::ActivateMacros(QVector *macroList, QWidget *parent) : QDialog(parent), ui(new Ui::ActivateMacros) { ui->setupUi(this); mL = macroList; activeMacros=new ReadOnlyStringListModel ( ); deactivatedMacros = new ReadOnlyStringListModel ( ); // activeList = new QStringList(); // QStringList deactivateList; int numberofMacros=macroList->size(); if (numberofMacros > 0 ) for(int i=0; i < numberofMacros;i++) { if( (*macroList).at(i).languageType >= 0) { activeList << (*macroList).at(i).name; deactivateList << ""; } else { deactivateList << (*macroList).at(i).name; activeList << ""; } } activeMacros->setStringList(activeList); deactivatedMacros->setStringList(deactivateList); ui->activeList->setModel(activeMacros); ui->passiveList->setModel(deactivatedMacros); } ActivateMacros::~ActivateMacros() { delete activeMacros; delete deactivatedMacros; delete ui; } void ActivateMacros::addtoList() { if(ui->activeList->currentIndex().data().toString().isEmpty()) return; deactivatedMacros->setData(ui->activeList->currentIndex(),ui->activeList->currentIndex().data()); deactivateList.replace(ui->activeList->currentIndex().row(),ui->activeList->currentIndex().data().toString()); activeMacros->setData(ui->activeList->currentIndex(),""); ui->activeList->clearSelection(); } void ActivateMacros::removefromList() { if(ui->passiveList->currentIndex().data().toString().isEmpty()) return; activeMacros->setData(ui->passiveList->currentIndex(),ui->passiveList->currentIndex().data()); activeList.replace(ui->passiveList->currentIndex().row(),ui->passiveList->currentIndex().data().toString()); deactivatedMacros->setData(ui->passiveList->currentIndex(),""); ui->passiveList->clearSelection(); } void ActivateMacros::accept() { int numberofMacros=mL->size(); if (numberofMacros > 0 ) for(int i=0; i < numberofMacros;i++) { if(((*mL).at(i).languageType >= 0) && (!deactivateList.at(i).isEmpty())) { Macro macro; macro=(*mL).at(i); macro.languageType -=3; mL->replace(i,macro); } else if (((*mL).at(i).languageType < 0) && (!activeList.at(i).isEmpty())) { Macro macro; macro=(*mL).at(i); macro.languageType +=3; mL->replace(i,macro); } } QDialog::accept(); } linpsk-1.3.5/gui/activatemacros.h000066400000000000000000000037561304636156700170100ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2014 by Volker Schroer, DL1KSV * * * * 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 ACTIVATEMACROS_H #define ACTIVATEMACROS_H #include #include "constants.h" class ReadOnlyStringListModel; namespace Ui { class ActivateMacros; } class ActivateMacros : public QDialog { Q_OBJECT public: explicit ActivateMacros(QVector *macroList,QWidget *parent = 0); ~ActivateMacros(); private: Ui::ActivateMacros *ui; QVector *mL; ReadOnlyStringListModel *activeMacros; ReadOnlyStringListModel *deactivatedMacros; QStringList activeList; QStringList deactivateList; protected slots: virtual void accept(); void removefromList(); void addtoList(); }; #endif // ACTIVATEMACROS_H linpsk-1.3.5/gui/activatemacros.ui000066400000000000000000000127111304636156700171650ustar00rootroot00000000000000 ActivateMacros 0 0 669 328 Active / Deactivate Macros Activated Macros Qt::Horizontal 40 35 Qt::Horizontal 58 20 Qt::Vertical 20 40 >> Deactivate Qt::Vertical 20 40 << Activate Qt::Vertical 20 40 Qt::Horizontal 40 35 Deactivated Macros Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok buttonBox accepted() ActivateMacros accept() 248 254 157 274 buttonBox rejected() ActivateMacros reject() 316 260 286 274 deactMacros clicked() ActivateMacros addtoList() 334 110 334 163 actMacros clicked() ActivateMacros removefromList() 334 202 334 163 addtoList() removefromList() linpsk-1.3.5/gui/addmacro.cpp000066400000000000000000000071261304636156700161030ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2012 by Volker Schroer, DL1KSV * * * * 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 "ui_addmacro.h" #include #include AddMacro::AddMacro(QVector *macroList,QStringList tokenList, QWidget* parent) : QDialog( parent), ui(new Ui::AddMacro) { ui->setupUi(this); ui->bG->setId(ui->lang0,0); ui->bG->setId(ui->lang1,1); ui->bG->setId(ui->lang2,2); mL=macroList; ReadOnlyStringListModel *model= new ReadOnlyStringListModel(); model->setStringList(tokenList); ui->KeywordDisplay->setModel(model); model= new ReadOnlyStringListModel(); QStringList macroName; int numberofMacros=macroList->size(); if (numberofMacros > 0 ) for(int i=0; i < numberofMacros;i++) macroName.append((*macroList).at(i).name); model->setStringList(macroName); ui->MacroDisplay->setModel(model); ui->Position->setMaximum(numberofMacros); ui->Position->setValue(numberofMacros); } AddMacro::~AddMacro() { delete ui; } void AddMacro::accept() { int anzahl; if (ui->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 (ui->MacroDefinition->toPlainText().length()== 0) { QMessageBox::warning(this,"Incomplete Macro Definition","Macrodefinition is missing \n Enter Macrodefinition", QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton); return; } anzahl=ui->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; } Macro macro; macro.name=ui->MacroName->text(); macro.text=ui->MacroDefinition->toPlainText(); macro.accelerator=ui->Accelerator->text(); macro.languageType=ui-> bG->checkedId(); // mL->append(macro); mL->insert(ui->Position->value(),macro); QDialog::accept(); } void AddMacro::insertKeyword(QModelIndex index) { QString s=index.data().toString(); ui->MacroDefinition->insertPlainText(s); ui->MacroDefinition->setFocus(); } linpsk-1.3.5/gui/addmacro.h000066400000000000000000000035151304636156700155460ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2012 by Volker Schroer, DL1KSV * * * * 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 #include #include #include "constants.h" namespace Ui { class AddMacro; } class AddMacro : public QDialog { Q_OBJECT public: AddMacro(QVector *macroList,QStringList tokenList,QWidget* parent = 0); ~AddMacro(); public slots: protected: protected slots: virtual void accept(); void insertKeyword(QModelIndex); private: Ui::AddMacro *ui; QVector *mL; }; #endif linpsk-1.3.5/gui/addmacro.ui000066400000000000000000000245711304636156700157410ustar00rootroot00000000000000 AddMacro 0 0 673 550 0 0 600 450 600 350 Add Macro true 90 20 Macro Name Qt::PlainText false 0 0 150 20 Language selection both true bG english bG german bG 145 20 Position in Macro List false Qt::Horizontal 31 20 45 20 1 90 20 Accelerator false 0 0 50 20 0 20 Macro Text Qt::PlainText false 0 20 List of allready existing macros false 0 0 Keywords false 0 0 Example QFrame::NoFrame QFrame::Plain @TX@ cq cq de @CALLSIGN@ pse k @RX@ Qt::PlainText false Qt::Horizontal 356 20 &OK true true Qt::Horizontal 72 22 &Cancel true qPixmapFromMimeSource buttonOk clicked() AddMacro accept() 20 20 20 20 buttonCancel clicked() AddMacro reject() 20 20 20 20 KeywordDisplay clicked(QModelIndex) AddMacro insertKeyword(QModelIndex) 162 382 367 256 insertKeyword(QModelIndex) linpsk-1.3.5/gui/addrxwindow.cpp000066400000000000000000000036401304636156700166600ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2007 - 2016 by Volker Schroer , DL1KSV * * * * 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(QStringList modeList, QWidget* parent) : QDialog( parent ), Ui::AddRxWindow() { setupUi(this); RxMode->addItems(modeList); 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(); } linpsk-1.3.5/gui/addrxwindow.h000066400000000000000000000035431304636156700163270ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2007 by volker, DL1KSV * * schroer@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 #include #include "ui_addrxwindow.h" #include "constants.h" class AddRxWindow : public QDialog, private Ui::AddRxWindow { Q_OBJECT public: AddRxWindow(QStringList modeList,QWidget* parent = 0); ~AddRxWindow(); Mode selectedMode(); QString titleText(); int frequency(); /*$PUBLIC_FUNCTIONS$*/ public slots: /*$PUBLIC_SLOTS$*/ protected: /*$PROTECTED_FUNCTIONS$*/ protected slots: /*$PROTECTED_SLOTS$*/ }; #endif linpsk-1.3.5/gui/addrxwindow.ui000066400000000000000000000140501304636156700165100ustar00rootroot00000000000000 AddRxWindow 0 0 325 299 Add another RxWIndow true Title false 0 0 Qt::Vertical 20 80 0 0 Mode false Qt::Vertical 20 80 Rx Frequency false 0 0 Hz 300 2500 1000 Qt::Horizontal 147 20 Qt::ClickFocus OK false false false Qt::Horizontal QSizePolicy::Expanding 40 20 Qt::ClickFocus Cancel false Qt::Horizontal 126 20 qPixmapFromMimeSource constants.h buttonOk clicked() AddRxWindow accept() 20 20 20 20 buttonCancel clicked() AddRxWindow reject() 20 20 20 20 linpsk-1.3.5/gui/controlpanel.cpp000066400000000000000000000041221304636156700170220ustar00rootroot00000000000000 #include "controlpanel.h" #include #include #include #include #include #include #include "spectrumdisplay.h" #include "qsodata.h" /* * Constructs a ControlPanel which is a child of 'parent', with the * name 'name'.' */ ControlPanel::ControlPanel( QWidget* parent) : QFrame( parent ), Ui::ControlPanel() { setupUi(this); connect(Display,SIGNAL(FrequencyChanged(double)),this,SIGNAL(FrequencyChanged(double))); connect(macroControl,SIGNAL(executeMacro(int)),this,SIGNAL(executeMacro(int))); } /* * 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::setQsoData(QsoData value,QString s) { QSO->setQsoData(value,s); } void ControlPanel::setPhasePointer(std::complex *p) { Display->setPhasePointer(p); } void ControlPanel::setColorList(QList *c) { Display->setColorList(c); } void ControlPanel::startPlot ( double *d, bool b) { Display->startPlot(d,b); } void ControlPanel::present(bool p) { Display->showSpectren(p); } void ControlPanel::newChannel() { QSO->newChannel(); } void ControlPanel::updateMacroWindow(int macroNumber) { macroControl->updateMacroWindow(macroNumber); } void ControlPanel::insertMacros(QVector *macroList) { macroControl->insertMacros(macroList); } void ControlPanel::enableSaveData() { QSO->enableSaveData(); } void ControlPanel::setAutoDate() { QSO->setAutoDate(); } void ControlPanel::restoreSplitterStates(const QByteArray & controlState,const QByteArray & spectrumState) { controlSplitter->restoreState(controlState); Display->restoreSplitterState(spectrumState); } QByteArray ControlPanel::controlSplitterState() const { return controlSplitter->saveState(); } QByteArray ControlPanel::spectrumSplitterState() const { return Display->spectrumSplitterState(); } void ControlPanel::initQsoData() { QSO->initQsoData(); } linpsk-1.3.5/gui/controlpanel.h000066400000000000000000000021551304636156700164730ustar00rootroot00000000000000 #ifndef CONTROLPANEL_H #define CONTROLPANEL_H #include #include #include #include #include "ui_controlpanel.h" #include #include "constants.h" class Macros; class ControlPanel : public QFrame, private Ui::ControlPanel { Q_OBJECT public: ControlPanel(QWidget* parent = 0); void insertMacros(Macros *); void setPhasePointer(std::complex *); void setColorList(QList *c); void present(bool p); void newChannel(); void updateMacroWindow(int macroNumber); void insertMacros(QVector *macroList); void enableSaveData(); void setAutoDate(); void initQsoData(); void restoreSplitterStates(const QByteArray & controlState,const QByteArray & spectrumState); QByteArray controlSplitterState() const; QByteArray spectrumSplitterState() const; ~ControlPanel(); protected: public slots: void startPlot ( double *, bool ); void setQsoData(QsoData,QString); protected slots: private: signals: void FrequencyChanged ( double ); void executeMacro ( int ); }; #endif // CONTROLPANEL_H linpsk-1.3.5/gui/controlpanel.ui000066400000000000000000000061241304636156700166610ustar00rootroot00000000000000 ControlPanel 0 0 604 190 Frame QFrame::StyledPanel QFrame::Sunken 1 Qt::Horizontal false 240 0 QFrame::StyledPanel QFrame::Raised 2 -1 1 273 0 10 0 Qso Infos Qt::AlignCenter Macro SpectrumDisplay QFrame
spectrumdisplay.h
1 FrequencyChanged(double)
QSOData QGroupBox
qsodata.h
1
MacroControl QGroupBox
macrocontrol.h
1
FrequencyChanged(double)
linpsk-1.3.5/gui/crxdisplay.cpp000066400000000000000000000155211304636156700165110ustar00rootroot00000000000000/*************************************************************************** * * * 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 #include #include #include #include "crxdisplay.h" #include "crxchannel.h" #include "crxwindow.h" #include "csquelch.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; CRxDisplay::CRxDisplay ( QWidget* parent ) : QFrame ( parent ), Ui::CRxDisplay() { setupUi(this); Sound = 0; RxChannel = new CRxChannel ( 0, this ); RxHeader->insertTab ( 0, RxChannel->getWindow(),QString("Rx 1") ); RxFreq->setFunctionText("Narrow"); settings.ChannelChain = RxChannel; settings.ActChannel = RxChannel; languageChange(); // Connect Signals and Slots connect ( RxChannel->RxWindow, SIGNAL ( setQsoData(QsoData,QString)),this, SIGNAL (setQsoData(QsoData,QString))); connect ( RxChannel, SIGNAL ( Triggered ( int ) ), RxHeader, SLOT ( setCurrentIndex ( int ) ) ); trigger(); // We should ensure that the triggertext is stored; Squelch->setSquelchState ( RxChannel->getSquelchState() ); // Creating Variables for the fft plan = fftw_plan_r2r_1d ( BUF_SIZE , 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" ) ); } bool CRxDisplay::start_process_loop() { QString errorstring; if ( Sound == 0 ) { if ( settings.DemoMode ) Sound = new WaveInput ( -1 ); else Sound = new CSound ( settings.serial ); if ( Sound <= NULL ) return false; connect ( Sound, SIGNAL ( samplesAvailable() ), this, SLOT ( process_rxdata() ) ); } 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::process_rxdata() { bool overload; Mode modtype; if ( Sound->getSamples ( inbuf, BUF_SIZE ) == 0 ) return; // No sample available, try later overload = false; 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() ); // Calculate FFT and start Ploting for ( int i = 0; i < BUF_SIZE;i++ ) { // First look for overload if ( inbuf[i] > 0.9 ) overload = true; // Apply Hamming to Data outbuf[i] = inbuf[i]*( 0.54 - 0.46 * cos ( ( i * PI2 ) / BUF_SIZE ) ); } fftw_execute ( plan ); //Calculate power spectrum for ( int i = 1;i < BUF_SIZE / 2;i++ ) // output[i] = output[i] * output[i] + output[BUF_SIZE-i] * output[BUF_SIZE-i]; outbuf[i] = output[i] * output[i] + output[BUF_SIZE-i] * output[BUF_SIZE-i]; emit startPlotting ( outbuf, overload ); for ( CRxChannel * p = RxChannel;p != 0;p = p->getNextChannel() ) { p->processInput ( inbuf, outbuf ); } /** Update IMD for the active Channel **/ emit new_IMD ( settings.ActChannel->getIMD() ); } void CRxDisplay::addRxWindow ( int Frequency, Mode Modulation, QString Heading ) { CRxChannel *p; int ID = RxHeader->count(); p = new CRxChannel ( ID, this, Modulation, Frequency ); RxHeader->insertTab ( ID, p->getWindow(),Heading ); connect ( p, SIGNAL ( Triggered ( int ) ), this, SLOT ( changeActiveRxWindow ( int ) ) ); connect ( p->RxWindow, SIGNAL ( setQsoData(QsoData,QString) ), this, SIGNAL ( setQsoData(QsoData,QString) ) ); RxChannel->insertChannel ( p ); RxHeader->setCurrentIndex ( ID ); 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(); CRxChannel *p; p=settings.ActChannel; if ( p != 0 ) { p->hide(); p->setQsoData ( settings.QslData ); // Save actual Data to Channel p->setAfcMode ( RxFreq->getAfcMode() ); if ( p->getChannel ( ID ) != 0 ) settings.ActChannel = p->getChannel ( ID ); p=settings.ActChannel; settings.QslData = p->getQsoData(); RxFreq->setAfcDisplayMode ( p->AfcProperties() ); RxFreq->setAfcMode ( p->getAfcMode() ); RxFreq->setFrequency ( ( unsigned int ) p->getRxFrequency() ); Squelch->setSquelchState ( p->getSquelchState() ); Squelch->setThreshold ( p->getThreshold() ); TriggerText->setText ( p->RxWindow->getTriggerText() ); triggerActivate->setChecked(p->RxWindow->getTriggerStatus()); recordActivate->setChecked ( p->RxWindow->getRecordingState() ); p->show(); emit newActiveChannel(); RxHeader->setCurrentIndex ( ID ); } } void CRxDisplay::stop_process_loop() { if ( Sound != 0 ) { Sound->stop(); Sound->wait(); Sound->close_Device(); } } void CRxDisplay::trigger() { settings.ActChannel->RxWindow->activateTrigger ( TriggerText->text() ); if ( !triggerActivate->isChecked() ) settings.ActChannel->RxWindow->deactivateTrigger(); } void CRxDisplay::setColorList ( QList *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 ) ); } void CRxDisplay::setAfc(AfcMode mode) { RxFreq->setAfcMode ( mode ); } void CRxDisplay::setAfcProperties(AfcMode mode) { RxFreq->setAfcDisplayMode ( mode ); } AfcMode CRxDisplay::getAfcMode() { return RxFreq->getAfcMode(); } void CRxDisplay::record(bool b) { settings.ActChannel->record(b); } void CRxDisplay::stopRecording() { //Stop recording for each channel if activated and close file. for ( CRxChannel * p = RxChannel;p != 0;p = p->getNextChannel() ) p->record(false); } linpsk-1.3.5/gui/crxdisplay.h000066400000000000000000000045731304636156700161630ustar00rootroot00000000000000/*************************************************************************** * * * 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 #include #include #include "constants.h" #include "ui_crxdisplay.h" class Input; class QTimer; class QPushButton; class CRxChannel; class CRxDisplay : public QFrame , private Ui::CRxDisplay { 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(); void setColorList ( QList *c ); AfcMode getAfcMode(); void stopRecording(); public slots: /** Starting receiving/transmitting */ void addRxWindow ( int Frequency, Mode Modulation, QString Heading ); void setRxFrequency ( double ); void setAfc(AfcMode mode); void setAfcProperties(AfcMode mode); protected: protected slots: virtual void languageChange(); void process_rxdata(); void changeActiveRxWindow ( int ); void trigger(); void clearRxWindow(); void record(bool); private: QList *Farbe; /** Sound is a pointer to the Input Source, may be a File with Demo Samples (text or wav), or the soundcard **/ Input *Sound; /** Pointer to input Buffer **/ 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[BUF_SIZE]; // double *m_pDec2InPtr; // double output[BUF_SIZE/2]; double output[BUF_SIZE]; fftw_plan plan; signals: void startPlotting ( double *, bool ); void newActiveChannel(); void new_IMD ( float ); void setQsoData(QsoData,QString); }; #endif // CRXDISPLAY_H linpsk-1.3.5/gui/crxdisplay.ui000066400000000000000000000201541304636156700163420ustar00rootroot00000000000000 CRxDisplay 0 0 636 186 QFrame::NoFrame QFrame::Plain 0 2 2 0 Qt::NoFocus -1 Qt::Horizontal 546 20 0 13 16777215 17 Qt::NoFocus Clear 1 QLayout::SetDefaultConstraint 0 30 9 2 2 2 RecordQso 0 70 Trigger Qt::AlignCenter 2 2 2 0 18 CQ CQ Activate 0 70 Rx Frequency / AFC 80 0 Squelch FrequencySelect QGroupBox
frequencyselect.h
1 FrequencyChanged(double)
CSquelch QGroupBox
csquelch.h
1
TabWidget QTabWidget
tabwidget.h
1
RxFreq FrequencyChanged(double) CRxDisplay setRxFrequency(double) 79 230 441 140 RxHeader currentChanged(int) CRxDisplay changeActiveRxWindow(int) 561 129 441 140 Clear clicked() CRxDisplay clearRxWindow() 833 258 441 140 triggerActivate clicked() CRxDisplay trigger() 86 161 441 140 TriggerText returnPressed() CRxDisplay trigger() 86 133 441 140 recordActivate toggled(bool) CRxDisplay record(bool) 86 54 441 140 setRxFrequency(double) changeActiveRxWindow(int) clearRxWindow() trigger() record(bool)
linpsk-1.3.5/gui/ctxdisplay.cpp000066400000000000000000000041111304636156700165040ustar00rootroot00000000000000/*************************************************************************** |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 "txwindow.h" #include "frequencyselect.h" /* * Constructs a CTxDisplay which is a child of 'parent', with the * name 'name'.' */ CTxDisplay::CTxDisplay( QWidget* parent ) : QFrame( parent), Ui::CTxDisplay() { setupUi(this); TxFreq->setFunctionText("Net"); TxFreq->setAfcDisplayMode(Narrow); TxFreq->setAfcMode(Narrow); connect(TxFunctions,SIGNAL(startRx()),this,SIGNAL(startRx())); connect(TxFunctions,SIGNAL(startTx()),this,SIGNAL(startTx())); connect(TxFunctions,SIGNAL(abortTx()),this,SIGNAL(abortTx())); 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::resizeEvent( QResizeEvent * ) { TxFunctions->setFixedSize(QSize(height()-20,height()-20)); } void CTxDisplay::insert(QString s) { txWindow->insertString(s); } void CTxDisplay::setTxFocus() { txWindow->setFocus(); } void CTxDisplay::switch2Rx() { TxFunctions->setStatus(SW); } linpsk-1.3.5/gui/ctxdisplay.h000066400000000000000000000030171304636156700161550ustar00rootroot00000000000000/*************************************************************************** |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 #include "ui_ctxdisplay.h" class CTxDisplay : public QFrame, public Ui::CTxDisplay { Q_OBJECT public: CTxDisplay( QWidget* parent = 0); ~CTxDisplay(); void insert(QString s); void setTxFocus(); void switch2Rx(); public slots: // void abbruch(); protected: void resizeEvent( QResizeEvent * ); protected slots: virtual void languageChange(); private: signals: void startRx(); void startTx(); void abortTx(); }; #endif // CTXDISPLAY_H linpsk-1.3.5/gui/ctxdisplay.ui000066400000000000000000000060631304636156700163470ustar00rootroot00000000000000 CTxDisplay 0 0 636 100 Frame QFrame::StyledPanel QFrame::Raised 1 2 6 QLayout::SetMinimumSize 2 150 0 150 16777215 Tx Freq Qt::AlignCenter 0 0 40 40 &RX Qt::StrongFocus QFrame::StyledPanel QFrame::Raised FrequencySelect QGroupBox
frequencyselect.h
1 FrequencyChanged(double)
CLedButton QPushButton
cledbutton.h
TxWindow QFrame
txwindow.h
1
linpsk-1.3.5/gui/definebandlist.cpp000066400000000000000000000121461304636156700173020ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2012 by Volker Schroer, DL1KSV * * * * 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 "definebandlist.h" #include "ui_definebandlist.h" #include "parameter.h" #include extern Parameter settings; DefineBandList::DefineBandList(QWidget *parent) : QDialog(parent), ui(new Ui::DefineBandList) { int rows; int i,j; ui->setupUi(this); rows = settings.bandList.size(); for(i=0; i < rows; i++) { ui->bandDefinitions->insertRow(i); // if(i < (rows-1)) ui->bandDefinitions->setItem(i,0,new QTableWidgetItem(settings.bandList.at(i).bandName)); for(j=1; j < 4; j++) { QLineEdit *line =new QLineEdit; line->setAlignment(Qt::AlignRight); line->setInputMask("00000000000D"); ui->bandDefinitions->setCellWidget(i,j,line); // if(i < (rows-1) ) // { if (j == 1 ) line->setText(QString("%1").arg(settings.bandList.at(i).bandStart)); else if ( j == 2 ) line->setText(QString("%1").arg(settings.bandList.at(i).bandEnd)); else line->setText(QString("%1").arg(settings.bandList.at(i).preferedFreq)); // } } } ui->bandDefinitions->setCurrentCell(rows-1,0); ui->bandDefinitions->setFocus(); ui->bandDefinitions->resizeColumnsToContents(); } DefineBandList::~DefineBandList() { delete ui; } void DefineBandList::accept() { QLineEdit *lE; settings.bandList.clear(); for(int i=0; i < ui->bandDefinitions->rowCount(); i++) { Band b; QTableWidgetItem *it=ui->bandDefinitions->item(i,0); if( it != NULL) b.bandName = it->text(); else break; lE= (QLineEdit *) ui->bandDefinitions->cellWidget(i,1); if ( lE != NULL) b.bandStart= lE->text().toInt(); else break; lE = (QLineEdit *) ui->bandDefinitions->cellWidget(i,2); if ( lE != NULL) b.bandEnd= lE->text().toInt(); else break; lE = (QLineEdit *) ui->bandDefinitions->cellWidget(i,3); if ( it != NULL) b.preferedFreq= lE->text().toInt(); else break; // To do: Check if definition ist consistent settings.bandList << b; } QDialog::accept(); } void DefineBandList::addRow() { int row; row= ui->bandDefinitions->rowCount(); ui->bandDefinitions->insertRow(row); for(int j=1; j < 4; j++) { QLineEdit *line =new QLineEdit; line->setAlignment(Qt::AlignRight); line->setInputMask("00000000000D"); ui->bandDefinitions->setCellWidget(row,j,line); } } void DefineBandList::deleteRow() { int row; row=ui->bandDefinitions->currentRow(); ui->bandDefinitions->removeRow(row); } void DefineBandList::rowUp() { QTableWidgetItem *it; QLineEdit *line1; QLineEdit *line0; int row; row=ui->bandDefinitions->currentRow(); if(row == 0) return; it=ui->bandDefinitions->takeItem(row-1,0); ui->bandDefinitions->setItem(row-1,0,ui->bandDefinitions->takeItem(row,0)); ui->bandDefinitions->setItem(row,0,it); for (int i=1; i < 4; i++) { line1 = (QLineEdit *)ui->bandDefinitions->cellWidget(row-1,i); line0 = (QLineEdit *)ui->bandDefinitions->cellWidget(row,i); QString s = line1->text(); line1->setText(line0->text()); line0->setText(s); } } void DefineBandList::rowDown() { QTableWidgetItem *it; QLineEdit *line1; QLineEdit *line0; int row; row=ui->bandDefinitions->currentRow(); if(row >=(ui->bandDefinitions->rowCount()-1) ) return; it=ui->bandDefinitions->takeItem(row+1,0); ui->bandDefinitions->setItem(row+1,0,ui->bandDefinitions->takeItem(row,0)); ui->bandDefinitions->setItem(row,0,it); for (int i=1; i < 4; i++) { line1 = (QLineEdit *)ui->bandDefinitions->cellWidget(row+1,i); line0 = (QLineEdit *)ui->bandDefinitions->cellWidget(row,i); QString s = line1->text(); line1->setText(line0->text()); line0->setText(s); } } linpsk-1.3.5/gui/definebandlist.h000066400000000000000000000034171304636156700167500ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2012 by Volker Schroer, DL1KSV * * * * 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 DEFINEBANDLIST_H #define DEFINEBANDLIST_H #include namespace Ui { class DefineBandList; } class DefineBandList : public QDialog { Q_OBJECT public: explicit DefineBandList(QWidget *parent = 0); ~DefineBandList(); private: Ui::DefineBandList *ui; public slots: virtual void accept(); void addRow(); void deleteRow(); void rowUp(); void rowDown(); }; #endif // DEFINEBANDLIST_H linpsk-1.3.5/gui/definebandlist.ui000066400000000000000000000133141304636156700171330ustar00rootroot00000000000000 DefineBandList 0 0 675 296 Define Bands Delete row Qt::Vertical 20 40 true To select row click Band name Row up Add row Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok QAbstractItemView::SingleSelection QAbstractItemView::SelectItems true 0 false 100 true false Band Name Startfrequency Endfrequency Preferred frequency Set Frequency to switch to AlignCenter true To select row click Band name Row down buttonBox accepted() DefineBandList accept() 248 254 157 274 buttonBox rejected() DefineBandList reject() 316 260 286 274 addButton clicked() DefineBandList addRow() 48 234 308 129 deleteButton clicked() DefineBandList deleteRow() 134 234 308 129 upButton clicked() DefineBandList rowUp() 568 162 308 129 downButton clicked() DefineBandList rowDown() 568 193 308 129 addRow() deleteRow() rowUp() rowDown() linpsk-1.3.5/gui/deletemacro.cpp000066400000000000000000000054301304636156700166110ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2012 - 2016 by Volker Schroer, DL1KSV * * * * 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 "ui_deletemacro.h" #include "readonlystringlistmodel.h" DeleteMacro::DeleteMacro (QVector *macroList, QWidget* parent) : QDialog ( parent), ui(new Ui::DeleteMacro) { ui->setupUi ( this ); mL = macroList; model = new ReadOnlyStringListModel ( ); QStringList macroName; int numberofMacros=macroList->size(); if (numberofMacros > 0 ) for(int i=0; i < numberofMacros;i++) macroName.append((*macroList).at(i).name); model->setStringList(macroName); deleteList = new ReadOnlyStringListModel ( this ); ui->MacroBox->setModel ( model ); ui->Macrostodelete->setModel ( deleteList ); } DeleteMacro::~DeleteMacro() { if ( model != 0 ) delete model; delete deleteList; delete ui; } 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 < mL->size();k++ ) { if ( mL->at ( k ).name == s ) { mL->remove ( k ,1); break; } } } } QDialog::accept(); } void DeleteMacro::addtoList() { QStringList l = deleteList->stringList(); l << ui->MacroBox->currentIndex().data().toString(); deleteList->setStringList ( l ); } void DeleteMacro::removefromList() { deleteList->removeRows ( ui->Macrostodelete->currentIndex().row(), 1 ); } linpsk-1.3.5/gui/deletemacro.h000066400000000000000000000036561304636156700162660ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2012 - 2016 by Volker Schroer, DL1KSV * * * * 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 #include "constants.h" namespace Ui { class DeleteMacro; } class ReadOnlyStringListModel; class DeleteMacro : public QDialog { Q_OBJECT public: DeleteMacro(QVector *macroList,QWidget* parent = 0 ); ~DeleteMacro(); public slots: /*$PUBLIC_SLOTS$*/ protected: ReadOnlyStringListModel *model; ReadOnlyStringListModel *deleteList; protected slots: virtual void accept(); void removefromList(); void addtoList(); private: Ui::DeleteMacro *ui; QVector *mL; }; #endif linpsk-1.3.5/gui/deletemacro.ui000066400000000000000000000204161304636156700164450ustar00rootroot00000000000000 DeleteMacro 0 0 415 279 250 200 600 400 300 100 Delete Macro 80 25 200 16777215 Available Macros Qt::PlainText false 0 0 300 16777215 130 100 Qt::Vertical 88 21 Qt::Horizontal 117 20 6 80 25 Macros to be deleted Qt::PlainText false 0 0 60 25 Delete Qt::Horizontal QSizePolicy::Expanding 13 20 60 25 Cancel Qt::Vertical 20 70 0 0 100 15 16777215 20 Add to list -> 0 0 130 15 200 20 Remove from list <- Qt::Vertical 20 69 qPixmapFromMimeSource Ok clicked() DeleteMacro accept() 20 20 20 20 Cancel clicked() DeleteMacro reject() 20 20 20 20 Add clicked() DeleteMacro addtoList() 307 134 299 145 Remove clicked() DeleteMacro removefromList() 307 160 299 145 addtoList() removefromList() linpsk-1.3.5/gui/editmacro.cpp000066400000000000000000000073511304636156700163000ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2012 - 2016 by Volker Schroer, DL1KSV * * * * 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 "ui_editmacro.h" #include "readonlystringlistmodel.h" #include EditMacro::EditMacro(QVector *macroList,QStringList tokenList, QWidget* parent) : QDialog( parent ), ui(new Ui::EditMacro) { ui->setupUi(this); mL=macroList; int anzahl=macroList->size(); model=new ReadOnlyStringListModel(); model->setStringList(tokenList); ui->Keywords->setModel(model); ui->Position->setMaximum(anzahl); ui->SelectMacro->insertItem(0,"Choose macro"); for(int i=0; i < anzahl; i++) ui->SelectMacro->insertItem(i+1,(*macroList).at(i).name); ui->bG->setId(ui->lang0,0); ui->bG->setId(ui->lang1,1); ui->bG->setId(ui->lang2,2); } EditMacro::~EditMacro() { delete ui; } void EditMacro::accept() { int aktPosition,newPosition; aktPosition=ui->SelectMacro->currentIndex()-1; if (aktPosition < 0) { QMessageBox::warning(this,"Edit macro","No macro selected \n Select correct macro", QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton); return; } Macro macro; newPosition=ui->Position->value(); macro=(*mL).at(aktPosition); macro.text=ui->Definition->toPlainText(); macro.accelerator=ui->Accelerator->text(); int langType=ui->bG->checkedId(); if(macro.languageType < 0) //Deactivated macro.languageType = langType-3; if(aktPosition < newPosition) // Macro should be moved behind { mL->insert(newPosition,macro); //First insert then remove mL->remove(aktPosition); } else if (aktPosition > newPosition) // Macro should be moved forward { mL->remove(aktPosition); // First remove, then insert mL->insert(newPosition,macro); } else mL->replace(aktPosition, macro); QDialog::accept(); } void EditMacro::setText( int Number) { int langType; if( Number > 0) { Number--; ui->Position->setValue(Number); ui->Definition->setText((*mL).at(Number).text); ui->Accelerator->setText((*mL).at(Number).accelerator); langType=(*mL).at(Number).languageType; if(langType <0 ) langType +=3; if ((langType <0) || (langType > 2 ) ) //Check range if config file was wrongly modified langType=0; ui->bG->button(langType)->setChecked(true); } } void EditMacro::insertKeyword(QModelIndex index) { QString s=index.data().toString(); ui->Definition->insertPlainText(s); ui->Definition->setFocus(); } linpsk-1.3.5/gui/editmacro.h000066400000000000000000000036621304636156700157460ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2012 - 2016 by Volker Schroer, DL1KSV * * * * 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 #include #include #include "constants.h" namespace Ui { class EditMacro; } class ReadOnlyStringListModel; class EditMacro : public QDialog { Q_OBJECT public: EditMacro(QVector *macroList,QStringList tokenList,QWidget* parent = 0 ); ~EditMacro(); public slots: protected: ReadOnlyStringListModel *model; protected slots: virtual void accept(); void setText( int Number); void insertKeyword(QModelIndex); private: Ui::EditMacro *ui; QVector *mL; }; #endif linpsk-1.3.5/gui/editmacro.ui000066400000000000000000000141501304636156700161260ustar00rootroot00000000000000 EditMacro 0 0 578 293 600 320 EditMacro true Select from list -1 Accelerator false Position false Definition false Keywords false Language selection both true bG english bG german bG Qt::Vertical 20 77 &OK true true &Cancel true qPixmapFromMimeSource buttonOk clicked() EditMacro accept() 20 20 20 20 buttonCancel clicked() EditMacro reject() 20 20 20 20 SelectMacro activated(int) EditMacro setText(int) 20 20 20 20 Keywords clicked(QModelIndex) EditMacro insertKeyword(QModelIndex) 329 155 288 146 insertKeyword(QModelIndex) linpsk-1.3.5/gui/generalsettings.cpp000066400000000000000000000166121304636156700175270ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2007 by volker, DL1KSV * * schroer@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 #include #include #include "readonlystringlistmodel.h" #include #include #ifdef WITH_HAMLIB #include #endif extern Parameter settings; GeneralSettings::GeneralSettings ( QWidget* parent, Qt::WindowFlags fl ) : QDialog ( parent, fl ), Ui::GeneralSettings() { setupUi ( this ); #ifndef WITH_HAMLIB Rignumber->hide(); modelNr->hide(); commParams->hide(); Rigdevice->hide(); rigControl->hide(); #endif QString DirectoryName; QDir dir; QString s; int index; LocalSettings = settings; 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); autoDate->setChecked(LocalSettings.autoDate); 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 ) ) ); if ( Demomode->isChecked() ) selectDemomode(true); else selectDemomode(false); //PTT and Rig // First look in the /dev Directory DirectoryName = "/dev/"; dir.setPath ( DirectoryName ); QStringList filenames; //Check for serial and usb to serial devices filenames << "ttyS*" << "ttyUSB*"; 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 ) ); // PTT pttDevice->addItem(QLatin1String("None")); pttDevice->addItems(Files); index=pttDevice->findText(LocalSettings.SerialDevice); if(index > 0) pttDevice->setCurrentIndex(index); else pttDevice->setCurrentIndex(0); // Rig rigControl->addItem(QLatin1String("None")); rigControl->addItems(Files); index=rigControl->findText(LocalSettings.rigDevice); if(index > 0) rigControl->setCurrentIndex(index); else rigControl->setCurrentIndex(0); // Sound Devices QStringList cards=getSoundCards(); soundInputDeviceName->addItems(cards); soundInputDeviceName->addItem(QLatin1String("LinPSK_Record")); index=soundInputDeviceName->findText(LocalSettings.InputDeviceName); if(index >=0) soundInputDeviceName->setCurrentIndex(index); soundOutputDeviceName->addItems(cards); soundOutputDeviceName->addItem(QLatin1String("LinPSK_Play")); index=soundOutputDeviceName->findText(LocalSettings.OutputDeviceName); if(index >= 0) soundOutputDeviceName->setCurrentIndex(index); //Logging Directory->setText ( LocalSettings.Directory ); QsoFile->setText ( LocalSettings.QSOFileName ); fileLog->setChecked ( LocalSettings.fileLog ); Directory->setDisabled ( !LocalSettings.fileLog ); QsoFile->setDisabled ( !LocalSettings.fileLog ); LinLog->setChecked ( LocalSettings.LinLog ); Port->setDisabled ( !LocalSettings.LinLog ); Host->setDisabled ( !LocalSettings.LinLog ); // Rig number modelNr->setText(QString("%1").arg(LocalSettings.rigModelNumber)); // Rig- Serial handShake->setCurrentIndex(LocalSettings.handshake); baudRate->setCurrentIndex(baudRate->findText(QString("%1").arg(LocalSettings.baudrate),Qt::MatchExactly)); } GeneralSettings::~GeneralSettings() {} Parameter GeneralSettings::getSettings() { LocalSettings.callsign = Callsign->text(); LocalSettings.myLocator = myLocator->text(); if ( Demomode->isChecked() ) { LocalSettings.DemoMode = true; LocalSettings.inputFilename = ""; } else { LocalSettings.DemoMode = false; LocalSettings.InputDeviceName=soundInputDeviceName->currentText(); LocalSettings.OutputDeviceName=soundOutputDeviceName->currentText(); } LocalSettings.timeoffset = UTC->value(); LocalSettings.slashed0 = SlashedZero->isChecked(); LocalSettings.autoCrLf = autoCrLf->isChecked(); LocalSettings.autoDate=autoDate->isChecked(); LocalSettings.SerialDevice = pttDevice->currentText(); LocalSettings.rigDevice=rigControl->currentText(); 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(); // Rig parameter #ifdef WITH_HAMLIB LocalSettings.rigModelNumber=modelNr->text().toInt(); LocalSettings.baudrate=baudRate->currentText().toInt(); LocalSettings.handshake=static_cast(handShake->currentIndex()); #else LocalSettings.rigModelNumber=0; #endif return LocalSettings; } void GeneralSettings::selectDemomode ( bool mode ) { if ( mode ) SoundDeviceBox->hide(); else SoundDeviceBox->show(); } void GeneralSettings::selectFileLogging ( bool b) { Directory->setDisabled ( !b); QsoFile->setDisabled ( !b ); } void GeneralSettings::selectLinLogLogging ( bool b ) { Port->setDisabled ( !b ); Host->setDisabled ( !b ); } void GeneralSettings::setSampleRate(QString s) { LocalSettings.sampleRate=s.toInt(); } void GeneralSettings::setComplexFormat(bool b) { LocalSettings.complexFormat=b; } QStringList GeneralSettings::getSoundCards() { QString line; QFile cards( "/proc/asound/cards" ); QStringList cardList; int pos; cardList << "None"; if (!cards.open(QIODevice::ReadOnly | QIODevice::Text)) return cardList; QTextStream in(&cards); cardList.clear(); do { line = in.readLine(); pos=line.indexOf(QLatin1String(": ")); if(pos > 0) cardList << line.mid(pos+1); } while (!in.atEnd()); if(cardList.isEmpty()) cardList << "None"; cards.close(); return cardList; } linpsk-1.3.5/gui/generalsettings.h000066400000000000000000000040521304636156700171670ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2007 by volker, DL1KSV * * schroer@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 #include #include "ui_generalsettings.h" class Parameter; class QButtonGroup; class QModelIndex; class QMenu; class GeneralSettings : public QDialog, private Ui::GeneralSettings { Q_OBJECT public: GeneralSettings(QWidget* parent = 0, Qt::WindowFlags fl = 0 ); ~GeneralSettings(); Parameter getSettings(); public slots: protected: QButtonGroup *FileFormat; Parameter LocalSettings; QMenu * selectionMenu; protected slots: void selectDemomode(bool); void selectFileLogging(bool); void selectLinLogLogging(bool); void setSampleRate(QString s); void setComplexFormat(bool); QStringList getSoundCards(); }; #endif linpsk-1.3.5/gui/generalsettings.ui000066400000000000000000000445651304636156700173720ustar00rootroot00000000000000 GeneralSettings 0 0 787 428 0 0 650 300 650 300 Qt::ClickFocus LinPSK General Settings true QFrame::NoFrame QFrame::Plain Callsign false Time Offset to UTC false -12 12 Qt::Horizontal 178 20 Locator Date Format describes the format displaying the date within qsodata dd.MM.yyyy yyyy-MM-dd Qt::Horizontal 178 20 Qt::Horizontal 283 20 150 0 Set Date qso saving true false Display Zero as Slashed Zero false true Send CR LF on enter Rig Comm Parameter Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter Baudrate Select Baudrate 3 1200 2400 4800 9600 19200 38400 57600 Handshake Select Handshake 1 3 None Hardware XonXoff QFrame::StyledPanel QFrame::Raised Demomode Logging File logging Log to File true false Working Directory Filename QSO.adif 8 LinLog logging Log to LinLog false LinLog Host Name localhost Port 1024 64000 8080 Rig Devices Rig number Set Rig number as defined in hamlib 0999 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter PTT device Rig device Sound Device Input card or device Output card or device 80 20 Qt::ClickFocus &Ok Alt+O false false 80 20 Qt::ClickFocus &Cancel false false false Qt::Horizontal 40 20 Qt::Horizontal 358 20 qPixmapFromMimeSource Callsign UTC Demomode fileLog Directory QsoFile LinLog Host Port parameter.h buttonOk clicked() GeneralSettings accept() 20 20 20 20 buttonCancel clicked() GeneralSettings reject() 20 20 20 20 Demomode clicked(bool) GeneralSettings selectDemomode(bool) 324 115 393 213 LinLog clicked(bool) GeneralSettings selectLinLogLogging(bool) 683 154 393 213 fileLog clicked(bool) GeneralSettings selectFileLogging(bool) 511 154 393 213 selectDemomode(bool) setControlDevice(QModelIndex) selectLinLogLogging(bool) selectFileLogging(bool) setRigNumber() linpsk-1.3.5/gui/linpsk.cpp000066400000000000000000001067571304636156700156430ustar00rootroot00000000000000/*************************************************************************** * * * 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 "addrxwindow.h" #include "bpskmodulator.h" #include "controlpanel.h" #include "crxdisplay.h" #include "ctxdisplay.h" #include "parameter.h" #include "spectrumdisplay.h" #include "frequencyselect.h" #include "cledbutton.h" #include "rttymodulator.h" #include "pskmodulator.h" #include "psk63modulator.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 "addmacro.h" #include "deletemacro.h" #include "activatemacros.h" #include "qsodata.h" #include "editmacro.h" #include "deletemacro.h" #include "renamemacro.h" #include "color.h" #include "definebandlist.h" #ifdef WITH_HAMLIB #include "rigcontrol.h" #endif #include #include #include #include #include #include #include #define VERSION "1.3.5" #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) : QMainWindow ( parent), Ui::LinPSK() { Sound = 0; Modulator = 0; inAction=false; // Content of modeList must correspond to enum Mode in constants.h modeList << "BPSK31" << "BPSK63" << "QPSK" << "RTTY" << "MFSK16" ; #ifdef WITH_HAMLIB settings.rig =new RigControl(); #endif /** To avoid multipe Macro clicking **/ blockMacros=false; /************************************/ SaveParameters = new Parameter(); setupUi(this); read_config(); apply_settings(); /** Fixme: handle font change: fontChange() **/ 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] ; setWindowTitle ( QString ( ProgramName ) + QString ( VERSION ) ); setWindowIcon ( QIcon ( ":/images/linpsk.png" ) ); // Create Statusbar statusBar()->setFixedHeight(18); statusbar->setSizeGripEnabled ( true ); //Messages msg = new QLabel ( ); statusbar->addPermanentWidget ( msg, 2 ); msg->setText ( tr ( "Ready" ) ); #ifdef WITH_HAMLIB rigInfo =new QLabel(); statusbar->addPermanentWidget(rigInfo,1); if((settings.rigModelNumber > 0) && settings.rigDevice != "None") { int rc=-settings.rig->connectRig(); if(rc != RIG_OK) { switch(rc) { case RIG_EINVAL : QMessageBox::warning(0,"Invalid parameter",QLatin1String("Probably unknown rig")); rigInfo->setText("Rig: None"); break; case RIG_ETIMEOUT: default: if(rc != RIG_ETIMEOUT) QMessageBox::warning(0,"Connection time out",QLatin1String(rigerror(rc))); if(QMessageBox::question ( 0,"Connection time out" , tr ( "Could not connect to rig\nTry again ?" ), QMessageBox::Yes | QMessageBox::No ) == QMessageBox::Yes) { rc=-settings.rig->connectRig(); if( rc != RIG_OK) { QMessageBox::warning(0,"Connection time out",QLatin1String(rigerror(rc))); rigInfo->setText("Rig: None"); } else rigInfo->setText(QLatin1String("Rig: ")+settings.rig->getModelName()); } else rigInfo->setText("Rig: None"); break; } } else { rigInfo->setText(QLatin1String("Rig: ")+settings.rig->getModelName()); } if( rc == RIG_OK) { } } #endif Control->initQsoData(); // 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->setAfcProperties(settings.ActChannel->AfcProperties()); RxDisplay->setAfc(settings.ActChannel->getAfcMode()); RxDisplay->setColorList ( &WindowColors ); settings.QslData = settings.ActChannel->getQsoData(); Control->setPhasePointer ( settings.ActChannel->getPhasePointer() ); Control->setColorList ( &WindowColors ); languageChange(); // signals and slots connections //========== Macro Processing ====================================== tokenList << "@CALLSIGN@" << "@DATE@" << "@Replace by filename@" << "@RX@" << "@THEIRCALL@" << "@THEIRNAME@"; tokenList << "@TIMELOCAL@" << "@TIMEUTC@" << "@TX@" << "@RSTGIVEN@" << "@RSTRCVD@" <<"@TXPWR@"; Control->insertMacros( ¯oList ); connect ( this, SIGNAL ( StartRx() ), this, SLOT ( startRx() ) ); connect ( this, SIGNAL ( StartTx() ), this, SLOT ( startTx() ) ); //=================================================================== TxBuffer = new CTxBuffer(); TxDisplay->txWindow->setTxBuffer ( TxBuffer ); } /* * 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" ), "", "*.wav" ); 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::helpAbout() { QMessageBox::about(this, QString(tr("About LinPsk")), QString(tr("

About LinPsk

LinPsk is a PSK31 program for Linux by Volker Schroer, DL1KSV. It supports some other digital modes and is developed under GPL
( Read the file COPYING contained in the distribution for more information )

"))); } void LinPSK::helpAboutQt() { QMessageBox::aboutQt(this); } void LinPSK::addRxWindow() { AddRxWindow *Channel = new AddRxWindow(modeList); if ( Channel->exec() != 0 ) { AfcMode modus; modus = RxDisplay->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->setAfcProperties( settings.ActChannel->AfcProperties() ); } } 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(inAction) return; inAction=true; if ( Modulator != 0 && !settings.DemoMode) { TxBuffer->insert ( TXOFF_CODE ); if ( Sound != NULL ) // Switch Trx to rx { TxDisplay->switch2Rx(); msg->setText ( tr ( "Switching to receive" ) ); while ( Sound->isRunning() ) // Wait for buffer to be cleared qApp->processEvents ( QEventLoop::AllEvents, 100 ); } } if ( RxDisplay->start_process_loop() ) { TxDisplay->TxFunctions->setStatus ( OFF ); if ( settings.ActChannel != 0 ) msg->setText ( tr ( "Receiving " ) + modeList[settings.ActChannel->getModulationType()] ); } else TxDisplay->TxFunctions->setStatus ( UNDEF ); Control->present(true); settings.Status = TxDisplay->TxFunctions->getstatus(); TxDisplay->txWindow->setFocus(); inAction=false; } void LinPSK::startTx() { Mode ModulationType; QString errorstring; 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 ); break; case BPSK31: Modulator = new BpskModulator ( 11025, Frequency, TxBuffer ); break; case BPSK63: Modulator = new Psk63Modulator ( 11025, Frequency, TxBuffer ); break; case RTTY: Modulator = new RTTYModulator ( 11025, Frequency, TxBuffer ); if ( settings.ActChannel->getParameter ( Extra ) != 0 ) Modulator->setParameter ( Extra, settings.ActChannel->getParameter ( Extra ) ); break; case MFSK16: Modulator = new MFSKModulator ( 11025, Frequency, TxBuffer ); break; /** default: Modulator = new BpskModulator ( 11025, Frequency, TxBuffer ); break; */ } if ( Sound <= NULL ) // Only create Sound Device once for output { if ( settings.DemoMode ) { Sound = new WaveInput ( -1 ); msg->setText ( tr ( "Transmitting (Demo)" ) ); } else Sound = new CSound ( settings.serial ); connect ( Sound, SIGNAL ( samplesAvailable() ), this, SLOT ( process_txdata() ) ); } if ( Sound <= NULL ) { QMessageBox::critical ( 0, " Programm Error! LinPsk", "Could not create Sound Device for Output" ); TxDisplay->TxFunctions->setStatus ( ON ); return; } if ( !Sound->open_Device_write ( &errorstring ) ) { QMessageBox::information ( 0, ProgramName, errorstring ); stopTx(); emit StartRx(); return; } connect ( Modulator, SIGNAL ( charSend ( char ) ), settings.ActChannel, SLOT ( updateRx ( char ) ) ); TxDisplay->TxFunctions->setStatus ( ON ); msg->setText ( tr ( "Transmitting " ) + modeList[ModulationType] ); TxDisplay->txWindow->setFocus(); settings.Status = TxDisplay->TxFunctions->getstatus(); Control->present(false); 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(); #ifdef WITH_HAMLIB int modelNr = settings.rigModelNumber; if( (modelNr >0) && ((modelNr != settings.rigModelNumber) || !settings.rig->isConnected()) ) //Rig has changed { settings.rig->disconnectRig(); int rc = -settings.rig->connectRig(); if(rc != RIG_OK) { switch(rc) { case RIG_ETIMEOUT: QMessageBox::warning(0,"Connection time out",QLatin1String("Could not connect to rig")); break; case RIG_EINVAL : QMessageBox::warning(0,"Invalid parameter",QLatin1String("Probably unknown rig.\nTrying to keep previous one")); break; default: QMessageBox::warning(0,"Connection time out",QLatin1String("Unknown reason")); break; } settings.rigModelNumber=modelNr; // Reconnect here ? if(settings.rig->connectRig() != RIG_OK) return; } } #endif } 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->wait(); Sound->close_Device(); } delete Modulator; Modulator = 0; TxDisplay->txWindow->clearBuffers(); } void LinPSK::apply_settings() { checkControlDevices(); Control->enableSaveData(); Control->setAutoDate(); actionOpen_Demo_File->setEnabled(settings.DemoMode); } void LinPSK::setChannelParams() { Control->setPhasePointer ( settings.ActChannel->getPhasePointer() ); Control->newChannel(); if ( settings.ActChannel != 0 ) msg->setText ( tr ( "Receiving " ) + modeList[settings.ActChannel->getModulationType()] ); RxDisplay->setAfcProperties( settings.ActChannel->AfcProperties() ); } void LinPSK::setRxMode() { ModeMenu Menu(modeList) ; ExtraParameter *Param; ExtraParameter parameter; 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->setAfcProperties( settings.ActChannel->AfcProperties() ); // RxDisplay->setAfc ( settings.ActChannel->getAfcMode() ); Control->setPhasePointer ( settings.ActChannel->getPhasePointer() ); parameter= Menu.getParameter(); settings.ActChannel->setParameter ( Extra, ¶meter ); msg->setText ( tr ( "Receiving " ) + modeList[rxmode] ); } } void LinPSK::save_config() { int i,size; QSettings config ( "DL1KSV", "LinPSK" ); /** Windows Parameter **/ config.beginGroup ( "WindowsParameter" ); config.setValue ( "WindowWidth", width() ); 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.setValue ("ControlSplitter",Control->controlSplitterState()); config.setValue ("SpectrumSplitter",Control->spectrumSplitterState()); config.endGroup(); /** DemoMode **/ config.setValue ( "DemoMode", settings.DemoMode ); //Operating config.setValue ( "Callsign", settings.callsign ); config.setValue ( "MyLocator", settings.myLocator ); //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); config.setValue ("autoDate",settings.autoDate); /** 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 size=macroList.size(); if ( size > 0 ) { config.beginWriteArray ( "Macros" ); for ( i = 0; i < size;i++ ) { config.setArrayIndex ( i ); config.setValue ( "Name", macroList.at( i ).name ); config.setValue ( "Definition", macroList.at(i).text ); config.setValue ( "Accelerator", macroList.at (i ).accelerator ); config.setValue ("Language",macroList.at( i ).languageType); } config.endArray(); } // Bandlist size=settings.bandList.size(); if(size >0) { config.beginWriteArray ("Bandlist"); for(i=0;i < size;i++) { config.setArrayIndex ( i ); config.setValue ( "Bandname", settings.bandList.at( i ).bandName ); config.setValue ( "Bandstart", settings.bandList.at(i).bandStart ); config.setValue ( "Bandend", settings.bandList.at(i).bandEnd ); config.setValue ( "PreferedFrequency",settings.bandList.at(i).preferedFreq); } config.endArray(); } // Rig parameter for use with hamlib config.beginGroup ( "Rigparameter" ); config.setValue ( "PTTDevice", settings.SerialDevice ); config.setValue( "RIGDevice", settings.rigDevice); config.setValue("Modelnr",settings.rigModelNumber); config.setValue("BaudRate",settings.baudrate); config.setValue("Handshake",settings.handshake); config.endGroup(); // SoundDevices config .beginGroup("SoundDevices"); config.setValue("InputDeviceName",settings.InputDeviceName); config.setValue("sampleRate",settings.sampleRate); config.setValue("OutputDeviceName",settings.OutputDeviceName); config.setValue("ComplexFormat",settings.complexFormat); config.endGroup(); } void LinPSK::executeMacro ( int id ) { // qDebug("Execute macro %d",id); if(blockMacros) { qDebug("Macro %d blocked",id); return; } else { blockMacros=true; QTimer::singleShot(1000,this,SLOT(unblockMacros())); } QString macro = macroList.at(id).text; QString Token; QFile *MacroFile; int i,anzahl; bool switchtoRx=false; anzahl = macro.count ( '@' ) / 2; if ( anzahl > 0 ) { int indexbis, indexvon = 0; for ( 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 == tokenList.at(0) ) // callsign { macro.replace ( indexvon, tokenList.at(0).length(), settings.callsign ); } else if ( Token == tokenList.at(1) ) // Date { QDate t = QDate::currentDate(); macro.replace ( indexvon, tokenList.at(1).length(), t.toString ( QString ( "d.MM.yyyy" ) ) ); } else if ( Token == tokenList.at(3) ) // RX { macro.remove ( indexvon, 4 ); switchtoRx=true; } else if ( Token == tokenList.at(4) ) // Remote callsign { macro.replace ( indexvon, tokenList.at(4).length(), settings.QslData->RemoteCallsign ); } else if ( Token == tokenList.at(5) ) // Remote op's name { macro.replace ( indexvon, tokenList.at(5).length(), settings.QslData->OpName ); } else if ( Token == tokenList.at(6) ) // Time Local { QDateTime t; t = QDateTime::currentDateTime(); macro.replace ( indexvon, tokenList.at(6).length(), t.toString ( "h:mm" ) ); } else if ( Token == tokenList.at(7) ) // Time UTC { QDateTime t; t = QDateTime::currentDateTime(); t = t.addSecs ( settings.timeoffset * 3600 ); macro.replace ( indexvon, tokenList.at(7).length(), t.toString ( "h:mm" ) ); } else if ( Token == tokenList.at(8) ) // TX { if ( settings.Status == UNDEF ) { QMessageBox::warning ( 0, "Warning", "Please listen before transmitting", QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton ); return; } if(settings.callsign.isEmpty()) { QMessageBox::warning(0,"Parameter error",QLatin1String("Callsign not set")); TxDisplay->TxFunctions->setStatus ( OFF ); return; } if(macro.contains(tokenList.at(4)) && settings.QslData->RemoteCallsign.isEmpty()) //Check if macro contains remote callsign when switching to tx { QMessageBox::critical(0,"Parameter error",QLatin1String("Remote callsign not set")); TxDisplay->TxFunctions->setStatus ( OFF ); return; } macro.remove ( indexvon, 4 ); if(settings.Status == OFF) emit StartTx(); else //We are alredy transmitting if (!TxBuffer->isEmpty()) return; } else if ( Token == tokenList.at(9) ) // RST given { macro.replace ( indexvon, tokenList.at(9).length(),settings.QslData->MyRST ); } else if ( Token == tokenList.at(10) ) // RST received { macro.replace ( indexvon, tokenList.at(10).length(),settings.QslData->HisRST ); } else if( Token == tokenList.at(11) ) // TXPWR { QString pwr; pwr.setNum(settings.pwr); macro.replace ( indexvon, tokenList.at(11).length(),pwr); } 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 ); if(Token.startsWith(QChar('/'))) // Distinguish between relative and absolute path MacroFile =new QFile( Token ); else MacroFile =new QFile( 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() ); TxDisplay->insert(Txstring); } MacroFile->close(); delete MacroFile; } else QMessageBox::warning ( 0, "Warning", "File " + Token + " not found ", QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton ); } } } anzahl=macro.length(); TxBuffer->insert(macro,anzahl); TxDisplay->setTxFocus(); TxDisplay->insert(macro); if(switchtoRx & (settings.Status == ON)) { TxDisplay->TxFunctions->setStatus(SW); msg->setText ( tr ( "Switching to receive" ) ); emit StartRx(); } } void LinPSK::addMacro() { AddMacro *nM = new AddMacro ( ¯oList,tokenList); if (nM->exec() != 0 ) Control->insertMacros( ¯oList ); delete nM; } void LinPSK::editMacro() { EditMacro * eM = new EditMacro(¯oList,tokenList); if(eM->exec() != 0) Control->insertMacros( ¯oList ); delete eM; } void LinPSK::deleteMacro() { DeleteMacro * dL = new DeleteMacro(¯oList); if ( dL->exec() !=0) { Control->insertMacros( ¯oList ); } delete dL; } void LinPSK::actdeactMacros() { ActivateMacros *act =new ActivateMacros(¯oList); if(act->exec() !=0 ) { Control->insertMacros( ¯oList ); } delete act; } void LinPSK::renameMacro() { RenameMacro *rM = new RenameMacro(¯oList); if(rM->exec() != 0) { Control->updateMacroWindow(rM->getMacroNumber()); } delete rM; } 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 ); Control->restoreSplitterStates(config.value("ControlSplitter").toByteArray(),config.value("SpectrumSplitter").toByteArray()); } config.endGroup(); /** DemoMode **/ settings.DemoMode = config.value ( "DemoMode" ).toBool(); //Operating settings.callsign = config.value ( "Callsign" ).toString(); settings.myLocator = config.value ( "MyLocator" ).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(); settings.autoDate = config.value("autoDate").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 ) { Macro macro; for ( i = 0; i < size;i++ ) { config.setArrayIndex ( i ); macro.name = config.value ( "Name" ).toString(); macro.text = config.value ( "Definition" ).toString(); macro.accelerator = config.value ( "Accelerator" ).toString(); macro.languageType=config.value("Language",0).toInt(); macroList.append(macro); } } config.endArray(); // Bandlist size = config.beginReadArray ("Bandlist"); if(size >0) { Band band; for(i=0;i < size;i++) { config.setArrayIndex ( i ); band.bandName = config.value ( "Bandname" ).toString(); band.bandStart = config.value ( "Bandstart",1).toInt(); band.bandEnd = config.value ( "Bandend",1).toInt(); band.preferedFreq = config.value ( "PreferedFrequency",1).toInt(); settings.bandList.append(band); } } else { Band none; none.bandName = "--"; none.bandStart = 0; none.bandEnd = 60000000; none.preferedFreq=0; settings.bandList.append(none); } config.endArray(); if ( ( HeighttoSet > 0 ) && ( WidthtoSet > 0 ) ) resize ( WidthtoSet, HeighttoSet ); if ( ( X >= 0 ) && ( Y >= 0 ) ) move ( X, Y ); // SoundDevices // Rig parameter for use with hamlib config.beginGroup ( "Rigparameter" ); settings.SerialDevice = config.value ( "PTTDevice" ).toString(); settings.rigDevice = config.value( "RIGDevice").toString(); settings.rigModelNumber = config.value("Modelnr",0).toInt(); settings.baudrate = config.value("BaudRate",9600).toInt(); settings.handshake= config.value("Handshake",1).toInt(); config.endGroup(); config .beginGroup("SoundDevices"); settings.InputDeviceName=config.value("InputDeviceName","LinPSK_Record").toString(); settings.sampleRate=config.value("sampleRate",11025).toInt(); settings.OutputDeviceName=config.value("OutputDeviceName","LinPSK_Play").toString(); settings.complexFormat=config.value("ComplexFormat").toBool(); config.endGroup(); } void LinPSK::checkControlDevices() { int err = 0; settings.serial = -1; int flags = TIOCM_RTS | TIOCM_DTR; if ( settings.SerialDevice != "None" ) { settings.serial = open( settings.SerialDevice.toLatin1().data(), O_EXCL | O_WRONLY ); if ( settings.serial > 0 ) err=ioctl ( settings.serial, TIOCMBIC, &flags ); if( (settings.serial <0) || (err < 0 )) { QMessageBox::critical ( 0, "LinPsk", "Unable to open PTT device " + settings.SerialDevice+"\nCheck if device is available or permission of device" ); settings.SerialDevice = "None"; //Their seems to be a wrong Value in the ConfigFile settings.serial=-1; } } #ifdef WITH_HAMLIB if( (settings.SerialDevice != "None") && (settings.SerialDevice == settings.rigDevice)) { QMessageBox::critical ( 0, "LinPsk", "PTT device and device to control the rig must be different\nPlease change configuration" ); settings.SerialDevice = "None"; settings.rigDevice="None"; return; } if ( settings.rigDevice != "None") { int fd = open( settings.rigDevice.toLatin1().data(), O_EXCL | O_WRONLY ); if ( fd > 0 ) err=ioctl ( fd, TIOCMBIC, &flags ); if( (fd <0) || (err < 0 )) { QMessageBox::critical ( 0, "LinPsk", "Unable to open serial port to control rig" + settings.rigDevice+"\nCheck if device is available or permission of device" ); settings.rigDevice = "None"; //Their seems to be a wrong Value in the ConfigFile } if(fd >0) ::close(fd); } #endif } 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(); RxDisplay->stopRecording(); e->accept(); save_config(); } else { QMessageBox::information ( 0, ProgramName, "You should stop transmitting before closing this window!" ); e->ignore(); } return; } void LinPSK::on_RxDisplay_newActiveChannel() { } void LinPSK::unblockMacros() { blockMacros=false; } void LinPSK::defineBandlist() { DefineBandList *dF = new DefineBandList(); if (dF->exec() != 0 ) Control->initQsoData(); delete dF; } linpsk-1.3.5/gui/linpsk.h000066400000000000000000000060461304636156700152760ustar00rootroot00000000000000/*************************************************************************** * * * 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 #include #include "constants.h" #include "ui_linpsk.h" #include class QActionGroup; class QToolBar; class QMenu; class QCloseEvent; class QLabel; class CModulator; class CTxBuffer; class Input; class Macros; class Parameter; class LinPSK : public QMainWindow, private Ui::LinPSK { Q_OBJECT public: LinPSK( QWidget* parent = 0); ~LinPSK(); public slots: virtual void Exit(); protected: protected slots: virtual void languageChange(); void fileOpen(); void helpAboutQt(); void addRxWindow(); void generalSettings(); void chooseColor(); void helpAbout(); /** Show Time */ void setclock(); /** Set IMD */ void setIMD(float); /** Start Rx **/ void startRx(); /** Start Tx **/ void startTx(); /** Calculate the TX Data **/ void process_txdata(); /** 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(); /** Executing Macros **/ void executeMacro(int id); /** Add Macro **/ void addMacro(); /** Edit Macro **/ void editMacro(); /** Delete Macro **/ void deleteMacro(); /** Rename Macro **/ void renameMacro(); /**Activate /Deactivate Macros**/ void actdeactMacros(); /** Font Settings **/ void FontSetup(); /** Define Bandlist **/ void defineBandlist(); /** Save Settings **/ void saveSettings(); /** Closing this window **/ void closeEvent( QCloseEvent *); private slots: void on_RxDisplay_newActiveChannel(); void unblockMacros(); private: void read_config(); void save_config(); bool inAction; bool blockMacros; 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; #ifdef WITH_HAMLIB QLabel *rigInfo; #endif void checkControlDevices(); /** To show date and time **/ QLabel *datum; QLabel *zeit; QLabel *IMD; QLabel *clockadj; QList WindowColors; /** Macros **/ QVector macroList; QStringList tokenList; /** Digital modes */ QStringList modeList; signals: void StartRx(); void StartTx(); }; #endif // LINPSK_H linpsk-1.3.5/gui/linpsk.ui000066400000000000000000000421021304636156700154550ustar00rootroot00000000000000 LinPSK 0 0 642 479 MainWindow :/images/linpsk.png:/images/linpsk.png 1 1 1 1 0 1 1 1 0 86 10 10 QFrame::StyledPanel QFrame::Sunken 1 2 0 175 10 15 QFrame::StyledPanel QFrame::Sunken 1 2 0 170 10 15 QFrame::StyledPanel QFrame::Sunken 0 0 642 19 File Settings Macro configuration RxParams About About Linpsk About Qt Open Demo File Add Rx Window Exit General Settings Add macro Edit macro Delete macro Rename macro true Font settings Color settings Save settings Change Rx mode Activate/ deactivate Macro Define Bandlist CRxDisplay QFrame
crxdisplay.h
1 startPlotting(double*,bool) new_IMD(float) newActiveChannel() record(bool) setQsoData(QsoData,QString) setFrequency(double)
CTxDisplay QFrame
ctxdisplay.h
1 startRx() startTx() abortTx()
ControlPanel QFrame
controlpanel.h
1 FrequencyChanged(double) executeMacro(int) startPlot(double*,bool) setQsoData(QsoData,QString)
actionOpen_Demo_File triggered() LinPSK fileOpen() -1 -1 399 299 actionAdd_Rx_Window triggered() LinPSK addRxWindow() -1 -1 399 299 actionExit triggered() LinPSK Exit() -1 -1 399 299 actionGeneral_Settings triggered() LinPSK generalSettings() -1 -1 399 299 actionAdd_macro triggered() LinPSK addMacro() -1 -1 399 299 actionEdit_macro triggered() LinPSK editMacro() -1 -1 399 299 actionDelete_macro triggered() LinPSK deleteMacro() -1 -1 399 299 actionRename_macro triggered() LinPSK renameMacro() -1 -1 399 299 actionFont_settings triggered() LinPSK FontSetup() -1 -1 399 299 actionColor_settings triggered() LinPSK chooseColor() -1 -1 399 299 actionSave_settings triggered() LinPSK saveSettings() -1 -1 399 299 actionChange_Rx_mode triggered() LinPSK setRxMode() -1 -1 399 299 actionAbout_Linpsk triggered() LinPSK helpAbout() -1 -1 399 299 actionAbout_Qt triggered() LinPSK helpAboutQt() -1 -1 399 299 RxDisplay startPlotting(double*,bool) Control startPlot(double*,bool) 404 154 405 455 RxDisplay new_IMD(float) LinPSK setIMD(float) 404 154 404 341 Control executeMacro(int) LinPSK executeMacro(int) 405 455 404 341 RxDisplay newActiveChannel() LinPSK setChannelParams() 404 154 404 341 RxDisplay setQsoData(QsoData,QString) Control setQsoData(QsoData,QString) 404 154 405 455 TxDisplay startRx() LinPSK startRx() 405 279 404 341 TxDisplay startTx() LinPSK startTx() 405 279 404 341 actionActivate_deactivate_Macro triggered() LinPSK actdeactMacros() -1 -1 320 239 TxDisplay abortTx() LinPSK stopTx() 320 236 320 239 actionDefine_Bandlist triggered() LinPSK defineBandlist() -1 -1 320 239 fileOpen() addRxWindow() Exit() generalSettings() addMacro() editMacro() deleteMacro() renameMacro() FontSetup() chooseColor() saveSettings() setRxMode() helpAbout() helpAboutQt() setIMD(float) executeMacro(int) setChannelParams() recording(bool) startRx() startTx() actdeactMacros() stopTx() defineBandlist()
linpsk-1.3.5/gui/macrocontrol.cpp000066400000000000000000000071151304636156700170310ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2012 by Volker Schroer, DL1KSV * * * * 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 "macrocontrol.h" #include "ui_macrocontrol.h" #include #include MacroControl::MacroControl(QWidget *parent) : QGroupBox(parent), ui(new Ui::MacroControl) { ui->setupUi(this); displayBox = new QButtonGroup(ui->area); ui->languageBox->setId(ui->lang0,0); ui->languageBox->setId(ui->lang1,1); ui->languageBox->setId(ui->lang2,2); macroLang=ui->languageBox->checkedId(); connect(displayBox,SIGNAL(buttonPressed(int)),this,SIGNAL(executeMacro(int))); } MacroControl::~MacroControl() { delete displayBox; delete ui; } void MacroControl::setMacroLanguage(int lang) { macroLang=lang; displayMacros(); } void MacroControl::insertMacros(QVector *macroList) { QPushButton *pb = 0; int anzahl,i; /** First Check, if box is empty, otherwise delete all entries,as order or even number of macros might have changed ( Delete or edit ) So we don't need extra processing for these cases. **/ anzahl = displayBox->buttons().size(); if ( anzahl > 0) for ( i = 0; i < anzahl; i++ ) // Clean the display box { pb= static_cast (displayBox->button ( i ) ); displayBox->removeButton (pb ); delete pb; } mL=macroList; anzahl=mL->size(); if ( anzahl > 0 ) { for (i = 0; i < anzahl;i++ ) // insert macro buttons { pb = new QPushButton ( mL->at(i).name, ui->area ); pb ->setCheckable(false); pb->setMaximumHeight(20); ui->arrangeButtons->addWidget(pb); displayBox->addButton ( pb, i ); } displayMacros(); } } void MacroControl::displayMacros() { int i, anzahl,lT; anzahl=mL->size(); if ( anzahl > 0 ) { ui->scrollArea->show(); for ( i = 0; i < anzahl;i++ ) // insert macro buttons { lT=mL->at(i).languageType; if(((macroLang == 0) && (lT >0)) || ( lT == macroLang)|| (lT == 0)) displayBox->button(i)->show(); else displayBox->button(i) ->hide(); } } else ui->scrollArea->hide(); } void MacroControl::updateMacroWindow(int macroNumber) { QPushButton *pb = static_cast (displayBox->button ( macroNumber ) ); pb->setText(mL->at(macroNumber).name); } linpsk-1.3.5/gui/macrocontrol.h000066400000000000000000000037151304636156700165000ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2012 by Volker Schroer, DL1KSV * * * * 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 MACROCONTROL_H #define MACROCONTROL_H #include #include "constants.h" class QButtonGroup; namespace Ui { class MacroControl; } class MacroControl : public QGroupBox { Q_OBJECT public: explicit MacroControl(QWidget *parent = 0); ~MacroControl(); void insertMacros(QVector *macroList); void updateMacroWindow(int macroNumber); public slots: void setMacroLanguage(int lang); signals: void executeMacro(int); private: Ui::MacroControl *ui; QVector *mL; int macroLang; QButtonGroup *displayBox; void displayMacros(); }; #endif // MACROCONTROL_H linpsk-1.3.5/gui/macrocontrol.ui000066400000000000000000000062071304636156700166650ustar00rootroot00000000000000 MacroControl 0 0 106 118 GroupBox Macros Qt::AlignCenter 1 1 true 0 0 96 71 1 1 1 Qt::NoFocus B true languageBox Qt::NoFocus e languageBox Qt::NoFocus g languageBox languageBox buttonClicked(int) MacroControl setMacroLanguage(int) -1 -1 54 79 setMacroLanguage(int) linpsk-1.3.5/gui/modemenu.cpp000066400000000000000000000057061304636156700161440ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2007 by volker, DL1KSV * * schroer@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(QStringList modeList, QWidget* parent, Qt::WindowFlags fl) : QDialog( parent, fl ), Ui::ModeMenu() { setupUi(this); RxMode->addItems(modeList); 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(); } linpsk-1.3.5/gui/modemenu.h000066400000000000000000000036561304636156700156130ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2007 by volker, DL1KSV * * schroer@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 #include #include "ui_modemenu.h" #include "constants.h" class QButtonGroup; class ModeMenu : public QDialog, private Ui::ModeMenu { Q_OBJECT public: ModeMenu(QStringList modeList,QWidget* parent = 0, Qt::WindowFlags fl = 0 ); ~ModeMenu(); void setParameter(ExtraParameter Param); ExtraParameter getParameter(); Mode selectedMode(); public slots: /*$PUBLIC_SLOTS$*/ protected: QButtonGroup *Stopbits; QButtonGroup *Parity; QStringList modeList; protected slots: void changeView(); }; #endif linpsk-1.3.5/gui/modemenu.ui000066400000000000000000000171661304636156700160020ustar00rootroot00000000000000 ModeMenu 0 0 350 250 0 0 350 250 350 150 Change Rx Mode true 30 190 300 50 60 20 &OK true true Qt::Horizontal QSizePolicy::Expanding 110 20 60 20 &Cancel true 260 30 80 31 Reverse true 250 90 91 91 Parity Qt::AlignHCenter 20 40 61 20 Odd 1 20 60 60 20 Even 2 20 20 60 20 None true 0 10 30 121 151 140 19 91 61 RTTY Spacing true 10 20 80 30 Hz 0 999 170 140 90 101 91 Stopbits Qt::AlignHCenter 10 20 80 22 1 0 10 40 81 21 1.5 true 1 10 60 80 21 2 2 qPixmapFromMimeSource constants.h buttonOk clicked() ModeMenu accept() 20 20 20 20 buttonCancel clicked() ModeMenu reject() 20 20 20 20 linpsk-1.3.5/gui/qsodata.cpp000066400000000000000000000401111304636156700157540ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2007 by volker, DL1KSV * * schroer@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 "constants.h" #ifdef WITH_HAMLIB #include "rigcontrol.h" #endif #include #include #include #include #include #include #include extern Parameter settings; QSOData::QSOData ( QWidget* parent ) : QGroupBox ( parent ), Ui::QSOData() { int i; 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 ; }" ); 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 ); HisRST->setText ( settings.QslData->HisRST ); MyRST->setText ( settings.QslData->MyRST ); dokName->setText(settings.QslData->dokName); } logBookCommunication = new ProcessLogData(); connectionError = false; connect ( Clear, SIGNAL ( clicked() ), this, SLOT ( clear() ) ); connect ( Qth, SIGNAL ( editingFinished () ), this, SLOT ( QTHchanged() ) ); connect ( QsoFrequency, SIGNAL ( activated (int) ), this, SLOT ( frequencyChanged(int) ) ); connect ( txPwr,SIGNAL( valueChanged(int) ), this ,SLOT( pwrChanged(int) ) ); 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 ( dokName, SIGNAL ( editingFinished()),this ,SLOT(dokChanged())); connect ( RemoteCallsign, SIGNAL ( editingFinished ( ) ), this, SLOT ( sendRequest() ) ); connect ( logBookCommunication, SIGNAL ( unabletoConnect() ), this , SLOT ( stopTrial() ) ); connect ( logBookCommunication, SIGNAL ( answerAvailable() ), this, SLOT ( copyAnswer() ) ); //====== Control the rig ================================== // for(i=0; i< settings.bandList.size(); i++) QsoFrequency->addItem(settings.bandList.at(i).bandName); // QsoFrequency->setCurrentIndex(findBand()); // txPwr->setValue(rigControl->get_pwr()); } QSOData::~QSOData() {} void QSOData::enableSaveData() { if ( ! ( settings.fileLog || settings.LinLog ) ) Save->setDisabled ( true ); else Save->setDisabled(false); } 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->setCurrentIndex(findBand()); #ifdef WITH_HAMLIB settings.pwr=settings.rig->get_pwr(); txPwr->setValue(settings.pwr); #endif 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(); dokName->clear(); eQsl->setChecked(false); bureau->setChecked(false); } 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(int index) { #ifdef WITH_HAMLIB settings.rig->set_frequency(settings.bandList.at(index).preferedFreq); #endif settings.QsoFrequency = index; } 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::dokChanged() { settings.QslData->dokName = dokName->text(); } 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(); HisRSTchanged(); MyRSTchanged(); if(settings.autoDate) refreshDateTime(); Datechanged(); Timechanged(); QString saveString, s; if ( RemoteCallsign->text().length() > 0 ) saveString = QString ( "%2\n" ).arg ( RemoteCallsign->text().length() ).arg ( RemoteCallsign->text() ); if ( settings.callsign != "" ) { s = QString ( "%2\n" ).arg ( settings.callsign.length() ).arg ( settings.callsign ); saveString.append ( s ); } if ( !OpName->text().isEmpty() ) { s = QString ( "%2\n" ).arg ( OpName->text().length() ).arg ( OpName->text() ); saveString.append ( s ); } if ( Qth->text() != "" ) { s = QString ( "%2\n" ).arg ( Qth->text().length() ).arg ( Qth->text() ); saveString.append ( s ); } if ( Loc->text() != "" ) { s = QString ( "%2\n" ).arg ( Loc->text().length() ).arg ( Loc->text() ); saveString.append ( s ); } if ( QsoFrequency->currentText() != "" ) { s = QString ( "%2\n" ).arg ( QsoFrequency->currentText().length() ).arg ( QsoFrequency->currentText() ); saveString.append ( s ); } // TxPwr int pwr=txPwr->value(); s.setNum(pwr); s = QString ("%2\n").arg(s.length()).arg(s); saveString.append(s); if ( QsoDate->text() == "" ) { s = QString ( "%1\n" ).arg ( QDateTime::currentDateTime().toString ( "yyyyMMdd" ) ); saveString.append ( s ); } else { s = QString ( "%1\n" ).arg ( QsoDate->date().toString ( "yyyyMMdd" ) ); saveString.append ( s ); } if ( QsoTime->text() != "" ) { QString timeValue= QsoTime->text().remove ( ':' ); s = QString ( "%2\n" ).arg ( timeValue.length() ).arg ( timeValue ); saveString.append ( s ); } if ( HisRST->text() != "" ) { s = QString ( "%2\n" ).arg ( HisRST->text().length() ).arg ( HisRST->text() ); saveString.append ( s ); } if ( MyRST->text() != "" ) { s = QString ( "%2\n" ).arg ( MyRST->text().length() ).arg ( MyRST->text() ); saveString.append ( s ); } if ( settings.ActChannel != 0 ) { s = QString ( "getModulationType() ) { case QPSK: s.append( "6>QPSK31"); break; case BPSK31: s.append ( "5>PSK31\n" ); break; case BPSK63: s.append ( "5>PSK63\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 ); } if(dokName->text() !="") saveString.append(QString("%2\n").arg(dokName->text().length()).arg(dokName->text())); 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 ) { saveString.append(""); if(bureau->isChecked()) saveString.append("R\n"); else saveString.append("N\n"); saveString.append(""); if(bureau->isChecked()) saveString.append("R\n"); else saveString.append("N\n"); saveString.append(""); if(eQsl->isChecked()) saveString.append("R\n"); else saveString.append("N\n"); saveString.append(""); if(eQsl->isChecked()) saveString.append("R\n"); else saveString.append("N\n"); saveString.append ( "\n" ); if ( !logBookCommunication->isRunning() ) { logBookCommunication->start(); #if QT_VERSION >= 0x050000 QThread::usleep(2000); #endif } #ifndef QT_NO_DEBUG qDebug ( "Written to Logbook\n%s", qPrintable ( saveString ) ); #endif 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, 5 ) ); } QSOData::coordinates QSOData::loc2coordinates ( const QChar *l ) { coordinates c; c.laenge = ( 20. * ( l[0].toLatin1() - 'A' ) + 2. * ( l[2].toLatin1() - '0' ) + ( 1. / 12. ) * ( l[4].toLatin1() - 'A' ) + 1. / 24. ); c.laenge *= M_PI / 180.; c.breite = 90. - ( 10. * ( l[1].toLatin1() - 'A' ) + 1. * ( l[3].toLatin1() - '0' ) + ( 1. / 24. ) * ( l[5].toLatin1() - 'A' ) + 1. / 48. ); c.breite *= M_PI / 180.; return c; } void QSOData::setQsoData(QsoData value,QString s) { switch (value) { case CallSign : RemoteCallsign->setText ( s.remove(QChar(' ')) ); Callsignchanged(); break; case QTH : Qth->setText ( s ); QTHchanged(); break; case Name: OpName->setText ( s ); Namechanged(); break; case Locator: Loc->setText ( s.left(6).toUpper()); Locatorchanged(); break; case RST: HisRST->setText ( s ); HisRSTchanged(); break; case DOK : dokName->setText(s); dokChanged(); break; } } 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 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(); #if QT_VERSION >= 0x050000 QThread::usleep(2000); #endif } logBookCommunication->requestCallsign ( results, RemoteCallsign->text().toUpper() ); } 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(); } void QSOData::setAutoDate() { if(settings.autoDate) { dateLabel->hide(); QsoDate->hide(); timeLabel->hide(); QsoTime->hide(); } else { dateLabel->show(); QsoDate->show(); timeLabel->show(); QsoTime->show(); } } void QSOData::pwrChanged(int p) { #ifdef WITH_HAMLIB settings.rig->set_pwr(p); #endif settings.pwr=p; } int QSOData::findBand() { #ifdef WITH_HAMLIB int freq = settings.rig->get_frequency(); for(int i=0; i < settings.bandList.size();i++) { if( (settings.bandList.at(i).bandStart <= freq) && (settings.bandList.at(i).bandEnd >= freq)) return i; } #endif return settings.bandList.size()-1; } void QSOData::initQsoData() { QsoFrequency->clear(); for(int i=0; i< settings.bandList.size(); i++) QsoFrequency->addItem(settings.bandList.at(i).bandName); QsoFrequency->setCurrentIndex(findBand()); #ifdef WITH_HAMLIB settings.pwr=settings.rig->get_pwr(); #endif txPwr->setValue(settings.pwr); } linpsk-1.3.5/gui/qsodata.h000066400000000000000000000047641304636156700154370ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2007 by volker, DL1KSV * * schroer@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 #include "ui_qsodata.h" #include "constants.h" class QChar; class ProcessLogData; class QValidator; class RigControl; class QSOData : public QGroupBox, private Ui::QSOData { Q_OBJECT struct coordinates { double laenge; double breite; }; public: QSOData(QWidget* parent = 0); ~QSOData(); void enableSaveData(); void setAutoDate(); void initQsoData(); public slots: /*$PUBLIC_SLOTS$*/ void Timechanged(); void Datechanged(); void MyRSTchanged(); void HisRSTchanged(); void frequencyChanged(int); void Locatorchanged(); void QTHchanged(); void Namechanged(); void Callsignchanged(); void clear(); void refreshDateTime(); void save(); void calculateDistance(QString); void dokChanged(); void setQsoData(QsoData,QString); void newChannel(); void pwrChanged(int); signals: protected: coordinates loc2coordinates ( const QChar *l ); protected slots: void sendRequest(); void stopTrial(); void copyAnswer(); private: ProcessLogData *logBookCommunication; bool connectionError; QValidator *validator; int findBand(); }; #endif linpsk-1.3.5/gui/qsodata.ui000066400000000000000000002063011304636156700156140ustar00rootroot00000000000000 QSOData 0 0 297 272 2 1 240 200 600 800 190 180 QSOData QsoData Qt::AlignHCenter false 1 1 Qt::NoFocus eQsl false Qt::NoFocus bureau false 0 0 16777215 20 Qt::NoFocus Save 0 0 16777215 20 Qt::NoFocus Clear QFrame::NoFrame QFrame::Plain 1 true 0 0 291 231 1 0 1 0 1 0 0 0 Date 0 0 0 Waz Zone 16777215 20 0 0 0 Locator 0 M. Prefix 0 0 255 255 255 255 255 255 255 255 255 true QFrame::StyledPanel QFrame::Sunken Qt::NoTextInteraction 16777215 20 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 true QFrame::StyledPanel QFrame::Sunken Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter 0 Qt::NoTextInteraction 0 0 0 Name 0 0 0 255 255 255 255 255 255 255 255 255 127 127 127 170 170 170 0 0 0 255 255 255 0 0 0 255 255 255 255 255 255 0 0 0 255 255 255 255 255 220 0 0 0 0 0 0 255 255 255 255 255 255 255 255 255 127 127 127 170 170 170 0 0 0 255 255 255 0 0 0 255 255 255 255 255 255 0 0 0 255 255 255 255 255 220 0 0 0 127 127 127 255 255 255 255 255 255 255 255 255 127 127 127 170 170 170 127 127 127 255 255 255 127 127 127 255 255 255 255 255 255 0 0 0 255 255 255 255 255 220 0 0 0 true QFrame::StyledPanel QFrame::Sunken 0 0 0 QTH 65 0 16777215 20 16777215 20 0 0 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 true QFrame::StyledPanel QFrame::Sunken Qt::NoTextInteraction 0 0 0 0 0 255 255 255 255 255 255 255 255 255 127 127 127 170 170 170 0 0 0 255 255 255 0 0 0 255 255 255 255 255 255 0 0 0 255 255 255 255 255 220 0 0 0 0 0 0 255 255 255 255 255 255 255 255 255 127 127 127 170 170 170 0 0 0 255 255 255 0 0 0 255 255 255 255 255 255 0 0 0 255 255 255 255 255 220 0 0 0 127 127 127 255 255 255 255 255 255 255 255 255 127 127 127 170 170 170 127 127 127 255 255 255 127 127 127 255 255 255 255 255 255 0 0 0 255 255 255 255 255 220 0 0 0 true QFrame::StyledPanel QFrame::Sunken Qt::NoTextInteraction 0 0 0 Callsign 0 0 0 Worked 0 0 0 Frequency 0 0 0 Itu Zone 70 0 16777215 20 0 1 7 true 0 0 60 0 16777215 20 20 0 0 0 Country 255 255 255 255 255 255 233 232 232 true QFrame::StyledPanel QFrame::Sunken Qt::NoTextInteraction 0 0 0 Time 0 0 0 255 255 255 255 255 255 255 255 255 127 127 127 170 170 170 0 0 0 255 255 255 0 0 0 255 255 255 255 255 255 0 0 0 255 255 255 255 255 220 0 0 0 0 0 0 255 255 255 255 255 255 255 255 255 127 127 127 170 170 170 0 0 0 255 255 255 0 0 0 255 255 255 255 255 255 0 0 0 255 255 255 255 255 220 0 0 0 127 127 127 255 255 255 255 255 255 255 255 255 127 127 127 170 170 170 127 127 127 255 255 255 127 127 127 255 255 255 255 255 255 0 0 0 255 255 255 255 255 220 0 0 0 true QFrame::StyledPanel QFrame::Sunken Qt::NoTextInteraction 0 0 0 Continent 16777215 20 0 0 80 0 0 RST rcvd 0 0 0 RST given 0 0 0 Dist. Dok 10 60 0 false -1 Power (Watt) Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 1 100 5 5 scrollArea RemoteCallsign OpName Qth Loc HisRST MyRST dokName QsoFrequency QsoTime QsoDate linpsk-1.3.5/gui/renamemacro.cpp000066400000000000000000000051451304636156700166210ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2007 - 2016 by Volker Schroer, DL1KSV * * * * 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 "readonlystringlistmodel.h" #include RenameMacro::RenameMacro(QVector *macroList,QWidget* parent) : QDialog( parent), ui(new Ui:: RenameMacro()) { ui->setupUi(this); mL = macroList; model=new ReadOnlyStringListModel(); QStringList macroName; int numberofMacros=macroList->size(); if (numberofMacros > 0 ) for(int i=0; i < numberofMacros;i++) macroName.append((*macroList).at(i).name); model->setStringList(macroName); ui->MacroBox->setModel(model); connect(ui->MacroBox,SIGNAL(clicked(const QModelIndex &)),this,SLOT(selectMacro(const QModelIndex &))); macroNumber=-1; } RenameMacro::~RenameMacro() { } void RenameMacro::accept() { if (ui->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; } Macro macro; macro=(*mL).at(macroNumber); macro.name=ui->NewName->text(); mL->replace(macroNumber,macro); QDialog::accept(); } void RenameMacro::selectMacro(const QModelIndex &index) { macroNumber=index.row(); ui->OldName->setText(index.data().toString()); } int RenameMacro::getMacroNumber() { return macroNumber; } linpsk-1.3.5/gui/renamemacro.h000066400000000000000000000037001304636156700162610ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2007 -2016 by Volker Schroer, DL1KSV * * * * 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 #include "ui_renamemacro.h" #include "constants.h" namespace Ui { class RenameMacro; } class ReadOnlyStringListModel; class RenameMacro : public QDialog { Q_OBJECT public: RenameMacro(QVector *macroList,QWidget* parent = 0 ); ~RenameMacro(); int getMacroNumber(); protected: ReadOnlyStringListModel *model; int macroNumber; protected slots: /*$PROTECTED_SLOTS$*/ virtual void accept(); void selectMacro(const QModelIndex &); private: Ui::RenameMacro *ui; QVector *mL; }; #endif linpsk-1.3.5/gui/renamemacro.ui000066400000000000000000000123551304636156700164550ustar00rootroot00000000000000 RenameMacro 0 0 460 300 400 200 500 400 Rename Macro true 160 30 Select Macro false 150 30 Old Name false 160 130 150 30 true Qt::Vertical 20 102 150 30 New Name false 150 30 &OK true true Qt::Horizontal QSizePolicy::Expanding 120 20 &Cancel true Qt::Horizontal 141 20 qPixmapFromMimeSource buttonOk clicked() RenameMacro accept() 20 20 20 20 buttonCancel clicked() RenameMacro reject() 20 20 20 20 linpsk-1.3.5/gui/spectrumdisplay.cpp000066400000000000000000000120361304636156700175550ustar00rootroot00000000000000/*************************************************************************** spectrumdisplay.cpp - description ------------------- begin : Fr March 19 2004 copyright : (C) 2004 by Volker Schroer email : dl1ksv@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 #include #include #include #include #include "spectrumdisplay.h" #include "crxchannel.h" #include "parameter.h" #include "color.h" extern Parameter settings; SpectrumDisplay::SpectrumDisplay ( QWidget* parent ) : QFrame ( parent ), Ui::SpectrumDisplay() { setupUi(this); spectrumWindow->setDisplayRange(MinFreq->value(),MaxFreq->value()); inputdata = 0; for(int i=0; i< fftsize;i++) smoothedfft[i]=0.; displayWidth=spectrumWindow->width()-2*spectrumWindow->frameWidth(); connect(spectrumWindow,SIGNAL(frequencyChanged(double)),this ,SIGNAL(FrequencyChanged(double))); connect(waterfallWindow,SIGNAL(frequencyChanged(double)),this ,SIGNAL(FrequencyChanged(double))); oldMinfreq=MinFreq->value(); oldMaxfreq=MaxFreq->value(); } /* * Destroys the object and frees any allocated resources */ SpectrumDisplay::~SpectrumDisplay() { // no need to delete child widgets, Qt does it all for us } void SpectrumDisplay::resizeEvent ( QResizeEvent * ) { if ( inputdata == 0 ) return; // No data available displayWidth=spectrumWindow->width()-2*spectrumWindow->frameWidth(); if(fftsize < displayWidth) { qDebug("+++ SpectrumDisplay: Spectrum array %d lower than displaywidth %d",fftsize,displayWidth); return; } translate(); calcFFT(); spectrumWindow->plotSpectrum(false,fftdata, MinFreq->value(),MaxFreq->value()); waterfallWindow->plotWaterfall(fftdata); } void SpectrumDisplay::calcFFT() { int i; float x,gain; if ( inputdata == 0 ) return; // No data available if( Smooth->isChecked()) { for ( i = 0;i < displayWidth;i++ ) { if(inputdata[xtranslate[i]]> 0.02) x=log10 ( inputdata[xtranslate[i]])+2; else x=0.; gain=(1. - exp(-(0.2 * x))); smoothedfft[i]=smoothedfft[i]*(1.-gain) + gain *x; fftdata[i] = smoothedfft[i]; } } else { for ( i = 0;i < displayWidth;i++ ) { if(inputdata[xtranslate[i]]> 0.02) fftdata[i]=log10 ( inputdata[xtranslate[i]])+2; else fftdata[i]=0.; } } i=spectrumWindow->height(); i=0; } void SpectrumDisplay::translate ( void ) { int i, to, minfreq, maxfreq,tmp; minfreq = MinFreq->value(); maxfreq = MaxFreq->value(); to = int ( maxfreq * fftsize *2/ settings.sampleRate ); for ( i = 0;i < displayWidth;i++ ) { tmp= ( ( ( maxfreq - minfreq ) * i * to / displayWidth ) + minfreq * to ) / maxfreq; if( tmp < fftsize) xtranslate[i] = tmp; else { qDebug("+++ SpectrumDisplay: translation array size %d lower than requested size %d",fftsize,tmp); return; } } } void SpectrumDisplay::startPlot ( double *x, bool overload ) { inputdata = x; int tmp=spectrumWindow->width()-2*spectrumWindow->frameWidth(); if( (tmp != displayWidth) || (oldMinfreq != MinFreq->value()) || (oldMaxfreq != MaxFreq->value())) { displayWidth=tmp; oldMinfreq=MinFreq->value(); oldMaxfreq=MaxFreq->value(); translate(); } calcFFT(); spectrumWindow->plotSpectrum(overload,fftdata, oldMinfreq,oldMaxfreq); waterfallWindow->plotWaterfall(fftdata); } void SpectrumDisplay::setnewFrequency ( int position ) { double freq; freq = ( position * ( MaxFreq->value() - MinFreq->value() ) ) / displayWidth + MinFreq->value(); settings.ActChannel->setRxFrequency ( freq ); emit FrequencyChanged ( freq ); } void SpectrumDisplay::setPhasePointer ( std::complex *p ) { spectrumWindow->setPhasePointer(p); } void SpectrumDisplay::setColorList(QList *c) { spectrumWindow->setColorList(c); } QByteArray SpectrumDisplay::spectrumSplitterState() const { return spectrumSplitter->saveState(); } void SpectrumDisplay::restoreSplitterState(const QByteArray & spectrumState) { spectrumSplitter->restoreState(spectrumState); } void SpectrumDisplay::showSpectren(bool p) { if(p) { spectrumWindow->show(); waterfallWindow->show(); } else { spectrumWindow->hide(); waterfallWindow->hide(); } } linpsk-1.3.5/gui/spectrumdisplay.h000066400000000000000000000042641304636156700172260ustar00rootroot00000000000000/*************************************************************************** spectrumdisplay.h - description ------------------- begin : Fr March 19 2004 copyright : (C) 2004 by Volker Schroer email : dl1ksv@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 #include #include "ui_spectrumdisplay.h" class QRadioButton; class QSpinBox; class QWidget; /** *@author Volker Schroer */ //const int fftsize=1024; // Check size to protect arrays const int fftsize=2048; // Check size to protect arrays class SpectrumDisplay : public QFrame , private Ui::SpectrumDisplay { Q_OBJECT public: SpectrumDisplay( QWidget* parent = 0); ~SpectrumDisplay(); void setPhasePointer(std::complex *); void setColorList(QList *c); QByteArray spectrumSplitterState() const; void restoreSplitterState(const QByteArray & spectrumState); void showSpectren(bool p); public slots: void startPlot(double *,bool); protected: void resizeEvent( QResizeEvent * ); protected slots: void setnewFrequency(int); private: /** Pointer to the Input for the FFT **/ double *inputdata; int displayWidth; void translate(void); void plotVector(QPainter *p); /** Results of FFT */ void calcFFT(); float fftdata[fftsize]; // Not all elements are used, it differs int xtranslate[fftsize]; // depending on the display width float smoothedfft[fftsize]; int oldMinfreq; int oldMaxfreq; signals: void FrequencyChanged(double); }; #endif linpsk-1.3.5/gui/spectrumdisplay.ui000066400000000000000000000126161304636156700174140ustar00rootroot00000000000000 SpectrumDisplay 0 0 330 175 Frame QFrame::StyledPanel QFrame::Raised 1 1 1 1 1 2 Hz 100 1300 100 Qt::Horizontal 40 20 Smooth Qt::Horizontal 40 20 Hz 1400 3100 100 2900 0 1 QFrame::NoFrame Qt::Vertical true false 100 80 QFrame::StyledPanel 100 30 QFrame::StyledPanel QFrame::Plain SpectrumWindow QFrame
spectrumwindow.h
1 frequencyChanged(int)
WaterfallWindow QFrame
waterfallwindow.h
1 frequencyChanged(int)
spectrumWindow frequencyChanged(int) SpectrumDisplay setnewFrequency(int) 204 80 204 131 waterfallWindow frequencyChanged(int) SpectrumDisplay setnewFrequency(int) 204 188 204 131 setnewFrequency(int)
linpsk-1.3.5/gui/txwindow.cpp000066400000000000000000000125541304636156700162150ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2012 by Volker Schroer, DL1KSV * * * * 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 "txwindow.h" #include "ui_txwindow.h" #include #include #include "parameter.h" #include "ctxbuffer.h" #include extern Parameter settings; TxWindow::TxWindow(QWidget *parent) : QFrame(parent), ui(new Ui::TxWindow) { QFontMetrics fm ( font() ); int pixelwidth=82*fm.width("A"); int height=fm.height(); ui->setupUi(this); zeile=0; spalte=0; for ( int i = 0;i < TXWINDOWBUFFER;i++ ) { scrollBuffer[i] = new QLineEdit ( ui->txLines ); scrollBuffer[i]->setFrame ( false ); scrollBuffer[i]->setFocusProxy(this); scrollBuffer[i]->setMaximumHeight(2*height); scrollBuffer[i]->setFixedWidth(pixelwidth); ui->linesLayout->addWidget(scrollBuffer[i]); } ui->txArea->ensureWidgetVisible(scrollBuffer[zeile]); } TxWindow::~TxWindow() { delete ui; } void TxWindow::insert ( unsigned char c ) { QString s = scrollBuffer[zeile]->text() + QString ( QChar ( c ) ); scrollBuffer[zeile]->setText ( s ); spalte++; if(c == '\n') { // Buffer->insert(c); gotoNextLine(); } else if (spalte >= 80) { if(settings.autoCrLf) Buffer->insert('\r'); Buffer->insert ( '\n' ); gotoNextLine(); } } void TxWindow::insertString (QString string ) { for(int i=0;i < string.length();i++) insert(string.at(i).toLatin1()); } void TxWindow::setTxBuffer ( CTxBuffer *p ) { Buffer = p; } void TxWindow::gotoNextLine() { int i; zeile++; spalte=0; if( zeile >= TXWINDOWBUFFER) //Scroll two lines { for(i=2; i< TXWINDOWBUFFER;i++) scrollBuffer[i-2]->setText(scrollBuffer[i]->text()); zeile = TXWINDOWBUFFER-2; for(i=zeile; i < TXWINDOWBUFFER;i++) scrollBuffer[i]->clear(); } scrollBuffer[zeile]->setCursorPosition(spalte); ui->txArea->ensureWidgetVisible(scrollBuffer[zeile]); } void TxWindow::clearBuffers() { for ( int i = 0;i < TXWINDOWBUFFER;i++ ) scrollBuffer[i]->clear(); Buffer->clear(); zeile=0; spalte=0; scrollBuffer[zeile]->setCursorPosition(spalte); ui->txArea->ensureWidgetVisible(scrollBuffer[zeile]); } void TxWindow::keyPressEvent ( QKeyEvent *e ) { unsigned char c; bool CapsLock = false; // Fixme checking CapsLock state 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'; Buffer->insert ( c ); backspace(); e->accept(); 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 ).toLatin1(); else c = 0; } else { if ( !e->text().isEmpty() ) c = e->text().toLower().at ( 0 ).toLatin1(); else c = 0; } if ( c != 0 ) { Buffer->insert ( c ); insert ( c ); e->accept(); } } // End Case } // keyPressEvent void TxWindow::backspace() { if(spalte > 0) { spalte--; scrollBuffer[zeile]->backspace(); } else if (zeile > 0) { zeile--; spalte=(scrollBuffer[zeile]->text()).length(); ui->txArea->ensureWidgetVisible(scrollBuffer[zeile]); } } void TxWindow::focusInEvent(QFocusEvent *e) { setStyleSheet("TxWindow{border: 1px solid green;}"); QFrame::focusInEvent(e); } void TxWindow::focusOutEvent(QFocusEvent *e) { setStyleSheet("TxWindow{border: 1px solid red;}"); QFrame::focusOutEvent(e); } linpsk-1.3.5/gui/txwindow.h000066400000000000000000000043071304636156700156570ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2012 by Volker Schroer, DL1KSV * * * * 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 TXWINDOW_H #define TXWINDOW_H #include #include "constants.h" class CTxBuffer; class QString; class QLineEdit; namespace Ui { class TxWindow; } class TxWindow : public QFrame { Q_OBJECT public: explicit TxWindow(QWidget *parent = 0); ~TxWindow(); void setTxBuffer(CTxBuffer *); void insertString(QString string); void insert(unsigned char); private: Ui::TxWindow *ui; CTxBuffer * Buffer; QLineEdit* scrollBuffer[TXWINDOWBUFFER]; int zeile,spalte; // Position in window buffer void gotoNextLine(); void backspace(); void keyPressEvent(QKeyEvent *); // Bearbeiten der Eingaben im TX Window protected: virtual void focusInEvent(QFocusEvent *e); virtual void focusOutEvent(QFocusEvent *e); // virtual void mousePressEvent(QMouseEvent *); public slots: void clearBuffers(); }; #endif // TXWINDOW_H linpsk-1.3.5/gui/txwindow.ui000066400000000000000000000051021304636156700160370ustar00rootroot00000000000000 TxWindow 0 0 494 236 Frame QFrame::StyledPanel QFrame::Raised 1 1 16777215 20 Clear Qt::Horizontal 383 20 Qt::ScrollBarAsNeeded true 0 0 484 205 0 QLayout::SetNoConstraint 0 clearWindow clicked() TxWindow clearBuffers() 450 222 246 117 clearBuffers() linpsk-1.3.5/images/000077500000000000000000000000001304636156700143005ustar00rootroot00000000000000linpsk-1.3.5/images/linpsk.png000066400000000000000000000004461304636156700163120ustar00rootroot00000000000000‰PNG  IHDR szzôíIDATxœíVÛ„ Egÿ+>Ýý2ö¡±1´‰:o‘碒– A r¤ùà#iÛÛ"}“Y¨r8F‰7! hÆÖ §-ÄzVóÞØð8xgê™}3µ3æ7[WL{p¯ÀAªm‰ˆbïÏaãkÕ ÿ “p´·íìWû ÕšZ•­àܬ½΄8á=p àé_Ðßu ü?p7žÕÏ€Ê3*5Þ!ôy ÄŸRJ#^X­Êuß 1§˜ûhâÜ@§Àß„Exæ5‰ƒž¨†¨Üb ñD?ã…d.‚IqIEND®B`‚linpsk-1.3.5/images/linpsk_32x32.png000077500000000000000000000020521304636156700171510ustar00rootroot00000000000000‰PNG  IHDR szzôsBIT|dˆ pHYsÄÄ•+ÌIDATX…í–OhWÆФuY7jcp“ r@>ÈSð¡Ê¥‡:ôÖƒ±¯JKC1ô^ˆL!ôÒKˆ ÐB …ÐZð!'8)¶ÀÈPÛ(¶Á"KhÉ_’VZiWr.uaa5ï{3ß¼™7ÚBœ£\8Ïà¡Vƒ…ÀG¾›,,.rÑù}ÈaW¼ŸÏ@k îp‡f˜ñu6Å㌠À ',±Ämnûâoq €9æ‡uèÉô`GmžÝ~Fñ½"ØÕÓýâÕç¯ Ð‰@±>°È¯ç¹ò÷—}÷û]ú¾è#ói üa™Ð£ƒƒN°L&ƒÆ}í~Û˜³ÑMRê-aÌäþÌa—lÇù:Bæ§ Å‹ðT>ªü*_Rí `dd„Êo®.\íÒµŒ""­f^¾ÿ’òge‚¡ c ¨fZËÖ|`Rü¶QàÝÆÞÜdŽ“…ö¯$÷(öʵf[s]åƒiÝëIàäM#ž‘Á\IEND®B`‚linpsk-1.3.5/images/linpsk_48x48.png000077500000000000000000000024351304636156700171740ustar00rootroot00000000000000‰PNG  IHDR00Wù‡sBIT|dˆ pHYsÄÄ•+¿IDATh혱OIÆ{B "o*\  KG·ŽDÁ5YÒœÝ%ÿáÊÒ%U: Õ¥3VRÜ) 4„2(ELu¦)‰í*ÂZJ_/"‘7ŠÄ»b±³kÏzí…%â­dϼývÞ¼ïͼ] AøŽñÓEOସtà¢140Î8Y²l³Mzß„2ĉwõGáÑÐ(R ±uÛ iHCËã‹î–‘Œ<•§òA>HÃÓ^É+y$âyuÚ2’ém­êÌK^NäDDDNäDVe5ô¡†r(‡rrÚ¼hõEá9”CIK:о+ Ò¤Ûÿ54Ò¤10zò·ÐÑÑN›­¾(<::7¹Ù¿„r’“†4|+øE¾È]¹Ûså^ÊK CC2/óó”¥ÜŸ„¼áëD¯Pæ%/û²ê@˜$¼Òí¼/H~Êm´Sý`Š©P›(¼á÷y¼Ù iJS¹zMi*w¤ÖŽ¡Z¹óä Ú‘Ú˜bŠfaDéç#Ì0CŠT»o”Qf™e‚‰¾W7*ÏÌ2Ë(£í>7ê!úë„W‹­œ‰‚(<ù“—¼›ÄƒÈÀÊ^’û<^ùµæ*×à€žó<4™£ð88¼à„G H‹ƒ¼ öBž°WJ¥ÞPö ŸJ~e)w%â{y/e)Äs|ÚzIA4ŸV+þ_œä½$Îpp•Ûß·”Ôëu&ïMb``OÚJÍÔX›_ ÷[Žõ•uwÅ\§wò;X“–òÞô4Å_‹0AŸ¬Î”ñxœäd’«÷®ÚÄŽb˜;&æŽIÕ®ÂÜ×1˲Hì¸ìœ`¥Rq'¿ÿþrjõ MgÖѧuØõ3ÞÏ3Tc^nÏåÙEãe=óšƒIEND®B`‚linpsk-1.3.5/images/linpsk_64x64.png000077500000000000000000000011541304636156700171650ustar00rootroot00000000000000‰PNG  IHDR@@ªiqÞsBIT|dˆ pHYsÄÄ•+IDATxœíZ[’ƒ l¶ö^Ù›Ù¹™žŒý0îªá1Ô¤dÚ²*‘IÛ4èñ¥-@f€¶m˜Ú´ñ- š1~ðSu²'†Vüe<>½Í~öf?g¢Ó<{®3¶öþK:¥¤5&¤:Þ‹_Ê3| ˆf@.]{Œ~k~ Ï¥ xàÑzqqÔ$îæ _ þZžî5àӳŊ`MÑJ¥×ÕÔïÁŸâ± ¨µ»-F¿5ŒÇ2 Å¨íÝm9ú­ùC<Ãg€óÞ½(ê°n –Ë$ ´àéÍâ~ ØePÛ}Ø­ðè¨p7÷¬Ýꦥ†¿ÛzÀ‚¥zû`SàJz ¿(z/ºk/Fn‡wïønÐÁ#û8|ç·Ã"îŒák€ -@f€¶m˜Ú´ah І -@f@²Õ|²¬-pœO.Ìñ¶'´$ãNçžóÑŸ¥{‚äñ»#ÞžO] D |r<çv1€$‚eñ»8‚aNqQ®‚Îj¹ŠˆNŸŽ(é<Ðq l&`Äîçn¤’¬*íüŠÔŠàI–µí¿>“ôÁ3!°G¶#¥'ÙÙº^ÿ² s° 7ñŸ/RݯL½¾ìE7äK£ÈQ ØÈ¤UýðÛé5w+L(.¦~½œJ®DY­ÞÌ“º— 9Ͷ,®-@f€¶müµïÜÍ=¤IEND®B`‚linpsk-1.3.5/linpsk.pro000066400000000000000000000120171304636156700150560ustar00rootroot00000000000000CONFIG += warn_on \ qt \ thread CONFIG += link_pkgconfig !packagesExist(fftw3) { error("LinPSK requires fftw3") } CONFIG(debug, debug|release) { message(Building Qt$$QT_VERSION debug version) QMAKE_CFLAGS_DEBUG += '-g3 -O0' QMAKE_CXXFLAGS_DEBUG += '-g3 -O0' } else { message(Building Qt$$QT_VERSION release) DEFINES += QT_NO_DEBUG } QT += network greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TEMPLATE = app TARGET = linpsk target.path=/usr/local/bin desktop.path=/usr/share/applications desktop.files=data/linpsk.desktop images.path=/usr/share/pixmaps images.files=images/linpsk.png INSTALLS +=desktop INSTALLS +=images INSTALLS +=target INCLUDEPATH += . src gui LIBS += -lasound -lfftw3 packagesExist( hamlib ) { message(LinPSK builds with hamlib) LIBS +=$$system("pkg-config --libs hamlib") DEFINES += WITH_HAMLIB HEADERS +=src/rigcontrol.h SOURCES +=src/rigcontrol.cpp } else { message(LinPSK builds without hamlib) } # Input HEADERS += gui/activatemacros.h \ gui/addmacro.h \ gui/addrxwindow.h \ gui/controlpanel.h \ gui/crxdisplay.h \ gui/ctxdisplay.h \ gui/definebandlist.h \ gui/deletemacro.h \ gui/editmacro.h \ gui/generalsettings.h \ gui/linpsk.h \ gui/macrocontrol.h \ gui/modemenu.h \ gui/qsodata.h \ gui/renamemacro.h \ gui/spectrumdisplay.h \ gui/txwindow.h \ src/bpskdemodulator.h \ src/bpskmodulator.h \ src/cdemodulator.h \ src/cledbutton.h \ src/cmodulator.h \ src/color.h \ src/constants.h \ src/cpskdemodulator.h \ src/crxchannel.h \ src/crxwindow.h \ src/csound.h \ src/csquelch.h \ src/ctxbuffer.h \ src/deinterleaver.h \ src/feccoder.h \ src/fircoeffs.h \ src/firfilter.h \ src/frequencyselect.h \ src/fskmodulator.h \ src/input.h \ src/interleaver.h \ src/mfskdemodulator.h \ src/mfskmodulator.h \ src/mfskvaricode.h \ src/parameter.h \ src/processlogdata.h \ src/pskmodulator.h \ src/qpskdemodulator.h \ src/qpskmodulator.h \ src/readonlystringlistmodel.h \ src/rttydemodulator.h \ src/rttymodulator.h \ src/spectrumwindow.h \ src/tabwidget.h \ src/viterbi.h \ src/waterfallwindow.h \ src/waveinput.h \ src/psk63demodulator.h \ src/psk63modulator.h FORMS += gui/activatemacros.ui \ gui/addmacro.ui \ gui/addrxwindow.ui \ gui/controlpanel.ui \ gui/crxdisplay.ui \ gui/ctxdisplay.ui \ gui/definebandlist.ui \ gui/deletemacro.ui \ gui/editmacro.ui \ gui/generalsettings.ui \ gui/linpsk.ui \ gui/macrocontrol.ui \ gui/modemenu.ui \ gui/qsodata.ui \ gui/renamemacro.ui \ gui/spectrumdisplay.ui \ gui/txwindow.ui SOURCES += gui/activatemacros.cpp \ gui/addmacro.cpp \ gui/addrxwindow.cpp \ gui/controlpanel.cpp \ gui/crxdisplay.cpp \ gui/ctxdisplay.cpp \ gui/definebandlist.cpp \ gui/deletemacro.cpp \ gui/editmacro.cpp \ gui/generalsettings.cpp \ gui/linpsk.cpp \ gui/macrocontrol.cpp \ gui/modemenu.cpp \ gui/qsodata.cpp \ gui/renamemacro.cpp \ gui/spectrumdisplay.cpp \ gui/txwindow.cpp \ src/bpskdemodulator.cpp \ src/bpskmodulator.cpp \ src/cdemodulator.cpp \ src/cledbutton.cpp \ src/cmodulator.cpp \ src/cpskdemodulator.cpp \ src/crxchannel.cpp \ src/crxwindow.cpp \ src/csound.cpp \ src/csquelch.cpp \ src/ctxbuffer.cpp \ src/deinterleaver.cpp \ src/feccoder.cpp \ src/firfilter.cpp \ src/frequencyselect.cpp \ src/fskmodulator.cpp \ src/input.cpp \ src/interleaver.cpp \ src/main.cpp \ src/mfskdemodulator.cpp \ src/mfskmodulator.cpp \ src/mfskvaricode.cpp \ src/parameter.cpp \ src/processlogdata.cpp \ src/pskmodulator.cpp \ src/qpskdemodulator.cpp \ src/qpskmodulator.cpp \ src/readonlystringlistmodel.cpp \ src/rttydemodulator.cpp \ src/rttymodulator.cpp \ src/spectrumwindow.cpp \ src/tabwidget.cpp \ src/viterbi.cpp \ src/waterfallwindow.cpp \ src/waveinput.cpp \ src/psk63demodulator.cpp \ src/psk63modulator.cpp RESOURCES += src/application.qrc DISTFILES += \ README \ ChangeLog \ COPYING linpsk-1.3.5/src/000077500000000000000000000000001304636156700136225ustar00rootroot00000000000000linpsk-1.3.5/src/application.qrc000066400000000000000000000001441304636156700166330ustar00rootroot00000000000000 ../images/linpsk.png linpsk-1.3.5/src/bpskdemodulator.cpp000066400000000000000000000066751304636156700175430ustar00rootroot00000000000000/*************************************************************************** bpskdemodulator.cpp - description ------------------- begin : Sat Jun 2 2001 copyright : (C) 2001 by Volker Schroer email : dl1ksv@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" #include "firfilter.h" BPskDemodulator::BPskDemodulator():CPskDemodulator() { ave1=1.0; ave2=1.0; } BPskDemodulator::~BPskDemodulator() { if( downFilter ) delete downFilter; if ( syncFilter ) delete syncFilter; } void BPskDemodulator::DecodeSymbol(double angle) { bool bit; char ch =0; CalcQuality(angle); bit = GetBPSKSymb(); // if( (bit==0) && m_LastBitZero ) //if character delimiter if( (!bit) && 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) if(!bit) 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); } 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; } 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; } void BPskDemodulator::Init(double Fs ,int BlockSize) { SampleRate = Fs; //sample rate NxSamples = BlockSize; //size data input buffer downFilter = new FIRFilter(PI2*31.25/Fs,79,ComplexData,10.); syncFilter = new FIRFilter(PI2*31.25*18./Fs,79, ComplexData,5.); downRate = 18; } double BPskDemodulator::calcFreqError(complex s) { double x,y; complex z; if (abs(s) >1 ) z=s/abs(s); else z=s; x= z.real()*z.imag(); x /=5000.; // 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; } linpsk-1.3.5/src/bpskdemodulator.h000066400000000000000000000030231304636156700171700ustar00rootroot00000000000000/*************************************************************************** bpskdemodulator.h - description ------------------- begin : Sat Jun 2 2001 copyright : (C) 2001 by Volker Schroer email : dl1ksv@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 #include "cpskdemodulator.h" /**Implementation of the BPSK Demodulator *@author Volker Schroer */ class BPskDemodulator : public CPskDemodulator { public: BPskDemodulator(); ~BPskDemodulator(); void Init(double Fs ,int BlockSize); protected: /** Decodes a BPSK Symbol */ void DecodeSymbol( double); void CalcQuality(double); double calcFreqError(complex s); private: bool GetBPSKSymb(); double ave1; double ave2; }; #endif linpsk-1.3.5/src/bpskmodulator.cpp000066400000000000000000000051161304636156700172170ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2012 -2017 by Volker Schroer, DL1KSV * * * * 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 "bpskmodulator.h" #include "constants.h" #include "parameter.h" #include "ctxbuffer.h" extern Parameter settings; #define SYM_NOCHANGE 0 //Stay the same phase #define SYM_P180 2 //Plus 180 deg BpskModulator::BpskModulator(int FS, double frequency, CTxBuffer *TxBuffer):PskModulator(FS,frequency,TxBuffer) { } char BpskModulator::getNextSymbolBit() { int bit; if(txShiftRegister != 0) { if(txShiftRegister &0x8000) bit=SYM_NOCHANGE; else bit=SYM_P180; txShiftRegister <<=1; if(txShiftRegister == 0) addEndingZero=true; } else { if(addEndingZero) { bit=SYM_P180; addEndingZero=false; } else { int ch; if((ch = getChar())>= 0) { // No controlcode txShiftRegister = VARICODE_TABLE[ ch&0xFF ]; bit=SYM_P180; //Start with a zero } else switch ( ch ) { case TXON_CODE: case TXTOG_CODE: //Idle bit = SYM_P180; break; case TXOFF_CODE: bit = SYM_NOCHANGE; break; } } } return bit; } linpsk-1.3.5/src/bpskmodulator.h000066400000000000000000000031611304636156700166620ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2012 -2017 by Volker Schroer, DL1KSV * * * * 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 BPSKMODULATOR_H #define BPSKMODULATOR_H #include "pskmodulator.h" class BpskModulator : public PskModulator { public: BpskModulator(int FS, double frequency, CTxBuffer *TxBuffer); protected: char getNextSymbolBit(); }; #endif // BPSKMODULATOR_H linpsk-1.3.5/src/cdemodulator.cpp000066400000000000000000000042471304636156700170170ustar00rootroot00000000000000/*************************************************************************** cdemodulator.cpp - description ------------------- begin : Sat Jun 2 2001 copyright : (C) 2001 by Volker Schroer email : dl1ksv@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; OszFrequency = 0.0; } CDemodulator::~CDemodulator() { } void CDemodulator::setAfcMode(AfcMode afc) { UseAfc=afc; } void CDemodulator::setRxFrequency(double freq) { if ( (freq > 200 ) && (freq < 3000 ) ) { RxFrequency = freq; OszFreqinc = freq*PI2/SampleRate; } } complex *CDemodulator::getPhasePointer() { return NULL; } 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; } 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; } linpsk-1.3.5/src/cdemodulator.h000066400000000000000000000051071304636156700164600ustar00rootroot00000000000000/*************************************************************************** cdemodulator.h - description ------------------- begin : Sat Jun 2 2001 copyright : (C) 2001 by Volker Schroer email : dl1ksv@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 using namespace std; #include "constants.h" #include #include /**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 void Init(double,int) = 0; virtual complex *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 linpsk-1.3.5/src/cledbutton.cpp000066400000000000000000000045041304636156700164740ustar00rootroot00000000000000/*************************************************************************** cledbutton.cpp - description ------------------- begin : Sun Jan 14 2001 copyright : (C) 2001 by Volker Schroer email : DL1KSV@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 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); 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::gray); paint.drawEllipse(4,4,14,14); break; case SW: paint.setPen(Qt::black); paint.setBrush(Qt::yellow); paint.drawEllipse(4,4,14,14); break; } } /** sets the buttonstatus */ void CLedButton::setStatus(BUTTONSTATUS state) { status=state; switch(status) { case UNDEF: case ON: setText("&RX"); break; case OFF: setText("&TX"); break; case SW: setText("&A"); 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; case SW: emit abortTx(); break; } } BUTTONSTATUS CLedButton::getstatus() { return status; } linpsk-1.3.5/src/cledbutton.h000066400000000000000000000030351304636156700161370ustar00rootroot00000000000000/*************************************************************************** cledbutton.h - description ------------------- begin : Sun Jan 14 2001 copyright : (C) 2001 by Volker Schroer email : DL1KSV@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 #include "constants.h" /**Constucts a pushbutton with a led in it *@author Volker Schroer */ 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(); void abortTx(); }; #endif linpsk-1.3.5/src/cmodulator.cpp000066400000000000000000000024311304636156700164770ustar00rootroot00000000000000/*************************************************************************** cmodulator.cpp - description ------------------- begin : Mon Aug 20 2001 copyright : (C) 2001 by Volker Schroer email : dl1ksv@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; transmitBuffer=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; } linpsk-1.3.5/src/cmodulator.h000066400000000000000000000034211304636156700161440ustar00rootroot00000000000000/*************************************************************************** cmodulator.h - description ------------------- begin : Mon Aug 20 2001 copyright : (C) 2001 by Volker Schroer email : dl1ksv@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 #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 *transmitBuffer; public slots: signals: void charSend(char); }; #endif linpsk-1.3.5/src/color.h000066400000000000000000000153061304636156700151160ustar00rootroot00000000000000/*************************************************************************** color.h - description ------------------- begin : Sun Mar 26 2000 copyright : (C) 2000 by Volker Schroer email : DL1KSV@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 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 linpsk-1.3.5/src/constants.h000066400000000000000000000314511304636156700160130ustar00rootroot00000000000000/*************************************************************************** constants.h - description ------------------- begin : Fri Apr 21 2000 copyright : (C) 2000 by Volker Schroer email : DL1KSV@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 // for some constants like PI #include #include #include enum BUTTONSTATUS // Status of RX/TX Button { UNDEF, // undefined ON, // TX OFF, // RX SW // Switching to RX }; #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 TXWINDOWBUFFER 6 // Mux Number of Lines in TX 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 #define PHASE_DISPLAY_BUFFER_LENGTH 12 struct Band { QString bandName; int bandStart; int bandEnd; int preferedFreq; }; enum Mode {BPSK31=0,BPSK63,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}; enum QsoData{CallSign,QTH,Name,Locator,RST,DOK}; 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 HisRST; QString MyRST; QDate QsoDate; QTime QsoTime; QString mainPrefix; QString continent; QString wazZone; QString ituZone; QString countryName; QString worked; QString dokName; } QsoInfo; //enum LangType{0,1,2}; struct Macro { QString name; QString text; QString accelerator; int languageType; // 0,1,2 languageType-3 >> Macro is disabled }; 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 }; #endif linpsk-1.3.5/src/cpskdemodulator.cpp000066400000000000000000000126261304636156700175350ustar00rootroot00000000000000/*************************************************************************** * * * 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 //#include #include "cpskdemodulator.h" #include "firfilter.h" #include "parameter.h" #include extern Parameter settings; CPskDemodulator::CPskDemodulator(): CDemodulator() { int i,temp; m_LastFreq = 1000.0; m_BitPhasePos = 0.0; Prev_Sample=complex(0.0,0.0) ; Phase_Vector = Prev_Sample; m_DevAve = 0.78; // FastSquelch fastSquelch=false; // IMD IMD=0.0; // Means Unknown f1=15.625; f2=46.875; x_loop_1=0; y_loop_1=0; m_SampCnt = 0; m_VaricodeDecTbl = NULL; downFilter = NULL; syncFilter = NULL; for(i=0; i < 20; i++ ) syncBuf[i]=0; m_VaricodeDecTbl = new unsigned char[2048]; for (i=0;i< PHASE_DISPLAY_BUFFER_LENGTH; i++) Phase[i]=0.0; phasePosition=0; for(i=0; i < 2048;i++) m_VaricodeDecTbl[i]=0; for(i=0; i<256;i++) { temp = VARICODE_TABLE[i]; temp >>= 4; while( !(temp&1) ) temp >>= 1; temp >>= 1; m_VaricodeDecTbl[temp] = (unsigned char)i; } m_BitAcc=0; m_LastBitZero = false; m_OnCount=0; m_OffCount=0; } CPskDemodulator::~CPskDemodulator() { if(m_VaricodeDecTbl) delete m_VaricodeDecTbl; } void CPskDemodulator::ProcessInput( double* pIn, double *Spectrum) { double vcophz = OszFrequency; int i; complex acc; if ( UseAfc == Wide ) { // Check if we are near the centerphasePosition 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; } if( RxFrequency != m_LastFreq ) //caller is changing center frequency { OszFreqinc = (PI2/SampleRate)*RxFrequency; //new center freq inc m_LastFreq = RxFrequency; } for( i = 0; i PI2) //handle 2 Pi wrap around vcophz -= PI2; complex xxx =pIn[i]*complex(cos(vcophz),sin(vcophz)); // assert(isnan(xxx.real()) == 0); downFilter->processFilter(&xxx,&acc,1); // assert(isnan(acc.real()) == 0); m_SampCnt++; if( (m_SampCnt%downRate) == 0) { syncFilter->processFilter(&acc,&xxx,1); // assert(isnan(xxx.real()) ==0); if( symbSync(xxx)) { Phase_Vector=xxx *conj(Prev_Sample); Prev_Sample = xxx; Phase[phasePosition++]=Phase_Vector; if(phasePosition >=PHASE_DISPLAY_BUFFER_LENGTH) phasePosition=0; 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; OszFrequency = vcophz; if (UseAfc != Off) // Change RxFrequency, but slowly { RxFrequency=OszFreqinc*SampleRate/PI2; m_LastFreq=RxFrequency; } } complex * CPskDemodulator::getPhasePointer() { return Phase; } int CPskDemodulator::getSquelchValue() { return (int) m_DevAve; } void CPskDemodulator::calcIMD(double *Spectrum) { int freq1,freq2; freq1 = (int) ((RxFrequency+f1)/2.69165); freq2 = (int) ((RxFrequency+f2)/2.69165); IMD=(Spectrum[freq2-1]+Spectrum[freq2]+Spectrum[freq2+1])/(Spectrum[freq1-1]+Spectrum[freq1]+Spectrum[freq1+1]); freq1=(int) ( (RxFrequency- f1)/2.69165); freq2=(int) ( (RxFrequency- f2)/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; } bool CPskDemodulator::symbSync(complex sample) { bool trigger; double sum,ampsum; trigger =false; int index = (int) m_BitPhasePos; // assert((index >= 0) && (index <20)); syncBuf[index] = 0.7 * syncBuf[index] + 0.3 * abs(sample); // syncBuf[index] = abs(sample); sum=0; ampsum=0; index = SYNCBUFFERLENGTH/2; for(int i=0; i =SYNCBUFFERLENGTH) { m_BitPhasePos -=SYNCBUFFERLENGTH; trigger = true; } else if(m_BitPhasePos < 0.) m_BitPhasePos +=SYNCBUFFERLENGTH; return trigger; } linpsk-1.3.5/src/cpskdemodulator.h000066400000000000000000000042631304636156700172000ustar00rootroot00000000000000/*************************************************************************** * * * 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 #include #include #include "cdemodulator.h" #define SYNCBUFFERLENGTH 20 // Just small oversample class FIRFilter; class CPskDemodulator : public CDemodulator { Q_OBJECT public: CPskDemodulator(); virtual ~CPskDemodulator(); int getSquelchValue(); void ProcessInput( double *pIn, double *Spectrum); complex * 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 double m_LastFreq; complex Prev_Sample; complex Phase_Vector; bool m_LastBitZero; int m_BitAcc; int m_OnCount; int m_OffCount; unsigned char* m_VaricodeDecTbl; double m_DevAve; bool fastSquelch; FIRFilter *downFilter; int downRate; FIRFilter *syncFilter; float f1,f2; virtual double calcFreqError(complex) =0; /** Some Variable for CalcQuality */ double x_loop_1,y_loop_1; private: bool symbSync( complex sample); void calcIMD(double *Spectrum); //variables int m_SampCnt; // Phase Values complex Phase[PHASE_DISPLAY_BUFFER_LENGTH]; int phasePosition; // Position in phase display buffer double syncBuf[SYNCBUFFERLENGTH]; // samples per symbol float m_BitPhasePos; float IMD; public slots: signals: // Signals }; #endif linpsk-1.3.5/src/crxchannel.cpp000066400000000000000000000172051304636156700164600ustar00rootroot00000000000000/*************************************************************************** * * * 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 #include #include "crxchannel.h" #include "cdemodulator.h" #include "crxwindow.h" #include "qpskdemodulator.h" #include "bpskdemodulator.h" #include "psk63demodulator.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(); SampleRate = 11025; BufferLength = BUF_SIZE; break; case RTTY: Demodulator = new RTTYDemodulator(); SampleRate = 11025; BufferLength = BUF_SIZE; break; case MFSK16: Demodulator = new MFSKDemodulator(); SampleRate = 11025; BufferLength = BUF_SIZE; break; case BPSK63: Demodulator = new PSk63Demodulator(); SampleRate = 11025; BufferLength = BUF_SIZE; break; case BPSK31: Demodulator = new BPskDemodulator(); 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* CRxChannel::getPhasePointer() { return Demodulator->getPhasePointer(); } 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(); SampleRate = 11025; BufferLength = BUF_SIZE; break; case RTTY: Demodulator = new RTTYDemodulator(); SampleRate = 11025; BufferLength = BUF_SIZE; break; case MFSK16: Demodulator = new MFSKDemodulator(); SampleRate = 11025; BufferLength = BUF_SIZE; break; case BPSK63: Demodulator = new PSk63Demodulator(); SampleRate = 11025; BufferLength = BUF_SIZE; break; case BPSK31: Demodulator = new BPskDemodulator(); 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(); } CRxWindow *CRxChannel::getWindow() { return RxWindow; } linpsk-1.3.5/src/crxchannel.h000066400000000000000000000051411304636156700161210ustar00rootroot00000000000000/*************************************************************************** crxchannel.h - description ------------------- begin : Sam Jan 4 2003 copyright : (C) 2003 by Volker Schroer email : dl1ksv@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 #include "constants.h" #include #include "cdemodulator.h" /**Class to administrate the different RX Channels *@author Volker Schroer */ class CRxWindow; class QWidget; #include class CRxChannel : public QObject { Q_OBJECT public: CRxChannel(int ID,QWidget* parent=0,Mode DemodulatorType= BPSK31,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(); CRxWindow *getWindow(); 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(); std::complex* getPhasePointer(); public slots: void setRxFrequency(double); void hide(); void show(); class CRxChannel *getChannel(int); void setAfcMode(AfcMode); 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 linpsk-1.3.5/src/crxwindow.cpp000066400000000000000000000215721304636156700163610ustar00rootroot00000000000000/*************************************************************************** * * * 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 #include #include #include #include #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()+3; int pixelwidth=82*fm.width("A"); DisplayBox = new QWidget (); DisplayBox-> setFocusPolicy( Qt::NoFocus); DisplayBox->setGeometry( 0,0 ,pixelwidth, RXWINDOWBUFFER*rowHeight ); DisplayBox->setContextMenuPolicy ( Qt::CustomContextMenu ); connect ( DisplayBox, SIGNAL ( customContextMenuRequested ( QPoint ) ), this, SLOT ( contextMenu ( QPoint ) ) ); setWidget ( DisplayBox ); linesLayout = new QVBoxLayout(DisplayBox); linesLayout->setSpacing(0); linesLayout->setContentsMargins(0, 0, 0, 0); linesLayout->setObjectName(QString::fromUtf8("linesLayout")); linesLayout->setSizeConstraint(QLayout::SetNoConstraint); setHorizontalScrollBarPolicy ( Qt::ScrollBarAsNeeded ); setVerticalScrollBarPolicy ( Qt::ScrollBarAlwaysOn ); trigger = false; TriggerText = ""; TexttoTrigger = ""; save = false; stream = 0; Row = 0; Column = 0; AutoScroll = true; for ( int i = 0;i < RXWINDOWBUFFER;i++ ) { ScrollBuffer[i] = new QLineEdit ( DisplayBox ); ScrollBuffer[i]->setFixedWidth(pixelwidth); ScrollBuffer[i]->setMaximumHeight(18); ScrollBuffer[i]->setFrame ( false ); ScrollBuffer[i]->setReadOnly ( true ); linesLayout->addWidget(ScrollBuffer[i]); ScrollBuffer[i]->setContextMenuPolicy ( Qt::NoContextMenu ); } 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() ) ); A = menu->addAction ("Dok"); connect ( A, SIGNAL ( triggered() ), this, SLOT ( copyDok() ) ); A = menu->addAction ("Clipboard"); connect ( A, SIGNAL ( triggered() ), this, SLOT ( copy() ) ); 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 ( QLatin1Char ( 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; 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() ); int pixelwidth=82*fm.width("A"); for ( int i = 0;i < RXWINDOWBUFFER;i++ ) ScrollBuffer[i]->setFixedWidth( pixelwidth ); DisplayLineHeight = ScrollBuffer[0]->height()-1; } **/ 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::contextMenu ( QPoint p ) { int selectedLine, selectedColumn; char c = 0xF8; QPoint p1 = QCursor::pos(); // selectedLine = (p.y()-3) / (ScrollBuffer[0]->height()-1); selectedLine = p.y() / ScrollBuffer[0]->height(); #ifndef QT_NO_DEBUG qDebug("Line %d selected, lineheight, %d ",selectedLine,ScrollBuffer[0]->height()); qDebug("*****Cursor: x: %i y: %i",p.x(),p.y()); int start; start=selectedLine-4; if(start <0) start=0; for(int i=start;i <=selectedLine;i++) { qDebug("Zeile: %i, %s",i,qPrintable(ScrollBuffer[i]->text())); } qDebug("***Menuposition x: %i y: %i",p1.x(),p1.y()); #endif if(selectedLine >= RXWINDOWBUFFER) selectedLine=RXWINDOWBUFFER-1; selectedColumn=0; if(!ScrollBuffer[selectedLine]->hasSelectedText()) { selectedColumn = ScrollBuffer[selectedLine]->cursorPositionAt ( QPoint ( p.x(), 2 ) ); ScrollBuffer[selectedLine]->setCursorPosition ( selectedColumn ); ScrollBuffer[selectedLine]->cursorWordForward ( true ); } selectedString = ScrollBuffer[selectedLine]->selectedText(); if(!selectedString.endsWith(QChar(' '))) { ScrollBuffer[selectedLine]->cursorWordForward ( true ); selectedString = ScrollBuffer[selectedLine]->selectedText(); if(!selectedString.endsWith(QChar(' '))) // / + extension might belong to the text (callsign) { 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(); } menu->exec ( p1 ); ScrollBuffer[selectedLine]->deselect(); } void CRxWindow::copyCallSign() { emit setQsoData(CallSign, selectedString ); } void CRxWindow::copyQTH() { emit setQsoData( QTH, selectedString ); } void CRxWindow::copyName() { emit setQsoData( Name, selectedString ); } void CRxWindow::copyLocator() { emit setQsoData( Locator, selectedString ); } void CRxWindow::copyRST() { emit setQsoData( RST, selectedString ); } void CRxWindow::copyDok() { emit setQsoData( DOK, selectedString ); } void CRxWindow::copy() { QApplication::clipboard()->setText(selectedString); } linpsk-1.3.5/src/crxwindow.h000066400000000000000000000034701304636156700160230ustar00rootroot00000000000000/*************************************************************************** * * * 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 #include "constants.h" #include #include class QLineEdit; class QWidget; class QString; class QMenu; class QVBoxLayout; 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 & ); protected slots: void copyCallSign(); void copyQTH(); void copyName(); void copyLocator(); void copyRST(); void copyDok(); void copy(); private: QVBoxLayout *linesLayout; 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; signals: void Triggered(); void setQsoData(QsoData,QString); }; #endif // CRXWINDOW_H linpsk-1.3.5/src/csound.cpp000066400000000000000000000420011304636156700156160ustar00rootroot00000000000000/*************************************************************************** csound.cpp - description ------------------- begin : Wed Apr 5 2000 copyright : (C) 2000 by Volker Schroer email : huv.schroer@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 #include using namespace std; extern Parameter settings; #ifdef SOUND_DEBUG static snd_pcm_format_t format_types[] = { // SND_PCM_FORMAT_UNKNOWN, SND_PCM_FORMAT_S8, SND_PCM_FORMAT_U8, SND_PCM_FORMAT_S16_LE, SND_PCM_FORMAT_S16_BE, SND_PCM_FORMAT_U16_LE, SND_PCM_FORMAT_U16_BE, SND_PCM_FORMAT_S24_LE, SND_PCM_FORMAT_S24_BE, SND_PCM_FORMAT_U24_LE, SND_PCM_FORMAT_U24_BE, SND_PCM_FORMAT_S32_LE, SND_PCM_FORMAT_S32_BE, SND_PCM_FORMAT_U32_LE, SND_PCM_FORMAT_U32_BE, SND_PCM_FORMAT_FLOAT_LE, SND_PCM_FORMAT_FLOAT_BE, SND_PCM_FORMAT_FLOAT64_LE, SND_PCM_FORMAT_FLOAT64_BE, SND_PCM_FORMAT_IEC958_SUBFRAME_LE, SND_PCM_FORMAT_IEC958_SUBFRAME_BE, SND_PCM_FORMAT_MU_LAW, SND_PCM_FORMAT_A_LAW, SND_PCM_FORMAT_IMA_ADPCM, SND_PCM_FORMAT_MPEG, SND_PCM_FORMAT_GSM, SND_PCM_FORMAT_SPECIAL, SND_PCM_FORMAT_S24_3LE, SND_PCM_FORMAT_S24_3BE, SND_PCM_FORMAT_U24_3LE, SND_PCM_FORMAT_U24_3BE, SND_PCM_FORMAT_S20_3LE, SND_PCM_FORMAT_S20_3BE, SND_PCM_FORMAT_U20_3LE, SND_PCM_FORMAT_U20_3BE, SND_PCM_FORMAT_S18_3LE, SND_PCM_FORMAT_S18_3BE, SND_PCM_FORMAT_U18_3LE, SND_PCM_FORMAT_U18_3BE }; static unsigned int test_rates[] = { 8000, 11025, 16000, 22050, 32000, 44100, 48000, 96000, 192000 }; #define NELEMS(x) (sizeof(x)/sizeof(x[0])) #endif CSound::CSound ( int ptt = -1 ) : Input ( ptt ) { started = false; output = false; freePointer = 0; available = 0; readPointer = 0; free = 2 * BUF_SIZE; handle=0; } 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; QString device(""); // Could InputDeviceName contain a card name ? if(!settings.InputDeviceName.contains(':')) // Could be card name, so check /proc/asound/cards { int card_number=getDeviceNumber(settings.InputDeviceName); if(card_number < 0) device=settings.InputDeviceName; else device = QString("plughw:%1").arg(card_number); } else device=settings.InputDeviceName; err = snd_pcm_open ( &handle, device.toLatin1(), SND_PCM_STREAM_CAPTURE, SND_PCM_ASYNC ); if ( err < 0 ) { *errorstring = QString ( "Unable to open Device: " )+ settings.InputDeviceName + QString(" ") + 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; } #ifdef SOUND_DEBUG dump_hw_params(handle,hwparams); #endif /* 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 ); // err = snd_pcm_hw_params_set_format ( handle, hwparams, SND_PCM_FORMAT_S32_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 ) ); #ifdef SOUND_DEBUG dump_hw_params(handle,hwparams); #endif 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; QString device(""); // Could OutputDeviceName contain a card name ? if(!settings.OutputDeviceName.contains(':')) // Could be card name, so check /proc/asound/cards { int card_number=getDeviceNumber(settings.OutputDeviceName); if(card_number < 0) device=settings.OutputDeviceName; else device = QString("plughw:%1").arg(card_number); } else device=settings.OutputDeviceName; err = snd_pcm_open ( &handle, device.toLatin1(), SND_PCM_STREAM_PLAYBACK, 0 ); if ( err < 0 ) { *errorstring = QString ( "Unable to open Device: " )+settings.OutputDeviceName+ QString(" ") + 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",(int) buffer_size); err = snd_pcm_hw_params ( handle, hwparams ); if ( err < 0 ) { *errorstring = QString ( "Unable to set hw params for Output: " ) + 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", (int) 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 ); } if (ii < 0) qDebug("Error using serial port"); 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 > 0) { qDebug("Strange situation, only %d bytes read\nRetry",err); snd_pcm_prepare ( handle ); snd_pcm_start ( handle ); } 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 || (!started && (toBePlayed >0))) // We should flush the buffer { LockPointers.lock(); if ( toBePlayed <= BUF_SIZE && ( !signaled ) ) { emit samplesAvailable(); signaled = true; } while ( toBePlayed < laenge && started ) WakeUp.wait ( &LockPointers ); LockPointers.unlock(); 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 ( " %s\nStopping Play Thread", snd_strerror ( err ) ); break; } } } snd_pcm_drain ( handle ); qDebug ( "Play Thread terminated" ); } int CSound::getDeviceNumber(QString device) { std::string line; std::ifstream cards( "/proc/asound/cards" ); int id; id=-1; if ( cards.is_open() ) { while ( cards.good() ) { getline (cards, line); if ( line.find( device.toStdString() ) != std::string::npos ) { std::istringstream( line ) >>id; cards.close(); return id; } } } cards.close(); return id; } #ifdef SOUND_DEBUG void CSound::dump_hw_params(snd_pcm_t *h,snd_pcm_hw_params_t* hw_p) { unsigned int i; qDebug("PCM name: %s\n", snd_pcm_name (h)); qDebug("Formats:\n"); for (i = 0; i < NELEMS (format_types); i++){ snd_pcm_format_t ft = format_types[i]; if (snd_pcm_hw_params_test_format (h, hw_p, ft) == 0) qDebug( " %-20s YES", snd_pcm_format_name (ft)); } qDebug("Sample Rates:\n"); for (i = 0; i < NELEMS (test_rates); i++){ unsigned int rate = test_rates[i]; qDebug( " %6u %s", rate, snd_pcm_hw_params_test_rate (h, hw_p, rate, 0) == 0 ? "YES" : "NO"); } } #endif linpsk-1.3.5/src/csound.h000066400000000000000000000041541304636156700152720ustar00rootroot00000000000000/*************************************************************************** csound.h - description ------------------- begin : Wed Apr 5 2000 copyright : (C) 2000 by Volker Schroer email : DL1KSV@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 #include #include #include #include #include #include #include "input.h" #include "constants.h" #include #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(); int getDeviceNumber(QString device); #ifdef SOUND_DEBUG void dump_hw_params(snd_pcm_t *h,snd_pcm_hw_params_t* hw_p); #endif protected: void run(); int free, freePointer, available, readPointer,toBePlayed; }; #endif linpsk-1.3.5/src/csquelch.cpp000066400000000000000000000106351304636156700161420ustar00rootroot00000000000000/*************************************************************************** |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 #include #include #include #include #include #include #include #include #include #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 pos; p.begin ( this ); // Get Parameters of the Slider initStyleOption ( &option ); pos=option.sliderPosition; option.sliderPosition=SquelchLevel; option.type = QStyleOption::SO_Slider; option.subControls = QStyle::SC_SliderGroove; if ( SquelchLevel < pos ) option.palette.setColor( QPalette::Normal,QPalette::Highlight,Qt::yellow); else option.palette.setColor( QPalette::Normal,QPalette::Highlight,Qt::cyan); p.drawComplexControl ( QStyle::CC_Slider, option ); option.sliderPosition=pos; option.subControls = QStyle::SC_SliderHandle; option.palette.setColor ( QPalette::Button, Qt::red ); p.drawComplexControl ( QStyle::CC_Slider, option ); p.end(); } 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 (QWidget* parent ) : QGroupBox ( 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 ); } linpsk-1.3.5/src/csquelch.h000066400000000000000000000035741304636156700156130ustar00rootroot00000000000000/*************************************************************************** |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 #include class QRadioButton; #include 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(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 linpsk-1.3.5/src/ctxbuffer.cpp000066400000000000000000000057431304636156700163270ustar00rootroot00000000000000/*************************************************************************** ctxbuffer.cpp - description ------------------- begin : Sam Feb 22 2003 copyright : (C) 2003 by Volker Schroer email : dl1ksv@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 #include 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; if( filled < 0) { filled=1; txbuffer[inpos++]=c; } } else { inpos--; if (inpos < 0) inpos +=TXBUFFER_LENGTH; } } } void CTxBuffer::clear() { /** if(filled > 0) { if(txbuffer[(outpos+filled-1) % TXBUFFER_LENGTH] == TXOFF_CODE) // We have to keep switching to rx { outpos = (outpos+filled-1) % TXBUFFER_LENGTH; inpos = (inpos+filled-1) % TXBUFFER_LENGTH; filled=1; return; } } **/ filled=0; inpos=0; outpos=0; } void CTxBuffer::insert(QString Text,int length) { for (int i=0;i Filled()) // Wait until Buffer is not filled qApp->processEvents(QEventLoop::AllEvents,100); filled++; txbuffer[inpos++]=Text.at(i).toLatin1(); inpos = inpos % TXBUFFER_LENGTH; } } } bool CTxBuffer::isEmpty() { return (filled== 0); } linpsk-1.3.5/src/ctxbuffer.h000066400000000000000000000026371304636156700157730ustar00rootroot00000000000000/*************************************************************************** ctxbuffer.h - description ------------------- begin : Sam Feb 22 2003 copyright : (C) 2003 by Volker Schroer email : dl1ksv@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(); bool isEmpty(); private: int txbuffer[TXBUFFER_LENGTH]; int filled; int inpos; int outpos; }; #endif linpsk-1.3.5/src/deinterleaver.cpp000066400000000000000000000041111304636156700171540ustar00rootroot00000000000000/*************************************************************************** deinterleaver.cpp - description ------------------- begin : Sam Feb 1 2003 copyright : (C) 2003 by Volker Schroer email : dl1ksv@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 // //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 }; linpsk-1.3.5/src/firfilter.cpp000066400000000000000000000072771304636156700163310ustar00rootroot00000000000000/*************************************************************************** firfilter.cpp - description ------------------- begin : Fr Nov 7 2003 copyright : (C) 2003 by Volker Schroer email : dl1ksv@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 #include "firfilter.h" #include FIRFilter::FIRFilter(double Fc, int Filterlength, FilterMode Mode, double gain) { // Cutoff Fc in radians double normalize = 0; int fhalbe; assert(Filterlength%2 == 1); fhalbe=(Filterlength-1)/2; NxCoeffs=Filterlength; h=new double[Filterlength]; if (Mode == RealData) { filterbuffer=new double[Filterlength]; cfilterbuffer = 0; } else { cfilterbuffer=new complex[Filterlength]; filterbuffer =0; } /** Calculate coefficients of sinc lp filter */ // sin(x-tau)/(x-tau) for (int i = 0; i < Filterlength; i++) if (i == fhalbe) h[i] = Fc; else h[i] = sin(Fc*(i - fhalbe))/(i-fhalbe); // blackman window for (int i = 1; i < Filterlength+1; i++) h[i-1] = h[i-1] * (0.42 - 0.5 * cos(2*M_PI*i/(Filterlength+1)) + 0.08 * cos(4*M_PI*i/(Filterlength+1))); // h[0]=0; // h[Filterlength-1]=0; // normalization factor for (int i = 1; i < Filterlength-1; i++) normalize += h[i]; if(gain !=0) normalize /=gain; // normalize the filter for (int i = 1; i < Filterlength-1; i++) h[i] /= normalize; for(int i=0;i (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 = (filterbuffer + NxCoeffs ) ) fbPtr=filterbuffer; *oPtr++ =acc; } fbBuffer=fbPtr; } /** void FIRFilter::setnewCoeffs(double *Filtercoeffs) { for(int i=0;i *input,complex *output,int NxSamples) { complex *oPtr,*fbPtr; complex acc; double *fPtr; oPtr=output; fbPtr=cfbBuffer; for(int i=0; i = (cfilterbuffer + NxCoeffs ) ) fbPtr=cfilterbuffer; *oPtr++ =acc; } cfbBuffer=fbPtr; } linpsk-1.3.5/src/firfilter.h000066400000000000000000000031571304636156700157670ustar00rootroot00000000000000/*************************************************************************** firfilter.h - description ------------------- begin : Fr Nov 7 2003 copyright : (C) 2003 by Volker Schroer email : dl1ksv@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 using namespace std; /**Implements an FIR- Filter *@author Volker Schroer */ enum FilterMode{RealData,ComplexData}; class FIRFilter { public: FIRFilter(double Fc, int Filterlength, FilterMode, double gain =1.); ~FIRFilter(); void processFilter(double *input,double *output,int NxSamples); void processFilter(complex *input,complex *output,int NxSamples); // void setnewCoeffs(double *Filtercoeffs); private: int NxCoeffs; double *h; complex *cfilterbuffer; complex *cfbBuffer; double *filterbuffer; double *fbBuffer; }; #endif linpsk-1.3.5/src/frequencyselect.cpp000066400000000000000000000112641304636156700175330ustar00rootroot00000000000000/*************************************************************************** |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 #include /* * 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( 100 ); 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; } linpsk-1.3.5/src/frequencyselect.h000066400000000000000000000036071304636156700172020ustar00rootroot00000000000000/*************************************************************************** |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 #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); }; #endif // FREQUENCYSELECT_H linpsk-1.3.5/src/fskmodulator.cpp000066400000000000000000000035021304636156700170400ustar00rootroot00000000000000/*************************************************************************** fskmodulator.cpp - description ------------------- begin : Sam Mär 1 2003 copyright : (C) 2003 by Volker Schroer email : dl1ksv@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=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; } linpsk-1.3.5/src/fskmodulator.h000066400000000000000000000017621304636156700165130ustar00rootroot00000000000000/*************************************************************************** * * * 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 FSKMODULATOR_H #define FSKMODULATOR_H #include "cmodulator.h" 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[16]; double ToneFrequencyi[16]; double Frequencyr,Frequencyi; unsigned int SamplesperSymbol; float Baudrate; unsigned int NxSamples; private: int c; }; #endif linpsk-1.3.5/src/input.cpp000066400000000000000000000023021304636156700154620ustar00rootroot00000000000000/*************************************************************************** input.cpp - description ------------------- begin : Sat May 5 2001 copyright : (C) 2001 by Volker Schroer email : DL1KSV@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 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; } linpsk-1.3.5/src/input.h000066400000000000000000000041551304636156700151370ustar00rootroot00000000000000/*************************************************************************** input.h - description ------------------- begin : Sat May 5 2001 copyright : (C) 2001 by Volker Schroer email : DL1KSV@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 #include #include #include #include /**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 linpsk-1.3.5/src/interleaver.cpp000066400000000000000000000041111304636156700166430ustar00rootroot00000000000000/*************************************************************************** interleaver.cpp - description ------------------- begin : Sam Mär 1 2003 copyright : (C) 2003 by Volker Schroer email : dl1ksv@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; } linpsk-1.3.5/src/interleaver.h000066400000000000000000000024341304636156700163160ustar00rootroot00000000000000/*************************************************************************** interleaver.h - description ------------------- begin : Sam Mär 1 2003 copyright : (C) 2003 by Volker Schroer email : dl1ksv@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 linpsk-1.3.5/src/main.cpp000066400000000000000000000025371304636156700152610ustar00rootroot00000000000000/*************************************************************************** main.cpp - description ------------------- begin : Sam Nov 23 11:37:46 CET 2002 copyright : (C) 2002 by Volker Schroer email : dl1ksv@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 #endif #include #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; } linpsk-1.3.5/src/mfskdemodulator.cpp000066400000000000000000000135721304636156700175360ustar00rootroot00000000000000/*************************************************************************** mfskdemodulator.cpp - description ------------------- begin : Mit Jan 29 2003 copyright : (C) 2003 by Volker Schroer email : dl1ksv@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 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; } void 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 ( 0.0, 0.0 ); for ( i = 0; i < RESOLUTION;i++ ) twiddles[i] = complex ( cos ( i * M_PI / RESOLUTION ), - sin ( i * M_PI / RESOLUTION ) ); } 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; 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 ); 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 accu; int index; index = 0; for ( int i = 0; i <= ( NxSamples - DOWNRATE );i += DOWNRATE ) { accu = complex ( 0., 0. ); for ( int k = i;k < i + DOWNRATE;k++ ) { accu += inputBuffer[k] * exp ( complex ( 0., -OszFrequency ) );; OszFrequency += OszFreqinc; OszFrequency = fmod ( OszFrequency, M_PI + M_PI ); } downBuffer[index] = accu; index++; } } void MFSKDemodulator::sfft ( complex input ) { complex z; int i, j, index; /* calculate the energy */ delayLine[processPtr] = input; if ( bitEstimatePtr >= 0 ) { for ( i = 0; i < 48; i++ ) { z = complex ( 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];; freq=pos=0; // 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; } linpsk-1.3.5/src/mfskdemodulator.h000066400000000000000000000050131304636156700171720ustar00rootroot00000000000000/*************************************************************************** mfskdemodulator.h - description ------------------- begin : Mit Jan 29 2003 copyright : (C) 2003 by Volker Schroer email : dl1ksv@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 #include 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(); void 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 *history; Viterbi * viterbi; void sfft(complex); void bitEstimate(); void afc(int,double); void recvbit(int); int processPtr,bitEstimatePtr,syncPtr,oscPos; /******************************/ /** coeficients for slidding fft */ complex twiddles[RESOLUTION];; complex downBuffer[DOWNSAMPLEDBUFFERLENGTH]; complex 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 linpsk-1.3.5/src/mfskmodulator.cpp000066400000000000000000000070301304636156700172150ustar00rootroot00000000000000/*************************************************************************** mfskmodulator.cpp - description ------------------- begin : Fre Feb 28 2003 copyright : (C) 2003 by Volker Schroer email : dl1ksv@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 ( unsigned 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 = transmitBuffer->getTxChar(); if ( ch < 0 ) { if ( ch == TXOFF_CODE ) // { postamblePtr = 10; // ch=0; // } // else ch = 0; // } 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 ) ); } } } linpsk-1.3.5/src/mfskmodulator.h000066400000000000000000000034571304636156700166730ustar00rootroot00000000000000/*************************************************************************** mfskmodulator.h - description ------------------- begin : Fre Feb 28 2003 copyright : (C) 2003 by Volker Schroer email : dl1ksv@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 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 linpsk-1.3.5/src/mfskvaricode.cpp000066400000000000000000000062021304636156700170030ustar00rootroot00000000000000/*************************************************************************** mfskvaricode.cpp - description ------------------- begin : Sam Mär 1 2003 copyright : (C) 2003 by Volker Schroer email : dl1ksv@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]; } linpsk-1.3.5/src/mfskvaricode.h000066400000000000000000000024401304636156700164500ustar00rootroot00000000000000/*************************************************************************** mfskvaricode.h - description ------------------- begin : Sam Mär 1 2003 copyright : (C) 2003 by Volker Schroer email : dl1ksv@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 linpsk-1.3.5/src/parameter.cpp000066400000000000000000000034161304636156700163120ustar00rootroot00000000000000/*************************************************************************** parameter.cpp - description ------------------- begin : Sat Apr 1 2000 copyright : (C) 2000 by Volker Schroer email : DL1KSV@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 callsign=""; QslData=0; serial=-1; // Serial none SerialDevice="none"; QSOFileName="QSOData.adif"; timeoffset=-2; DemoMode=true; slashed0=false; autoCrLf=true; autoDate=true; RxChannels=1; ActChannel = 0; // Pointer to the active Channel ChannelChain = 0; // Pointer to the Start of the Rx - ChannelChain ApplicationFont =0; dateFormat="dd.MM.yyyy"; InputDeviceName="LinPSK_Record"; OutputDeviceName="LinPSK_Play"; sampleRate=11025; complexFormat=false; LangName[0]="B"; LangName[1]="E"; LangName[2]="G"; /** Rig **/ rigModelNumber=0; // No rig #ifdef WITH_HAMLIB rig=0; #endif rigDevice="none"; QsoFrequency=-1; pwr=5; handshake=1; // hardware baudrate=9600; } Parameter::~Parameter() { } linpsk-1.3.5/src/parameter.h000066400000000000000000000052561304636156700157630ustar00rootroot00000000000000/*************************************************************************** parameter.h - description ------------------- begin : Sat Apr 1 2000 copyright : (C) 2000 by Volker Schroer email : DL1KSV@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 #include #include #include #include #include #include "constants.h" class CRxChannel; class QString; class QFont; class RigControl; /**Contains parameters for transmitting and receiving some of them are set by settup *@author Volker Schroer */ class Parameter { public: Parameter(); ~Parameter(); void setupDevices(); // Variables QString callsign; // Callsign QString myLocator; QString inputFilename; //Name of Demofile 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 ? QString LangName[3]; //Contains the used language names for button labeling int timeoffset; // offset to UTC /** DeviceSection */ QString InputDeviceName; QString OutputDeviceName; int sampleRate; bool complexFormat; bool slashed0; // True if to print 0 slashed bool autoCrLf; // True if sending cr lf on enter bool autoDate; // True if date/time will be set automatically when qso data are saved // If false, fields are displayed in qso data and editable int RxChannels; CRxChannel * ChannelChain; CRxChannel * ActChannel; QsoInfo *QslData; BUTTONSTATUS Status; QFont *ApplicationFont; QString dateFormat; /** Rig **/ int QsoFrequency; // Number of item in QCombobox int pwr; int rigModelNumber; int handshake; int baudrate; #ifdef WITH_HAMLIB RigControl *rig; #endif QString rigDevice; QList bandList; }; #endif linpsk-1.3.5/src/processlogdata.cpp000066400000000000000000000117741304636156700173520ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2005 by Volker Schroer * * dl1ksv@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 #include #include #include #include #include ProcessLogData::ProcessLogData ( QObject *parent ) : QThread ( parent ) { tcpSocket = 0; connectionEstablished = false; connectionError = false; connect(this,SIGNAL(executeAction()),this,SLOT(doAction()),Qt::QueuedConnection); } ProcessLogData::~ProcessLogData() { } void ProcessLogData::saveQsoData ( QString s ) { actionString = s; emit executeAction(); } void ProcessLogData::requestCallsign (QLabel **r, QString s ) { actionString.clear(); actionString.append ( "@@@@" ); actionString.append ( s ); actionString.append ( "\r\n" ); for ( int i = 0; i < 6;i++ ) results[i] = r[i]; emit executeAction(); } void ProcessLogData::run() { connectionEstablished = false; connectionError = false; qRegisterMetaType ( "QAbstractSocket::SocketError" ); tcpSocket = new QTcpSocket(); connect ( tcpSocket, SIGNAL ( disconnected() ), this, SLOT ( connectionClosedbyHost() ) ,Qt::QueuedConnection); connect ( tcpSocket, SIGNAL ( readyRead() ), this, SLOT ( readAnswer() ) ,Qt::QueuedConnection); connect ( tcpSocket, SIGNAL ( connected() ), this, SLOT ( setConnected() ) ,Qt::QueuedConnection); connect ( tcpSocket, SIGNAL ( error ( QAbstractSocket::SocketError ) ), this, SLOT ( setError ( QAbstractSocket::SocketError ) ) ); tcpSocket->connectToHost ( QHostAddress::LocalHost, 8080, QIODevice::ReadWrite ); tcpSocket->waitForConnected(6000); exec(); } void ProcessLogData::doAction() { if ( !connectionEstablished ) usleep ( 6000 ); while (tcpSocket == 0) // On heavy loaded systems it might last some times until socket is created 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; } //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() ); } /** qt 4.7 lets flush write data again*/ // tcpSocket->flush(); } void ProcessLogData::connectionClosedbyHost() { connectionEstablished = false; tcpSocket->disconnect(); 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; } linpsk-1.3.5/src/processlogdata.h000066400000000000000000000044111304636156700170050ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2005 by Volker Schroer * * dl1ksv@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 #include class QString; class QLabel; /** Sends logdata to the linlogbook server and requests infos for a callsign from the linlogbook server @author Volker Schroer */ class ProcessLogData : public QThread { Q_OBJECT public: ProcessLogData ( QObject *parent = 0 ); ~ProcessLogData(); void saveQsoData ( QString s ); void run(); void requestCallsign (QLabel **r, QString s ); private: QString actionString; QTcpSocket *tcpSocket; QLabel * results[6]; bool connectionEstablished; bool connectionError; public slots: private slots: void doAction(); void connectionClosedbyHost(); void readAnswer(); void setConnected(); void setError ( QAbstractSocket::SocketError ); signals: void unabletoConnect(); void answerAvailable(); void executeAction(); }; #endif linpsk-1.3.5/src/psk63demodulator.cpp000066400000000000000000000057641304636156700175500ustar00rootroot00000000000000/*************************************************************************** * * * 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 "psk63demodulator.h" #include "firfilter.h" PSk63Demodulator::PSk63Demodulator():CPskDemodulator() { ave1=1.0; ave2=1.0; } PSk63Demodulator::~PSk63Demodulator() { if( downFilter ) delete downFilter; if ( syncFilter ) delete syncFilter; } void PSk63Demodulator::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 PSk63Demodulator::GetBPSKSymb() { return (Phase_Vector.real()> 0.0); } void PSk63Demodulator::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; } 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; } void PSk63Demodulator::Init(double Fs ,int BlockSize) { SampleRate = Fs; //sample rate NxSamples = BlockSize; //size data input buffer downFilter = new FIRFilter(PI2*125./Fs,79,ComplexData,10.); syncFilter = new FIRFilter(PI2*62.5*9./Fs,79, ComplexData); downRate = 9; f1=31.25; f2=93.75; } double PSk63Demodulator::calcFreqError(complex s) { double x,y; complex z; if (abs(s) >1 ) z=s/abs(s); else z=s; x= z.real()*z.imag(); x /=2500.; // 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; } linpsk-1.3.5/src/psk63demodulator.h000066400000000000000000000022061304636156700172010ustar00rootroot00000000000000/*************************************************************************** * * * 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 PSK63DEMODULATOR_H #define PSK63DEMODULATOR_H #include #include "cpskdemodulator.h" /**Implementation of the BPSK Demodulator *@author Volker Schroer */ class PSk63Demodulator : public CPskDemodulator { public: PSk63Demodulator(); ~PSk63Demodulator(); void Init(double Fs ,int BlockSize); protected: /** Decodes a BPSK Symbol */ void DecodeSymbol( double); void CalcQuality(double); double calcFreqError(complex s); private: bool GetBPSKSymb(); double ave1; double ave2; }; #endif linpsk-1.3.5/src/psk63modulator.cpp000066400000000000000000000052451304636156700172310ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2012 -2017 by Volker Schroer, DL1KSV * * * * 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 "psk63modulator.h" #include "constants.h" #include "parameter.h" #include "ctxbuffer.h" extern Parameter settings; #define SYM_NOCHANGE 0 //Stay the same phase #define SYM_P180 2 //Plus 180 deg Psk63Modulator::Psk63Modulator(int FS, double frequency, CTxBuffer *TxBuffer):PskModulator(FS,frequency,TxBuffer) { symbolSize=(((100 * FS) / 6250) + 1); periodTime=1./62.5; period=periodTime; } char Psk63Modulator::getNextSymbolBit() { int bit; if(txShiftRegister != 0) { if(txShiftRegister &0x8000) bit=SYM_NOCHANGE; else bit=SYM_P180; txShiftRegister <<=1; if(txShiftRegister == 0) addEndingZero=true; } else { if(addEndingZero) { bit=SYM_P180; addEndingZero=false; } else { int ch; if((ch = getChar())>= 0) { // No controlcode txShiftRegister = VARICODE_TABLE[ ch&0xFF ]; bit=SYM_P180; //Start with a zero } else switch ( ch ) { case TXON_CODE: case TXTOG_CODE: //Idle bit = SYM_P180; break; case TXOFF_CODE: bit = SYM_NOCHANGE; break; } } } return bit; } linpsk-1.3.5/src/psk63modulator.h000066400000000000000000000031651304636156700166750ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2012 -2017 by Volker Schroer, DL1KSV * * * * 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 PSK63MODULATOR_H #define PSK63MODULATOR_H #include "pskmodulator.h" class Psk63Modulator : public PskModulator { public: Psk63Modulator(int FS, double frequency, CTxBuffer *TxBuffer); protected: char getNextSymbolBit(); }; #endif // BPSKMODULATOR_H linpsk-1.3.5/src/pskmodulator.cpp000066400000000000000000000241201304636156700170510ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2012 -2017 by Volker Schroer, DL1KSV * * * * 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 #include "pskmodulator.h" #include "constants.h" #include "parameter.h" #include "ctxbuffer.h" extern Parameter settings; extern unsigned short int VariCode_Table[]; #define SYM_NOCHANGE 0 //Stay the same phase #define SYM_P180 2 //Plus 180 deg PskModulator::PskModulator(int FS, double frequency, CTxBuffer *TxBuffer):CModulator(FS,TxBuffer) { transition[0][0]=ZZ; //old 0 new 0 transition[0][1]=ZN; //old 0 new 90 transition[0][2]=ZP; //old 0 new 180 transition[0][3]=ZZ7; //old 0 new 270 = -90 transition[1][0]=NN; //old 90 new 90 transition[1][1]=NP; //old 90 new 180 transition[1][2]=NZ7; //old 90 new 270 = -90 transition[1][3]=NZ; //old 90 new 0 transition[2][0]=PP; //old 180 new 180 transition[2][1]=PZ7; //old 180 new 270 = -90 transition[2][2]=PZ; //old 180 new 0 transition[2][3]=PN; //old 180 new = 90 transition[3][0]=Z7Z7;//old 270 = -90 new 270 = -90 transition[3][1]=Z7Z; //old 270 = -90 new 0 transition[3][2]=Z7N; //old 270 = -90 new 90 transition[3][3]=Z7P; //old 270 = -90 new 180 /** transition[0][1]=ZZ7; transition[0][3]=ZN; transition[1][0]=Z7Z7; transition[3][0]=NN;**/ status=TX_OFF_STATE; addEndingZero=false; amblePtr=0; pState=PZ; aktBit=2; aktFrequency=0.; txShiftRegister=0; txFrequencyInc=PI2 * frequency / SampleRate; //carrier frequency symbolSize=(((100 * FS) / 3125) + 1); periodTime=1./31.25; periodDelta=1./FS; period=periodTime; inSymbolPtr=0; } int PskModulator::CalcSignal(double *data, int BufferSize) { short int c; double x; std::complex temp; std::complex I=std::complex(0.,1.); #define amp 0.3 for(int i=0; i < BufferSize;i++) { if(period >=periodTime) { period -=periodTime; c=getNextSymbolBit(); inSymbolPtr=0; if(status == TX_END_STATE) { for(int j=i;j < BufferSize;j++) { temp=-amp*(cos(aktFrequency) + sin(aktFrequency)* I); data[j]=temp.real()+temp.imag(); aktFrequency += txFrequencyInc; aktFrequency=fmod(aktFrequency,PI2); } return -BufferSize; } pState=transition[aktBit][c]; switch(pState) { case ZZ: aktBit=0; break; case ZN: aktBit=1; break; case ZP: aktBit=2; break; case ZZ7: aktBit=3; break; case NN: aktBit=1; break; case NP: aktBit=2; break; case NZ7: aktBit=3; break; case NZ: aktBit=0; break; case PP: aktBit=2; break; case PZ7: aktBit=3; break; case PZ: aktBit=0; break; case PN: aktBit=1; break; case Z7Z7: aktBit=3; break; case Z7Z: aktBit=0; break; case Z7N: aktBit=1; break; case Z7P: aktBit=2; break; } } switch(pState) { case ZZ: temp=amp*(cos(aktFrequency) + sin(aktFrequency)*I); data[i]=temp.real() + temp.imag(); break; case ZN: x=cos((double) inSymbolPtr * M_PI / (double) symbolSize); temp=amp*(cos(aktFrequency)+x*sin(aktFrequency)*I); data[i]=temp.real() + temp.imag(); break; case ZP: x=cos((double) inSymbolPtr * M_PI / (double) symbolSize); temp=amp*(x*cos(aktFrequency) + x*sin(aktFrequency)*I); data[i]=temp.real() + temp.imag(); break; case ZZ7: x=cos((double) inSymbolPtr * M_PI / (double) symbolSize); temp=amp*(x*cos(aktFrequency) + sin(aktFrequency)*I); data[i]=temp.real() + temp.imag(); break; case NN: temp=amp*(cos(aktFrequency) - sin(aktFrequency)*I); data[i]=temp.real() + temp.imag(); break; case NZ: x=cos((double) inSymbolPtr * M_PI / (double) symbolSize); temp=amp*(cos(aktFrequency) -x * sin(aktFrequency)*I); data[i]=temp.real() + temp.imag(); break; case NP: x=cos((double) inSymbolPtr * M_PI / (double) symbolSize); temp=amp*(x*cos(aktFrequency) - sin(aktFrequency)*I); data[i]=temp.real() + temp.imag(); break; case NZ7: x=cos((double) inSymbolPtr * M_PI / (double) symbolSize); temp=amp*(x*cos(aktFrequency)-x*sin(aktFrequency)*I); data[i]=temp.real() + temp.imag(); break; case PP: temp=-amp*(cos(aktFrequency) + sin(aktFrequency)*I); data[i]=temp.real() + temp.imag(); break; case PZ7: x=cos((double) inSymbolPtr * M_PI / (double) symbolSize); temp=amp*(-cos(aktFrequency)-x*sin(aktFrequency)*I); data[i]=temp.real() + temp.imag(); break; case PZ: x=-cos((double) inSymbolPtr * M_PI / (double) symbolSize); temp=amp*(x*cos(aktFrequency) + x*sin(aktFrequency)*I); data[i]=temp.real() + temp.imag(); break; case PN: x=cos((double) inSymbolPtr * M_PI / (double) symbolSize); temp=amp*(-x*cos(aktFrequency) - sin(aktFrequency)*I); data[i]=temp.real() + temp.imag(); break; case Z7Z7: temp=amp*(-cos(aktFrequency) + sin(aktFrequency)*I); data[i]=temp.real() + temp.imag(); break; case Z7Z: x=cos((double) inSymbolPtr * M_PI / (double) symbolSize); temp=amp*(-x*cos(aktFrequency) + sin(aktFrequency)*I); data[i]=temp.real() + temp.imag(); break; case Z7N: x=cos((double) inSymbolPtr * M_PI / (double) symbolSize); temp=amp*(-x*cos(aktFrequency) + x*sin(aktFrequency)*I); data[i]=temp.real() + temp.imag(); break; case Z7P: x=cos((double) inSymbolPtr * M_PI / (double) symbolSize); temp=amp*(-cos(aktFrequency) + x*sin(aktFrequency)*I); data[i]=temp.real() + temp.imag(); break; } aktFrequency += txFrequencyInc; aktFrequency=fmod(aktFrequency,PI2); inSymbolPtr++; period +=periodDelta; } return BufferSize; } char PskModulator::getNextSymbolBit() { int bit; if(txShiftRegister != 0) { if(txShiftRegister &0x8000) bit=SYM_NOCHANGE; else bit=SYM_P180; txShiftRegister <<=1; if(txShiftRegister == 0) addEndingZero=true; } else { if(addEndingZero) { bit=SYM_P180; addEndingZero=false; } else { int ch; if((ch = getChar())>= 0) { // No controlcode txShiftRegister = VARICODE_TABLE[ ch&0xFF ]; bit=SYM_P180; //Start with a zero } else switch ( ch ) { case TXON_CODE: case TXTOG_CODE: //Idle bit = SYM_P180; break; case TXOFF_CODE: bit = SYM_NOCHANGE; break; } } } return bit; } int PskModulator::getChar() { int ch=0; switch(status) { case TX_OFF_STATE: status=TX_PREAMBLE_STATE; amblePtr++; ch=TXON_CODE; break; case TX_PREAMBLE_STATE: if(amblePtr++ < 33) ch=TXON_CODE; else { amblePtr=0; status=TX_SENDING_STATE; ch = TXTOG_CODE; } break; case TX_SENDING_STATE: ch=transmitBuffer->getTxChar(); if(ch > 0) emit charSend(ch); if(ch == TXOFF_CODE) { status=TX_POSTAMBLE_STATE; ch = TXTOG_CODE; //Necessary to print last character at receiver side amblePtr=0; } break; case TX_POSTAMBLE_STATE: ch=TXON_CODE; if(amblePtr++ >31) { status=TX_END_STATE; ch=TXOFF_CODE; } break; case TX_END_STATE: qDebug("TX_END_STATE should never be reached here!"); break; } return ch; } linpsk-1.3.5/src/pskmodulator.h000066400000000000000000000052621304636156700165240ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2012 -2017 by Volker Schroer, DL1KSV * * * * 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 PSKMODULATOR_H #define PSKMODULATOR_H #include "cmodulator.h" class PskModulator : public CModulator { public: PskModulator(int FS, double frequency, CTxBuffer *TxBuffer); int CalcSignal(double *data,int BufferSize); protected: virtual char getNextSymbolBit()=0; int getChar(); double aktFrequency; double txFrequencyInc; unsigned short txShiftRegister; int symbolSize; int inSymbolPtr; int amblePtr; short int aktBit; enum TxStatus { 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_PREAMBLE_STATE, //TX sending starting preamble TX_POSTAMBLE_STATE //TX sending ending posteamble // TX_TUNE_STATE //TX is tuning mode }; TxStatus status; enum PhaseState { // old , new ZZ, // 0 , 0 ZN, // 0 , 90 ZP, // 0 , 180 ZZ7, // 0 , 270 NN , // 90 , 90 NP , // 90 , 180 NZ7, // 90 , 270 NZ , // 90 , 0 PZ, // 180 , 0 PN, // 180 , 90 PP, // 180 , 180 PZ7, // 180 , 270 Z7Z, // 270 , 0 Z7N, // 270 , 90 Z7P, // 270 , 180 Z7Z7,// 270 , 270 }; PhaseState pState; PhaseState transition[4][4]; double periodTime; double periodDelta; double period; bool addEndingZero; }; #endif // BPSKMODULATOR_H linpsk-1.3.5/src/qpskdemodulator.cpp000066400000000000000000000064751304636156700175600ustar00rootroot00000000000000/*************************************************************************** * * * 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 "firfilter.h" #include "qpskdemodulator.h" #include "viterbi.h" // phase wraparound correction table for viterbi decoder 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 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() { if( downFilter ) delete downFilter; if ( syncFilter ) delete syncFilter; } 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; } } 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; 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.; } void QPskDemodulator::Init(double Fs ,int BlockSize) { SampleRate = Fs; //sample rate NxSamples = BlockSize; //size data input buffer downFilter = new FIRFilter(PI2*31.25/Fs,79,ComplexData,10.); syncFilter = new FIRFilter(PI2*31.25*18./Fs,79, ComplexData,5.); downRate = 18; } double QPskDemodulator::calcFreqError(complex s) { double x,y; complex z; if (abs(s) >1 ) z=s/abs(s); else z=s; x= z.real()*z.imag(); x /=5000.; // 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; } linpsk-1.3.5/src/qpskdemodulator.h000066400000000000000000000022371304636156700172150ustar00rootroot00000000000000 /*************************************************************************** * * * 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(); void Init(double Fs ,int BlockSize); protected: /** Decodes a QPSK Symbol */ //void DecodeSymbol( complex newsamp); void DecodeSymbol( double); double calcFreqError(complex s); void CalcQuality(double); private: double ave1,ave2; Viterbi *v; }; #endif linpsk-1.3.5/src/qpskmodulator.cpp000066400000000000000000000061551304636156700172420ustar00rootroot00000000000000 /*************************************************************************** * * * 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 0 //No change #define SYM_ON 2 //Change // 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::getNextSymbolBit(void) { char symb; int ch; symb = ConvolutionCodeTable[txShiftRegister&0x1F]; //get next convolution code // symb=(4-symb)%4; txShiftRegister = txShiftRegister<<1; if( m_TxCodeWord == 0 ) //need to get next codeword { if( addEndingZero ) //if need to add a zero { 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 ) { txShiftRegister |= 1; } m_TxCodeWord = m_TxCodeWord<<1; if(m_TxCodeWord == 0) addEndingZero = true; //need to add another zero } return symb; } linpsk-1.3.5/src/qpskmodulator.h000066400000000000000000000025201304636156700166770ustar00rootroot00000000000000/*************************************************************************** qpskmodulator.h - description ------------------- begin : Don Feb 27 2003 copyright : (C) 2003 by Volker Schroer email : dl1ksv@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 getNextSymbolBit(void); private: unsigned short int m_TxCodeWord; }; #endif linpsk-1.3.5/src/readonlystringlistmodel.cpp000066400000000000000000000033661304636156700213170ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2007 by volker, DL1KSV * * schroer@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; } linpsk-1.3.5/src/readonlystringlistmodel.h000066400000000000000000000036421304636156700207610ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2007 by volker, DL1KSV * * schroer@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 /** ReadOnlyStringListModel provides a readonly StringList model, so that views of this model cannot change the model's data @author volker, DL1KSV */ 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 linpsk-1.3.5/src/rigcontrol.cpp000066400000000000000000000065151304636156700165170ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2014 by Volker Schroer, DL1KSV * * * * 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 "rigcontrol.h" #include "parameter.h" #include extern Parameter settings; RigControl::RigControl() { frequency=0; pwr=0; connected=false; rig= NULL; } int RigControl::connectRig() { int rc; rc = -1; if( (settings.rigModelNumber == 0) || (settings.rigDevice == "None") ) return RIG_OK; rig=rig_init(settings.rigModelNumber); if(rig->caps->port_type != RIG_PORT_NONE) { if(rig->caps->port_type == RIG_PORT_SERIAL) { strcpy(rig->state.rigport.pathname,settings.rigDevice.toLatin1()); rig->state.rigport.parm.serial.rate=settings.baudrate; rig->state.rigport.parm.serial.handshake = (serial_handshake_e) settings.handshake; rig->state.rigport.retry=3; } if (rig) { rc=rig_open(rig); if(rc == RIG_OK ) connected=true; } } return rc; } int RigControl::get_frequency() { int rc; freq_t freq; if(connected) { rc = rig_get_freq(rig, RIG_VFO_CURR, &freq); if( rc == RIG_OK) frequency = (int) freq; } return frequency; } void RigControl::set_frequency(int f) { freq_t freq; if(connected) { freq=f; if(rig_set_freq(rig, RIG_VFO_CURR, freq) == RIG_OK) frequency=f; } } int RigControl::get_pwr() { value_t p; if(connected) { if(rig_get_level(rig,RIG_VFO_CURR,RIG_LEVEL_RFPOWER,&p)== RIG_OK ) pwr=p.f*100; } return pwr; } void RigControl::set_pwr(int p) { value_t pset; if( connected ) { pset.f = (float) p/100.; if( rig_set_level(rig,RIG_VFO_CURR,RIG_LEVEL_RFPOWER,pset)== RIG_OK) pwr=p; } } void RigControl::disconnectRig() { if ( (rig != NULL) && connected) { rig_close(rig); rig_cleanup(rig); } rig = NULL; connected=false; } bool RigControl::isConnected() { return connected; } QLatin1String RigControl::getModelName() { if(rig == NULL) return QLatin1String("None"); else return QLatin1String(rig->caps->model_name); } linpsk-1.3.5/src/rigcontrol.h000066400000000000000000000034101304636156700161530ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2014 by Volker Schroer, DL1KSV * * * * 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 RIGCONTROL_H #define RIGCONTROL_H #include class QLatin1String; class RigControl { public: RigControl(); int get_frequency(); void set_frequency(int f); int get_pwr(); void set_pwr(int p); int connectRig(); void disconnectRig(); bool isConnected(); QLatin1String getModelName(); private: RIG *rig; int frequency; int pwr; bool connected; }; #endif // RIGCONTROL_H linpsk-1.3.5/src/rttydemodulator.cpp000077500000000000000000000463011304636156700175770ustar00rootroot00000000000000/*************************************************************************** rttydemodulator.cpp - description ------------------- begin : Mon Jun 4 2001 copyright : (C) 2001 by Volker Schroer email : dl1ksv@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[FFTLENGTH]; pOutF0 = new complex[FFTLENGTH]; pOutF1 = new complex[FFTLENGTH]; pFilterF0 = new complex[FFTLENGTH]; pFilterF1 = new complex[FFTLENGTH]; pFilterIn = new complex[FFTLENGTH]; pResultF0 = new complex[FFTLENGTH]; pResultF1 = new complex[FFTLENGTH]; pOverlapF0 = new complex[FFTFILTERLENGTH-1]; pOverlapF1 = new complex[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 ( 0., 0. ); pOverlapF1[i] = complex ( 0., 0. ); } filteredSamples = 0; delayZ = complex ( 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; } void 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.; } void RTTYDemodulator::ProcessInput ( double *input, double * ) { char c1; int i, j, count; int StartBitCount, StartBitLength, StartBit2Lead; int StopBit2Count; int actSample; // int Filtered[RESULTLENGTH]; // complex 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 ( 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 ( 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 ( 0., PI2 * freq1 / SampleRate * ( i - ( FilterLength - 1 ) / 2 ) ) ); for ( i = FilterLength;i < FFTLENGTH;i++ ) pFilterIn[i] = complex ( 0., 0. ); fftw_execute ( pfilter ); memcpy ( pFilterF1, pFilterF0, FFTLENGTH*sizeof ( complex ) ); for ( i = 0;i < FFTLENGTH;i++ ) pFilterIn[i] = coeffs[i] * exp ( complex ( 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 * z0, complex *z1, int anzahl, int *y, double *omegaF0, double *omegaF1 ) { int i, j, k; complex 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 ( 0., -F0inc ) ) / norm ) ; // zz1 = ( z1[j] * exp ( complex ( 0., -F1inc ) ) / norm ) ; z0[j] *= exp ( complex ( 0., -F0inc )); zz0 = z0[j]/ norm ; sumf0 += zz0; z1[j] *= exp ( complex ( 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 ); } } linpsk-1.3.5/src/rttydemodulator.h000077500000000000000000000072471304636156700172520ustar00rootroot00000000000000/*************************************************************************** rtty2demodulator.h - description ------------------- begin : Mon Jun 4 2001 copyright : (C) 2001 by Volker Schroer email : dl1ksv@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 #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(); void 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 *,complex *, 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 *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 delayZ; }; #endif linpsk-1.3.5/src/rttymodulator.cpp000066400000000000000000000300551304636156700172620ustar00rootroot00000000000000/*************************************************************************** rttymodulator.cpp - description ------------------- begin : Tue Aug 21 2001 copyright : (C) 2001 by Volker Schroer email : dl1ksv@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= 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; } bit = 1; 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 backspace 8 0x00, // HT undefined 9 0x02, // LF 10 0x00, // VT undefined 11 0x00, // FF undefined 12 0x08, // CR 13 0x00, // SO undefined 14 0x00, // SI undefinde 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 = transmitBuffer->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); } linpsk-1.3.5/src/rttymodulator.h000066400000000000000000000041741304636156700167320ustar00rootroot00000000000000/*************************************************************************** rttymodulator.h - description ------------------- begin : Tue Aug 21 2001 copyright : (C) 2001 by Volker Schroer email : dl1ksv@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 linpsk-1.3.5/src/spectrumwindow.cpp000066400000000000000000000125101304636156700174170ustar00rootroot00000000000000/*************************************************************************** spectrumwindow.cpp - description ------------------- begin : Sat Aug 25 2012 copyright : (C) 2012 by Volker Schroer email : DL1KSV@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 "spectrumwindow.h" #include "parameter.h" #include #include #include #include "crxchannel.h" #include extern Parameter settings; SpectrumWindow::SpectrumWindow(QWidget *parent) : QFrame(parent) { int x=2*frameWidth(); pdisplay=new QPixmap (width()-x,height()-x); pdisplay->fill(); Farbe=0; } void SpectrumWindow::setDisplayRange(int minfreq, int maxfreq) { minDisplayfrequency=minfreq; maxDisplayfrequency=maxfreq; } void SpectrumWindow::resizeEvent(QResizeEvent *) { int x=2*frameWidth(); if(pdisplay != 0) delete pdisplay; pdisplay =new QPixmap (this->width()-x,this->height()-x); pdisplay->fill(); QPainter p(pdisplay); paintLineal(&p,pdisplay->width(),pdisplay->height(),minDisplayfrequency,maxDisplayfrequency); p.end(); } void SpectrumWindow::paintLineal ( QPainter* p, int xmax, int ymax,int minfreq,int maxfreq ) { int stepfrequency; float stepwidth; int i, ix, NumberofFreqs, diff; int y; QString frequency; QFontMetrics fm ( this->font() ); // Calcalute Frequency- Steps diff = ( maxfreq - minfreq ); NumberofFreqs = 7; while ( NumberofFreqs > 4 ) { stepfrequency = diff / NumberofFreqs; if ( (stepfrequency * NumberofFreqs) != diff ) NumberofFreqs--; else break; } stepwidth = float ( xmax ) / NumberofFreqs; diff = ymax / 10; if( diff < 12) diff = 12; y = ymax -3* diff/2; y=(y/diff)*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, y+diff+diff/2, frequency ); } // Plot Grid for ( i = diff;i <=y; i +=diff ) { p->drawLine ( 0, i, xmax, i ); } baseline=y; } void SpectrumWindow::plotSpectrum(bool overload,float *fftdata,int minfreq,int maxfreq) { float scale; int y1,y2,z; int ymax = pdisplay->height(); int xmax = pdisplay-> width(); // scale = ymax / 100.; scale=baseline/8.03; pdisplay->fill(); QPainter p(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 two lines { z=(( z-minfreq)*xmax)/(maxfreq-minfreq); p.drawLine(z,0,z,ymax); } } if ( overload ) p.setPen ( Qt::red ); else p.setPen ( Qt::black ); for ( int i = 1;i < xmax;i++ ) { y1 = baseline - ( int ) ( scale * fftdata[i-1] ); y2 = baseline - ( int ) ( scale * fftdata[i] ); p.drawLine ( i - 1, y1, i, y2 ); } p.setPen ( Qt::black ); paintLineal ( &p, xmax, ymax,minfreq,maxfreq ); if ( Phase != 0 ) plotVector ( &p ); p.end(); update(); } void SpectrumWindow::paintEvent(QPaintEvent *e) { int x=frameWidth(); QFrame::paintEvent(e); QPainter p(this); p.drawPixmap(x,x,pdisplay->copy(0,0,pdisplay->width(),pdisplay->height())); p.end(); } void SpectrumWindow::setColorList ( QList *c ) { Farbe=c; } void SpectrumWindow::setPhasePointer ( std::complex *p ) { Phase = p; } void SpectrumWindow::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< PHASE_DISPLAY_BUFFER_LENGTH; 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 SpectrumWindow::mousePressEvent ( QMouseEvent *e ) { emit frequencyChanged ( e->x() - lineWidth() ); } void SpectrumWindow::wheelEvent ( QWheelEvent * e ) { double freq=settings.ActChannel->getRxFrequency(); if(e->delta() >0 ) freq =freq+1; else freq = freq -1; emit frequencyChanged(freq); settings.ActChannel->setRxFrequency(freq); e->accept(); } linpsk-1.3.5/src/spectrumwindow.h000066400000000000000000000037261304636156700170750ustar00rootroot00000000000000/*************************************************************************** spectrumwindow.h - description ------------------- begin : Sat Aug 25 2012 copyright : (C) 2012 by Volker Schroer email : DL1KSV@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 SPECTRUMWINDOW_H #define SPECTRUMWINDOW_H #include #include #include #include class QPixmap; class SpectrumWindow : public QFrame { Q_OBJECT public: explicit SpectrumWindow(QWidget *parent = 0); void plotSpectrum(bool overload, float *fftdata, int minfreq, int maxfreq); void setDisplayRange(int minfreq, int maxfreq); void setColorList(QList *c); void mousePressEvent ( QMouseEvent *e ); void setPhasePointer(std::complex *); private: void paintLineal(QPainter* ,int,int,int,int); void plotVector ( QPainter *p ); QPixmap *pdisplay; // Display for double buffering int baseline; // Y Position of X- Axis in window std::complex *Phase; int minDisplayfrequency; int maxDisplayfrequency; protected: void resizeEvent( QResizeEvent * ); void paintEvent(QPaintEvent *); void wheelEvent ( QWheelEvent * e ); QList *Farbe; signals: void frequencyChanged(int); void frequencyChanged(double); public slots: }; #endif // SPECTRUMWINDOW_H linpsk-1.3.5/src/tabwidget.cpp000066400000000000000000000003331304636156700162770ustar00rootroot00000000000000#include "tabwidget.h" #include TabWidget::TabWidget(QWidget *parent) : QTabWidget(parent) { } void TabWidget::setTabTextColor(int index, const QColor &color) { tabBar()->setTabTextColor(index, color); } linpsk-1.3.5/src/tabwidget.h000066400000000000000000000004261304636156700157470ustar00rootroot00000000000000#ifndef TABWIDGET_H #define TABWIDGET_H #include class TabWidget : public QTabWidget { Q_OBJECT public: explicit TabWidget(QWidget *parent = 0); void setTabTextColor(int index, const QColor &color); signals: public slots: }; #endif // TABWIDGET_H linpsk-1.3.5/src/textinput.cpp000066400000000000000000000060571304636156700164020ustar00rootroot00000000000000/*************************************************************************** textinput.cpp - description ------------------- begin : Sat May 5 2001 copyright : (C) 2001 by Volker Schroer email : DL1KSV@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 #include #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.toLatin1(), 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.toLatin1(), 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; } linpsk-1.3.5/src/textinput.h000066400000000000000000000035531304636156700160450ustar00rootroot00000000000000/*************************************************************************** textinput.h - description ------------------- begin : Sat May 5 2001 copyright : (C) 2001 by Volker Schroer email : DL1KSV@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 #include /**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 linpsk-1.3.5/src/viterbi.cpp000066400000000000000000000062311304636156700157740ustar00rootroot00000000000000/*************************************************************************** viterbi.cpp - description ------------------- begin : Sam Maerz 8 2003 copyright : (C) 2003 by Volker Schroer email : dl1ksv@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 using namespace std; Viterbi::Viterbi(int K, unsigned int PolyA, unsigned int PolyB,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 > i ) & 1; } int Viterbi::getbitinvers(unsigned int i) { return (~( PathMem[MinimumPath] >> i )) & 1; } linpsk-1.3.5/src/viterbi.h000066400000000000000000000031501304636156700154360ustar00rootroot00000000000000/*************************************************************************** viterbi.h - description ------------------- begin : Sam Maerz 8 2003 copyright : (C) 2003 by Volker Schroer email : dl1ksv@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,unsigned int,unsigned int,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); double (*dist)(double *,int); }; #endif linpsk-1.3.5/src/waterfallwindow.cpp000066400000000000000000000051021304636156700175350ustar00rootroot00000000000000/*************************************************************************** waterfallwindow.h - description ------------------- begin : Sat Aug 26 2012 copyright : (C) 2012 by Volker Schroer email : DL1KSV@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 #include #include #include "waterfallwindow.h" #include "color.h" #include "parameter.h" #include "crxchannel.h" extern Parameter settings; WaterfallWindow::WaterfallWindow(QWidget *parent) : QFrame(parent) { int x=2*frameWidth(); pwaterfall=new QPixmap (width()-x,height()-x); pwaterfall->fill(Qt::black); } void WaterfallWindow::plotWaterfall(float *fftdata) { int xmax = pwaterfall->width(); int y1; QPainter p(pwaterfall); p.drawPixmap(0,2,pwaterfall->copy(0,0,pwaterfall->width(),pwaterfall->height()-2)); for (int i=0;i 255) { // qDebug("y1: %i, fft: %f",y1,fftdata[i]); y1 = 255; } else if ( y1 < 0 ) y1= 0; p.setPen(color[y1]); p.drawPoint(i,0); p.drawPoint(i,1); } p.end(); update(); } void WaterfallWindow::paintEvent(QPaintEvent *e) { int x=frameWidth(); QFrame::paintEvent(e); QPainter p(this); p.drawPixmap(x,x,pwaterfall->copy(0,0,pwaterfall->width(),pwaterfall->height())); p.end(); } void WaterfallWindow::resizeEvent(QResizeEvent *) { int x=2*frameWidth(); if(pwaterfall != 0) delete pwaterfall; pwaterfall =new QPixmap (this->width()-x,this->height()-x); pwaterfall->fill(Qt::black); } void WaterfallWindow::mousePressEvent ( QMouseEvent *e ) { emit frequencyChanged ( e->x() - lineWidth() ); } void WaterfallWindow::wheelEvent ( QWheelEvent * e ) { double freq=settings.ActChannel->getRxFrequency(); if(e->delta() >0 ) freq =freq+1; else freq = freq -1; emit frequencyChanged(freq); settings.ActChannel->setRxFrequency(freq); e->accept(); } linpsk-1.3.5/src/waterfallwindow.h000066400000000000000000000027311304636156700172070ustar00rootroot00000000000000/*************************************************************************** waterfallwindow.h - description ------------------- begin : Sat Aug 26 2012 copyright : (C) 2012 by Volker Schroer email : DL1KSV@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 WATERFALLWINDOW_H #define WATERFALLWINDOW_H #include class QPixmap; class WaterfallWindow : public QFrame { Q_OBJECT public: explicit WaterfallWindow(QWidget *parent = 0); void plotWaterfall(float *fftdata); void mousePressEvent ( QMouseEvent *e ); protected: void resizeEvent( QResizeEvent * ); void paintEvent(QPaintEvent *); void wheelEvent ( QWheelEvent * e ); private: QPixmap *pwaterfall; signals: void frequencyChanged(double); void frequencyChanged(int); public slots: }; #endif // WATERFALLWINDOW_H linpsk-1.3.5/src/waveinput.cpp000066400000000000000000000152661304636156700163620ustar00rootroot00000000000000/*************************************************************************** waveinput.cpp - description ------------------- begin : Sat May 5 2001 copyright : (C) 2001 by Volker Schroer email : DL1KSV@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[4]; 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.toLatin1(),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[4]=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[4]=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= Length ) { lseek(fd,offset,SEEK_SET); Bytesread=0; } } // End while return j; } bool WaveInput::close_Device() { return true; } /** void WaveInput::samplesAvailable() { emit Input::samplesAvailable(); } **/ linpsk-1.3.5/src/waveinput.h000066400000000000000000000040201304636156700160110ustar00rootroot00000000000000/*************************************************************************** waveinput.h - description ------------------- begin : Sat May 5 2001 copyright : (C) 2001 by Volker Schroer email : DL1KSV@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 /**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 linpsk-1.3.5/templates/000077500000000000000000000000001304636156700150315ustar00rootroot00000000000000linpsk-1.3.5/templates/cpp000066400000000000000000000025431304636156700155420ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2007 by volker, DL1KSV * * schroer@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. * ***************************************************************************/ linpsk-1.3.5/templates/h000066400000000000000000000025431304636156700152070ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2007 by volker, DL1KSV * * schroer@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. * ***************************************************************************/