linpsk/0000755000175000017500000000000011337745306012263 5ustar schroerschroerlinpsk/gui/0000755000175000017500000000000011337745305013046 5ustar schroerschroerlinpsk/gui/addmacro.cpp0000644000175000017500000000645511337745305015336 0ustar schroerschroer/*************************************************************************** * 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 "addmacro.h" #include "readonlystringlistmodel.h" #include AddMacro::AddMacro(Macros *k,QWidget* parent, Qt::WFlags fl) : QDialog( parent, fl ), Ui::AddMacro() { setupUi(this); ReadOnlyStringListModel *model= new ReadOnlyStringListModel(); model->setStringList(k->getKeyWordList()); KeywordDisplay->setModel(model); connect(KeywordDisplay,SIGNAL(clicked(const QModelIndex &)),this,SLOT(insertKeyword(const QModelIndex &))); model= new ReadOnlyStringListModel(); model->setStringList(k->getMacroList()); MacroDisplay->setModel(model); Position->setMaximum(k->getMacroList().size()+1); Position->setValue(k->getMacroList().size()+1); } AddMacro::~AddMacro() { } void AddMacro::accept() { if (MacroName->text().length()== 0) { QMessageBox::warning(this,"Incomplete Macro Definition","Name of Macro is missing \n Enter Name of Macro", QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton); return; } if (MacroDefinition->toPlainText().length()== 0) { QMessageBox::warning(this,"Incomplete Macro Definition","Macrodefinition is missing \n Enter Macrodefinition", QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton); return; } int anzahl=MacroDefinition->toPlainText().count(QLatin1Char('@')); if (( anzahl > 0) && ((anzahl/2)*2 != anzahl) ) { QMessageBox::warning(this,"Error in Macro Definition","Error in Macrodefinition. Incorrect number of @ \n Enter Macrodefinition", QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton); return; } QDialog::accept(); } void AddMacro::insertKeyword(const QModelIndex &index) { QString s=index.data().toString(); MacroDefinition->insertPlainText(s); MacroDefinition->setFocus(); } QString AddMacro::macroName() { return MacroName->text(); } QString AddMacro::macroDefinition() { return MacroDefinition->toPlainText(); } int AddMacro::position() { return Position->value(); } QString AddMacro::accelerator() { return Accelerator->text(); } linpsk/gui/qsodata.cpp0000644000175000017500000003217411337745305015215 0ustar schroerschroer/*************************************************************************** * 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 #include #include #include #include #include #include extern Parameter settings; QSOData::QSOData ( QWidget* parent ) : QGroupBox ( parent ), Ui::QSOData() { setupUi ( this ); QRegExp rx ( "^[A-R][A-R][0-9][0-9][A-X][A-X]$" ); validator = new QRegExpValidator ( rx, this ); Loc->setValidator ( validator ); Loc->setStyleSheet ( "QLineEdit{color: black ; }" ); Distance->setAlignment ( Qt::AlignRight ); QsoDate->setDisplayFormat ( settings.dateFormat ); refreshDateTime(); if ( settings.QslData ) { RemoteCallsign->setText ( settings.QslData->RemoteCallsign ); OpName->setText ( settings.QslData->OpName ); Qth->setText ( settings.QslData->Qth ); Loc->setText ( settings.QslData->Locator ); QsoFrequency->setText ( settings.QslData->QsoFrequency ); HisRST->setText ( settings.QslData->HisRST ); MyRST->setText ( settings.QslData->MyRST ); } if ( ! ( settings.fileLog || settings.LinLog ) ) Save->setDisabled ( true ); logBookCommunication = new ProcessLogData(); connectionError = false; connect ( Clear, SIGNAL ( clicked() ), this, SLOT ( clear() ) ); connect ( Refresh, SIGNAL ( clicked() ), this, SLOT ( refreshDateTime() ) ); connect ( Qth, SIGNAL ( editingFinished () ), this, SLOT ( QTHchanged() ) ); connect ( QsoFrequency, SIGNAL ( editingFinished () ), this, SLOT ( Frequencychanged() ) ); connect ( MyRST, SIGNAL ( editingFinished () ), this, SLOT ( MyRSTchanged() ) ); connect ( OpName, SIGNAL ( editingFinished () ), this, SLOT ( Namechanged() ) ); connect ( Save, SIGNAL ( clicked() ), this, SLOT ( save() ) ); connect ( Loc, SIGNAL ( editingFinished () ), this, SLOT ( Locatorchanged() ) ); connect ( HisRST, SIGNAL ( editingFinished () ), this, SLOT ( HisRSTchanged() ) ); connect ( QsoDate, SIGNAL ( dateChanged ( const QDate & ) ), this, SLOT ( Datechanged() ) ); connect ( QsoTime, SIGNAL ( timeChanged ( const QTime & ) ), this, SLOT ( Timechanged() ) ); connect ( RemoteCallsign, SIGNAL ( editingFinished ( ) ), this, SLOT ( sendRequest() ) ); connect ( logBookCommunication, SIGNAL ( unabletoConnect() ), this , SLOT ( stopTrial() ) ); connect ( logBookCommunication, SIGNAL ( answerAvailable() ), this, SLOT ( copyAnswer() ) ); } QSOData::~QSOData() {} void QSOData::clear() { RemoteCallsign->setText ( "" ); settings.QslData->RemoteCallsign = RemoteCallsign->text(); OpName->setText ( "" ); settings.QslData->OpName = OpName->text(); Qth->setText ( "" ); settings.QslData->Qth = Qth->text(); Loc->setText ( "" ); settings.QslData->Locator = Loc->text(); QsoFrequency->setText ( "" ); settings.QslData->Locator = Loc->text(); HisRST->setText ( "" ); settings.QslData->HisRST = HisRST->text(); MyRST->setText ( "" ); settings.QslData->MyRST = MyRST->text(); Distance->setText ( "" ); continent->setText ( "" ); settings.QslData->continent = continent->text(); wazZone->setText ( "" ); settings.QslData->wazZone = wazZone->text(); ituZone->setText ( "" ); settings.QslData->ituZone = ituZone->text(); countryName->setText ( "" ); settings.QslData->countryName = countryName->text(); worked->setText ( "" ); settings.QslData->worked = worked->text(); mainPrefix->setText ( "" ); settings.QslData->mainPrefix = mainPrefix->text(); refreshDateTime(); } void QSOData::Callsignchanged() { settings.QslData->RemoteCallsign = RemoteCallsign->text(); RemoteCallsign->setModified ( true ); sendRequest(); } void QSOData::Namechanged() { settings.QslData->OpName = OpName->text(); } void QSOData::QTHchanged() { settings.QslData->Qth = Qth->text(); } void QSOData::Locatorchanged() { int i=0; QString toCheck= Loc->text(); QValidator::State status=validator->validate(toCheck,i); if(status==QValidator::Invalid) Loc->setStyleSheet ( "QLineEdit{color: red ; }" ); else { Loc->setStyleSheet ( "QLineEdit{color: black ; }" ); settings.QslData->Locator = toCheck; calculateDistance ( toCheck ); } } void QSOData::Frequencychanged() { settings.QslData->QsoFrequency = QsoFrequency->text(); } void QSOData::HisRSTchanged() { settings.QslData->HisRST = HisRST->text(); } void QSOData::MyRSTchanged() { settings.QslData->MyRST = MyRST->text(); } void QSOData::Datechanged() { settings.QslData->QsoDate = QsoDate->date(); } void QSOData::Timechanged() { settings.QslData->QsoTime = QsoTime->time(); } void QSOData::refreshDateTime() { QDateTime t1; QDateTime t; t = QDateTime::currentDateTime(); t1 = t.addSecs ( settings.timeoffset * 3600 ); QsoDate->setDate ( t.date() ); QsoTime->setTime ( t1.time() ); if ( settings.QslData ) { settings.QslData->QsoTime = QsoTime->time(); settings.QslData->QsoDate = QsoDate->date(); } } void QSOData::save() { if ( ( ( settings.QSOFileName == "" ) && ( !settings.LinLog ) ) || connectionError ) return ; // No Filename specified, and no LinLog logging required // Get the most recent values settings.QslData->RemoteCallsign = RemoteCallsign->text(); Namechanged(); // Later ?, not saved at the moment QTHchanged(); Locatorchanged(); Frequencychanged(); HisRSTchanged(); MyRSTchanged(); Datechanged(); Timechanged(); QString saveString, s; if ( RemoteCallsign->text().length() > 0 ) saveString = QString ( "%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->text() != "" ) { s = QString ( "%2\n" ).arg ( QsoFrequency->text().length() ).arg ( QsoFrequency->text() ); 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() != "" ) { s = QString ( "%2\n" ).arg ( QsoTime->text().length() ).arg ( QsoTime->text().remove ( ':' ) ); 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: case BPSK: s.append ( "5>PSK31\n" ); break; case RTTY: s.append ( "4>RTTY\n" ); break; case MFSK16: s.append ( "6>MFSK16\n" ); break; default: s.append ( "5>PSK31\n" ); } saveString.append ( s ); } saveString.append ( "\n" ); if ( settings.fileLog ) { QDir d; if ( !d.cd ( settings.Directory ) ) d.mkdir ( settings.Directory ); QFile f ( settings.Directory + "/" + settings.QSOFileName ); if ( !f.open ( QIODevice::WriteOnly | QIODevice::Append ) ) { QMessageBox::information ( 0, "Saving to adif File", "Could not open file " + settings.QSOFileName ); return; } QTextStream stream ( &f ); stream << saveString ; f.close(); } if ( settings.LinLog ) { if ( !logBookCommunication->isRunning() ) logBookCommunication->start(); qDebug ( "Written to Logbook\n%s", qPrintable ( saveString ) ); logBookCommunication->saveQsoData ( saveString ); } } void QSOData::calculateDistance ( QString loc ) { coordinates mine, his; double dist; if ( settings.myLocator.isEmpty() ) { Distance->setText ( "" ); return; } if ( loc.length() != 6 ) return; QString s ( "%1 km" ); mine = loc2coordinates ( settings.myLocator.constData() ); his = loc2coordinates ( loc.constData() ); dist = 6371. * acos ( sin ( mine.breite ) * sin ( his.breite ) + cos ( mine.breite ) * cos ( his.breite ) * cos ( mine.laenge - his.laenge ) ); Distance->setText ( s.arg ( ( int ) dist, 6 ) ); } QSOData::coordinates QSOData::loc2coordinates ( const QChar *l ) { coordinates c; c.laenge = ( 20. * ( l[0].toAscii() - 'A' ) + 2. * ( l[2].toAscii() - '0' ) + ( 1. / 12. ) * ( l[4].toAscii() - 'A' ) + 1. / 24. ); c.laenge *= M_PI / 180.; c.breite = 90. - ( 10. * ( l[1].toAscii() - 'A' ) + 1. * ( l[3].toAscii() - '0' ) + ( 1. / 24. ) * ( l[5].toAscii() - 'A' ) + 1. / 48. ); c.breite *= M_PI / 180.; return c; } void QSOData::copyCallSign ( QString s ) { RemoteCallsign->setText ( s ); Callsignchanged(); } void QSOData::copyQTH ( QString s ) { Qth->setText ( s ); QTHchanged(); } void QSOData::copyName ( QString s ) { OpName->setText ( s ); Namechanged(); } void QSOData::copyLocator ( QString s ) { Loc->setText ( s.left(6).toUpper()); Locatorchanged(); } void QSOData::copyRST ( QString s ) { HisRST->setText ( s ); HisRSTchanged(); } void QSOData::newChannel() { Distance->setText ( "" ); if ( settings.QslData ) { RemoteCallsign->setText ( settings.QslData->RemoteCallsign ); OpName->setText ( settings.QslData->OpName ); Qth->setText ( settings.QslData->Qth ); Loc->setText ( settings.QslData->Locator ); Locatorchanged(); // Check Locator and set Color QsoFrequency->setText ( settings.QslData->QsoFrequency ); HisRST->setText ( settings.QslData->HisRST ); MyRST->setText ( settings.QslData->MyRST ); QsoDate->setDate ( settings.QslData->QsoDate ); QsoTime->setTime ( settings.QslData->QsoTime ); mainPrefix->setText ( settings.QslData->mainPrefix ); continent->setText ( settings.QslData->continent ); wazZone->setText ( settings.QslData->wazZone ); ituZone->setText ( settings.QslData->ituZone ); countryName->setText ( settings.QslData->countryName ); worked->setText ( settings.QslData->worked ); } else clear(); } void QSOData::sendRequest() { bool test; test = RemoteCallsign->isModified(); if ( test ) { RemoteCallsign->setModified ( false ); //To avoid calling twice settings.QslData->RemoteCallsign = RemoteCallsign->text(); } if ( !settings.LinLog || connectionError || !test ) // No request to LinLogbook if disabled in the settings return; qDebug ( "Trying to request %s", qPrintable ( RemoteCallsign->text().toUpper() ) ); QLabel *results[6]; results[0] = mainPrefix; results[1] = wazZone; results[2] = ituZone; results[3] = countryName; results[4] = continent; results[5] = worked; if ( !logBookCommunication->isRunning() ) { logBookCommunication->start(); // qApp->processEvents ( QEventLoop::AllEvents, 100 ); } logBookCommunication->requestCallSign ( results, RemoteCallsign->text().toUpper() ); qDebug ( "Request send" ); } void QSOData::stopTrial() { connectionError = true; } void QSOData::copyAnswer() { settings.QslData->mainPrefix = mainPrefix->text(); settings.QslData->wazZone = wazZone->text(); settings.QslData->ituZone = ituZone->text(); settings.QslData->countryName = countryName->text(); settings.QslData->continent = continent->text(); settings.QslData->worked = worked->text(); } linpsk/gui/modemenu.ui0000644000175000017500000001716611337745305015231 0ustar schroerschroer 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/gui/generalsettings.cpp0000644000175000017500000001352711337745305016760 0ustar schroerschroer/*************************************************************************** * 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 extern Parameter settings; GeneralSettings::GeneralSettings ( QWidget* parent, Qt::WFlags fl ) : QDialog ( parent, fl ), Ui::GeneralSettings() { setupUi ( this ); QString DirectoryName; QDir dir; LocalSettings = settings; FileFormat = new QButtonGroup ( FileFormatLayout ); FileFormat->setExclusive ( true ); FileFormat->addButton ( Wav, 0 ); FileFormat->addButton ( Text, 1 ); if ( LocalSettings.DemoTypeNumber == 0 ) Wav->setChecked ( true ); else Text->setChecked ( true ); Callsign->setText ( LocalSettings.callsign ); myLocator->setText ( LocalSettings.myLocator ); UTC->setValue ( LocalSettings.timeoffset ); SlashedZero->setAutoExclusive(false); SlashedZero->setChecked ( LocalSettings.slashed0 ); autoCrLf->setAutoExclusive(false); autoCrLf->setChecked(LocalSettings.autoCrLf); QRegExp rx ( "^[A-R][A-R][0-9][0-9][A-X][A-X]$" ); QValidator *validator = new QRegExpValidator ( rx, this ); myLocator->setValidator ( validator ); myLocator->setText ( LocalSettings.myLocator ); Demomode->setChecked ( LocalSettings.DemoMode ); connect ( Demomode, SIGNAL ( clicked ( bool ) ), this, SLOT ( selectDemomode ( bool ) ) ); connect ( AvailableDevices, SIGNAL ( clicked ( const QModelIndex & ) ), this, SLOT ( setPTTDevice ( const QModelIndex & ) ) ); if ( Demomode->isChecked() ) FileFormatLayout->show(); else FileFormatLayout->hide(); //PTT SelectedDevice->setText ( LocalSettings.SerialDevice ); // First look in the /dev Directory DirectoryName = "/dev/"; dir.setPath ( DirectoryName ); QStringList filenames; filenames << "ttyS*"; QStringList Files = dir.entryList ( filenames, QDir::System | QDir::CaseSensitive, QDir::Name ); for ( int kk = 0; kk < Files.size(); kk++ ) Files.replace ( kk, DirectoryName + Files.at ( kk ) ); ReadOnlyStringListModel *m = new ReadOnlyStringListModel ( this ); m->setStringList ( Files ); AvailableDevices->setModel ( m ); AvailableDevices->show(); // Now check for usb devices /** Directory="/dev/usb/tts/"; dir.setPath(Directory); Files=dir.entryList(QDir::Files|QDir::System,QDir::Name); for(QStringList::iterator Name=Files.begin();Name !=Files.end(); Name++) AvailableDevices->insertItem(Directory + *Name); **/ //Logging Directory->setText ( LocalSettings.Directory ); QsoFile->setText ( LocalSettings.QSOFileName ); fileLog->setChecked ( LocalSettings.fileLog ); connect(fileLog,SIGNAL(clicked(bool)),this,SLOT(selectFileLogging(bool))); Directory->setDisabled ( !LocalSettings.fileLog ); QsoFile->setDisabled ( !LocalSettings.fileLog ); LinLog->setChecked ( LocalSettings.LinLog ); connect(LinLog,SIGNAL(clicked(bool)),this,SLOT(selectLinLogLogging(bool))); Port->setDisabled ( !LocalSettings.LinLog ); Host->setDisabled ( !LocalSettings.LinLog ); } GeneralSettings::~GeneralSettings() {} /*$SPECIALIZATION$*/ Parameter GeneralSettings::getSettings() { LocalSettings.callsign = Callsign->text(); LocalSettings.myLocator = myLocator->text(); if ( Demomode->isChecked() ) { LocalSettings.DemoMode = true; LocalSettings.DemoTypeNumber = FileFormat->checkedId(); LocalSettings.inputFilename = ""; } else LocalSettings.DemoMode = false; LocalSettings.timeoffset = UTC->value(); if ( SlashedZero->isChecked() ) LocalSettings.slashed0 = true; else LocalSettings.slashed0 = false; if ( autoCrLf->isChecked() ) LocalSettings.autoCrLf = true; else LocalSettings.autoCrLf = false; LocalSettings.SerialDevice = SelectedDevice->text(); LocalSettings.fileLog = fileLog->isChecked(); if ( LocalSettings.fileLog ) { LocalSettings.Directory = Directory->text(); LocalSettings.QSOFileName = QsoFile->text(); } LocalSettings.LinLog = LinLog->isChecked(); if ( LocalSettings.LinLog ) { LocalSettings.Host = Host->text(); LocalSettings.Port = Port->value(); } LocalSettings.dateFormat=dateFormat->currentText(); return LocalSettings; } void GeneralSettings::selectDemomode ( bool mode ) { if ( mode ) FileFormatLayout->show(); else FileFormatLayout->hide(); } void GeneralSettings::setPTTDevice ( const QModelIndex &index ) { QString s = index.data().toString(); SelectedDevice->clear(); SelectedDevice->setText ( s ); LocalSettings.SerialDevice = s; } void GeneralSettings::selectFileLogging ( bool b) { Directory->setDisabled ( !b); QsoFile->setDisabled ( !b ); } void GeneralSettings::selectLinLogLogging ( bool b ) { Port->setDisabled ( !b ); Host->setDisabled ( !b ); } linpsk/gui/renamemacro.ui0000644000175000017500000001235511337745305015704 0ustar schroerschroer 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/gui/.directory0000644000175000017500000000006311337745305015052 0ustar schroerschroer[Dolphin] Timestamp=2009,11,14,11,57,46 ViewMode=1 linpsk/gui/generalsettings.ui0000644000175000017500000003165211337745305016612 0ustar schroerschroer GeneralSettings 0 0 650 392 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 115 20 Display Zero as Slashed Zero false Qt::Horizontal 115 20 true Send CR LF on enter Qt::Horizontal 129 20 Qt::Horizontal 283 20 QFrame::StyledPanel QFrame::Raised Demomode Fileformat Wav false Text false PTT Device 10 20 131 94 10 120 131 21 Logging Log to File true false Working Directory Filename QSO.adif 0 Log to LinLog false LinLog Host Name localhost Port 1024 64000 8080 80 20 Qt::ClickFocus &Ok Alt+O false false 80 20 Qt::ClickFocus &Cancel false false false Qt::Horizontal 115 20 qPixmapFromMimeSource Callsign Demomode Text buttonOk buttonCancel parameter.h buttonOk clicked() GeneralSettings accept() 20 20 20 20 buttonCancel clicked() GeneralSettings reject() 20 20 20 20 linpsk/gui/renamemacro.h0000644000175000017500000000364011337745305015513 0ustar schroerschroer/*************************************************************************** * 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 RENAMEMACRO_H #define RENAMEMACRO_H #include #include "ui_renamemacro.h" class Macros; class ReadOnlyStringListModel; class RenameMacro : public QDialog, private Ui::RenameMacro { Q_OBJECT public: RenameMacro(Macros *M,QWidget* parent = 0, Qt::WFlags fl = 0 ); ~RenameMacro(); /*$PUBLIC_FUNCTIONS$*/ public slots: /*$PUBLIC_SLOTS$*/ protected: ReadOnlyStringListModel *model; Macros *AllMacros; int MacroNumber; protected slots: /*$PROTECTED_SLOTS$*/ virtual void accept(); void selectMacro(const QModelIndex &); }; #endif linpsk/gui/modemenu.cpp0000644000175000017500000000600711337745305015366 0ustar schroerschroer/*************************************************************************** * 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(QWidget* parent, Qt::WFlags fl) : QDialog( parent, fl ), Ui::ModeMenu() { setupUi(this); RxMode->insertItem(0,"BPSK"); RxMode->insertItem(1,"QPSK"); RxMode->insertItem(2,"RTTY"); RxMode->insertItem(3,"MFSK16"); RxMode->setCurrentRow(settings.ActChannel->getModulationType() ); connect(RxMode,SIGNAL(itemSelectionChanged ()),this,SLOT(changeView())); Stopbits=new QButtonGroup(this); Stopbits->addButton(One,0); Stopbits->addButton(Onepoint5,1); Stopbits->addButton(Two,2); Parity=new QButtonGroup(this); Parity->addButton(None,0); Parity->addButton(Odd,1); Parity->addButton(Even,2); if ( settings.ActChannel->getModulationType() != RTTY) { ParityLayout->hide(); Spacing->hide(); Reverse->hide(); StopbitsLayout->hide(); } } ModeMenu::~ModeMenu() { } void ModeMenu::changeView() { int index=RxMode->currentRow(); if ( index == RTTY ) { ParityLayout->show(); Spacing->show(); Reverse->show(); StopbitsLayout->show(); } else { ParityLayout->hide(); Spacing->hide(); Reverse->hide(); StopbitsLayout->hide(); } } void ModeMenu::setParameter(ExtraParameter Param) { RTTYSpacing->setValue(Param.offset); /** FIXME Parity->setChecked(Param.parity); Stopbits->setChecked(Param.stopbits); **/ Reverse->setChecked(Param.reverse); } ExtraParameter ModeMenu::getParameter() { ExtraParameter Param; Param.offset=RTTYSpacing->value(); Param.reverse=Reverse->isChecked(); Param.parity=(Paritaet) Parity->checkedId(); Param.stopbits=(StopBits) Stopbits->checkedId(); return Param; } Mode ModeMenu::selectedMode() { return (Mode) RxMode->currentRow(); } linpsk/gui/editmacro.h0000644000175000017500000000357711337745305015202 0ustar schroerschroer/*************************************************************************** * 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 EDITMACRO_H #define EDITMACRO_H #include #include "ui_editmacro.h" class Macros; class ReadOnlyStringListModel; class EditMacro : public QDialog, private Ui::EditMacro { Q_OBJECT public: EditMacro(Macros *M,QWidget* parent = 0, Qt::WFlags fl = 0 ); ~EditMacro(); public slots: /*$PUBLIC_SLOTS$*/ protected: Macros *AllMacros; ReadOnlyStringListModel *model; protected slots: /*$PROTECTED_SLOTS$*/ virtual void accept(); void setText( int Number); void insertKeyword(const QModelIndex &); }; #endif linpsk/gui/editmacro.ui0000644000175000017500000000757711337745305015374 0ustar schroerschroer EditMacro 0 0 578 293 600 320 EditMacro true Accelerator false Position false Definition false Keywords false &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 linpsk/gui/qsodata.ui0000644000175000017500000014310711337745305015047 0ustar schroerschroer QSOData 0 0 420 264 2 1 240 200 600 800 190 180 QSOData QsoData Qt::AlignHCenter false 7 3 7 3 Callsign Frequency Name QTH RST received RST given Date Time Locator 0 1 Dist. 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 Main Prefix 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 Continent 0 0 Waz Zone Itu Zone 0 0 Country Worked Qt::Horizontal 72 22 0 0 Save 0 0 Refresh 0 0 Clear 255 255 255 255 255 255 233 232 232 true QFrame::StyledPanel QFrame::Sunken Qt::NoTextInteraction 255 255 255 255 255 255 255 255 255 true QFrame::StyledPanel QFrame::Sunken Qt::NoTextInteraction 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 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 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 linpsk/gui/generalsettings.h0000644000175000017500000000374611337745305016427 0ustar schroerschroer/*************************************************************************** * 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 "ui_generalsettings.h" class Parameter; class QButtonGroup; class QModelIndex; class GeneralSettings : public QDialog, private Ui::GeneralSettings { Q_OBJECT public: GeneralSettings(QWidget* parent = 0, Qt::WFlags fl = 0 ); ~GeneralSettings(); Parameter getSettings(); public slots: /*$PUBLIC_SLOTS$*/ protected: QButtonGroup *FileFormat; /*$PROTECTED_FUNCTIONS$*/ Parameter LocalSettings; protected slots: void selectDemomode(bool); void setPTTDevice(const QModelIndex &); void selectFileLogging(bool); void selectLinLogLogging(bool); }; #endif linpsk/gui/addrxwindow.ui0000644000175000017500000001405011337745305015737 0ustar schroerschroer 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/gui/deletemacro.h0000644000175000017500000000366511337745305015515 0ustar schroerschroer/*************************************************************************** * 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 DELETEMACRO_H #define DELETEMACRO_H #include #include "ui_deletemacro.h" class Macros; class ReadOnlyStringListModel; class DeleteMacro : public QDialog, private Ui::DeleteMacro { Q_OBJECT public: DeleteMacro(Macros *M,QWidget* parent = 0, Qt::WFlags fl = 0 ); ~DeleteMacro(); /*$PUBLIC_FUNCTIONS$*/ public slots: /*$PUBLIC_SLOTS$*/ protected: Macros *AllMacros; ReadOnlyStringListModel *model; ReadOnlyStringListModel *deleteList; protected slots: /*$PROTECTED_SLOTS$*/ virtual void accept(); void removefromList(); void addtoList(); }; #endif linpsk/gui/addmacro.h0000644000175000017500000000377111337745305015001 0ustar schroerschroer/*************************************************************************** * 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 ADDMACRO_H #define ADDMACRO_H #include #include #include "macros.h" #include "ui_addmacro.h" class Macros; class QModelIndex; class AddMacro : public QDialog, private Ui::AddMacro { Q_OBJECT public: AddMacro(Macros *,QWidget* parent = 0, Qt::WFlags fl = 0 ); ~AddMacro(); /*$PUBLIC_FUNCTIONS$*/ //void setKeywords( Macros *k ); QString macroName(); QString macroDefinition(); int position(); QString accelerator(); public slots: /*$PUBLIC_SLOTS$*/ protected: /*$PROTECTED_FUNCTIONS$*/ protected slots: /*$PROTECTED_SLOTS$*/ virtual void accept(); void insertKeyword(const QModelIndex &); }; #endif linpsk/gui/editmacro.cpp0000644000175000017500000000524611337745305015530 0ustar schroerschroer/*************************************************************************** * 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 "editmacro.h" #include "macros.h" #include "readonlystringlistmodel.h" EditMacro::EditMacro(Macros *M,QWidget* parent, Qt::WFlags fl) : QDialog( parent, fl ), Ui::EditMacro() { setupUi(this); AllMacros=M; model=new ReadOnlyStringListModel(); model->setStringList(M->getKeyWordList()); Keywords->setModel(model); int anzahl=AllMacros->count(); Position->setMaximum(anzahl); SelectMacro->insertItem(0," "); connect(SelectMacro,SIGNAL(activated(int)),this,SLOT(setText(int))); connect(Keywords,SIGNAL(activated(const QModelIndex &)),this,SLOT(insertKeyword(const QModelIndex &))); for(int i=0; i < anzahl; i++) SelectMacro->insertItem(i+1,AllMacros->getMacroName(i)); } EditMacro::~EditMacro() { } void EditMacro::accept() { int AktPosition; AktPosition=SelectMacro->currentIndex()-1; AllMacros->setDefinition(Definition->toPlainText(),AktPosition); AllMacros->setAccelerator(Accelerator->text(),AktPosition); QDialog::accept(); } void EditMacro::setText( int Number) { if( Number > 0) { Number--; Position->setValue(Number); Definition->setText(AllMacros->getDefinition(Number)); Accelerator->setText(AllMacros->getAccelerator(Number)); } } void EditMacro::insertKeyword(const QModelIndex &index) { QString s=index.data().toString(); Definition->insertPlainText(s); Definition->setFocus(); } linpsk/gui/gui.pro0000644000175000017500000000115511337745305014356 0ustar schroerschroerFORMS += addmacro.ui \ addrxwindow.ui \ deletemacro.ui \ editmacro.ui \ generalsettings.ui \ modemenu.ui \ qsodata.ui \ renamemacro.ui CONFIG += build_all \ staticlib \ debug DESTDIR = . SOURCES += generalsettings.cpp \ addmacro.cpp \ addrxwindow.cpp \ deletemacro.cpp \ modemenu.cpp \ qsodata.cpp \ renamemacro.cpp \ editmacro.cpp HEADERS += generalsettings.h \ addmacro.h \ addrxwindow.h \ deletemacro.h \ modemenu.h \ qsodata.h \ renamemacro.h \ editmacro.h TEMPLATE = lib QMAKE_CXXFLAGS_DEBUG += -g3 \ -O0 QMAKE_CXXFLAGS_RELEASE += -O2 CONFIG -= debug QT += network INCLUDEPATH += ../src linpsk/gui/addrxwindow.cpp0000644000175000017500000000375411337745305016115 0ustar schroerschroer/*************************************************************************** * 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 "addrxwindow.h" #include "parameter.h" extern Parameter settings; AddRxWindow::AddRxWindow(QWidget* parent, Qt::WFlags fl) : QDialog( parent, fl ), Ui::AddRxWindow() { setupUi(this); RxMode->insertItem(0,"BPSK"); RxMode->insertItem(1,"QPSK"); RxMode->insertItem(2,"RTTY"); RxMode->insertItem(3,"MFSK16"); RxMode->setCurrentRow(0); TitleText->setText("Rx " + QString().setNum(settings.RxChannels+1)); } AddRxWindow::~AddRxWindow() { } Mode AddRxWindow::selectedMode() { return (Mode) RxMode->currentRow(); } QString AddRxWindow::titleText() { return TitleText->text(); } int AddRxWindow::frequency() { return Frequency->value(); } linpsk/gui/deletemacro.ui0000644000175000017500000001565411337745305015704 0ustar schroerschroer DeleteMacro 0 0 600 291 300 200 600 400 300 100 Delete Macro 80 30 Available Macros Qt::PlainText false Qt::Horizontal 117 20 80 25 Macros to be deleted false 0 0 130 100 Qt::Vertical 20 70 0 0 0 0 100 15 16777215 20 Add to list -> 0 0 120 15 200 20 Remove from list <- Qt::Vertical 20 69 60 25 Ok Qt::Horizontal QSizePolicy::Expanding 140 20 60 25 Cancel Qt::Horizontal 117 20 Qt::Horizontal 208 20 qPixmapFromMimeSource Ok clicked() DeleteMacro accept() 20 20 20 20 Cancel clicked() DeleteMacro reject() 20 20 20 20 linpsk/gui/addmacro.ui0000644000175000017500000002260611337745305015165 0ustar schroerschroer AddMacro 0 0 676 531 0 0 600 450 600 350 Add Macro true 90 20 Macro Name Qt::PlainText false 0 0 210 20 145 20 Position in Macro List false Qt::Horizontal 72 20 45 20 1 90 20 Accelerator false 0 0 210 20 Qt::Horizontal 72 20 0 20 Macro Text Qt::PlainText false 0 20 List of macros false 0 0 0 0 &OK true true Qt::Horizontal 72 22 &Cancel true Qt::Horizontal 71 22 Keywords false Qt::Horizontal QSizePolicy::Expanding 237 21 Qt::Horizontal 338 21 Example 10 20 281 41 QFrame::NoFrame QFrame::Plain @TX@ cq cq de @CALLSIGN@ pse k @RX@ Qt::PlainText false qPixmapFromMimeSource buttonOk clicked() AddMacro accept() 20 20 20 20 buttonCancel clicked() AddMacro reject() 20 20 20 20 linpsk/gui/modemenu.h0000644000175000017500000000357111337745305015036 0ustar schroerschroer/*************************************************************************** * 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 "ui_modemenu.h" #include "constants.h" class QButtonGroup; class ModeMenu : public QDialog, private Ui::ModeMenu { Q_OBJECT public: ModeMenu(QWidget* parent = 0, Qt::WFlags fl = 0 ); ~ModeMenu(); /*$PUBLIC_FUNCTIONS$*/ void setParameter(ExtraParameter Param); ExtraParameter getParameter(); Mode selectedMode(); public slots: /*$PUBLIC_SLOTS$*/ protected: QButtonGroup *Stopbits; QButtonGroup *Parity; protected slots: void changeView(); }; #endif linpsk/gui/qsodata.h0000644000175000017500000000457611337745305014667 0ustar schroerschroer/*************************************************************************** * 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" class QChar; class ProcessLogData; class QValidator; class QSOData : public QGroupBox, private Ui::QSOData { Q_OBJECT struct coordinates { double laenge; double breite; }; public: QSOData(QWidget* parent = 0); ~QSOData(); /*$PUBLIC_FUNCTIONS$*/ public slots: /*$PUBLIC_SLOTS$*/ void Timechanged(); void Datechanged(); void MyRSTchanged(); void HisRSTchanged(); void Frequencychanged(); void Locatorchanged(); void QTHchanged(); void Namechanged(); void Callsignchanged(); void clear(); void refreshDateTime(); void save(); void calculateDistance(QString); void copyCallSign(QString); void copyQTH(QString); void copyName(QString); void copyLocator(QString); void copyRST(QString); void newChannel(); protected: coordinates loc2coordinates ( const QChar *l ); protected slots: void sendRequest(); void stopTrial(); void copyAnswer(); private: ProcessLogData *logBookCommunication; bool connectionError; QValidator *validator; }; #endif linpsk/gui/addrxwindow.h0000644000175000017500000000351311337745305015553 0ustar schroerschroer/*************************************************************************** * 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 "ui_addrxwindow.h" #include "constants.h" class AddRxWindow : public QDialog, private Ui::AddRxWindow { Q_OBJECT public: AddRxWindow(QWidget* parent = 0, Qt::WFlags fl = 0 ); ~AddRxWindow(); Mode selectedMode(); QString titleText(); int frequency(); /*$PUBLIC_FUNCTIONS$*/ public slots: /*$PUBLIC_SLOTS$*/ protected: /*$PROTECTED_FUNCTIONS$*/ protected slots: /*$PROTECTED_SLOTS$*/ }; #endif linpsk/gui/deletemacro.cpp0000644000175000017500000000546211337745305016045 0ustar schroerschroer/*************************************************************************** * 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 "deletemacro.h" #include "macros.h" //#include #include "readonlystringlistmodel.h" DeleteMacro::DeleteMacro ( Macros *M, QWidget* parent, Qt::WFlags fl ) : QDialog ( parent, fl ), Ui::DeleteMacro() { setupUi ( this ); AllMacros = M; // model = new QStringListModel ( AllMacros->getMacroList() ); model = new ReadOnlyStringListModel ( AllMacros->getMacroList() ); // deleteList = new QStringListModel ( this ); deleteList = new ReadOnlyStringListModel ( this ); MacroBox->setModel ( model ); Macrostodelete->setModel ( deleteList ); connect ( Add, SIGNAL ( clicked ( bool ) ), this, SLOT ( addtoList() ) ); connect ( Remove, SIGNAL ( clicked ( bool ) ), this, SLOT ( removefromList() ) ); } DeleteMacro::~DeleteMacro() { if ( model != 0 ) delete model; delete deleteList; } void DeleteMacro::accept() { QStringList d = deleteList->stringList(); if ( !d.isEmpty() ) { QString s; for ( int i = 0; i < d.size(); i++ ) { s = d.at ( i ); for ( int k = 0;k < AllMacros->count();k++ ) { if ( AllMacros->getMacroName ( k ) == s ) { AllMacros->deleteMacro ( k ); break; } } } // Store list to macros ?? } QDialog::accept(); } void DeleteMacro::addtoList() { QStringList l = deleteList->stringList(); l << MacroBox->currentIndex().data().toString(); deleteList->setStringList ( l ); } void DeleteMacro::removefromList() { deleteList->removeRows ( Macrostodelete->currentIndex().row(), 1 ); } linpsk/gui/renamemacro.cpp0000644000175000017500000000443011337745305016044 0ustar schroerschroer/*************************************************************************** * 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 "renamemacro.h" #include "macros.h" #include "readonlystringlistmodel.h" #include RenameMacro::RenameMacro(Macros *M,QWidget* parent, Qt::WFlags fl) : QDialog( parent, fl ), Ui::RenameMacro() { setupUi(this); model=new ReadOnlyStringListModel(); model->setStringList(M->getMacroList()); AllMacros=M; MacroBox->setModel(model); connect(MacroBox,SIGNAL(clicked(const QModelIndex &)),this,SLOT(selectMacro(const QModelIndex &))); } RenameMacro::~RenameMacro() { } void RenameMacro::accept() { if (NewName->text().length() ==0 ) { QMessageBox::warning(this, "Error", "New Name of Macro is missing. \n Enter new Name of Macro",QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton); return; } else AllMacros->setMacroName(NewName->text(),MacroNumber); QDialog::accept(); } void RenameMacro::selectMacro(const QModelIndex &index) { MacroNumber=index.row(); OldName->setText(index.data().toString()); } linpsk/src/0000755000175000017500000000000011337745306013052 5ustar schroerschroerlinpsk/src/cledbutton.cpp0000644000175000017500000000427111337745305015724 0ustar schroerschroer/*************************************************************************** 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); //drawButton(&paint); switch (status) { case ON: paint.setPen(Qt::black); paint.setBrush(Qt::red); paint.drawEllipse(4,4,14,14); break; case OFF: paint.setPen(Qt::black); paint.setBrush(Qt::green); paint.drawEllipse(4,4,14,14); break; case UNDEF: paint.setPen(Qt::black); paint.setBrush(Qt::yellow); paint.drawEllipse(4,4,14,14); break; } //paint.drawText(4,height()-5,text()); } /** sets the buttonstatus */ void CLedButton::setStatus(BUTTONSTATUS state) { status=state; switch(status) { case UNDEF: case ON: setText("RX"); break; case OFF: setText("TX"); break; } repaint(); } /** No descriptions */ void CLedButton::rxtx() { switch(status) { case UNDEF: case ON: // setStatus(OFF); emit startRx(); break; case OFF: // setStatus(ON); emit startTx(); break; } } BUTTONSTATUS CLedButton::getstatus() { return status; } linpsk/src/firfilter.cpp0000644000175000017500000000556311337745305015554 0ustar schroerschroer/*************************************************************************** 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 "firfilter.h" FIRFilter::FIRFilter(double *Filtercoeffs,int Filterlength,FilterMode Mode) { NxCoeffs=Filterlength; h=new double[Filterlength]; if (Mode == RealData) filterbuffer=new double[Filterlength]; else cfilterbuffer=new complex[Filterlength]; 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/src/frequencyselect.h0000644000175000017500000000364011337745305016426 0ustar schroerschroer/*************************************************************************** |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); // void toggleAFC(bool); }; #endif // FREQUENCYSELECT_H linpsk/src/color.h0000644000175000017500000001530611337745305014345 0ustar schroerschroer/*************************************************************************** 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/src/application.qrc0000644000175000017500000000014411337745305016062 0ustar schroerschroer ../images/linpsk.png linpsk/src/constants.h0000644000175000017500000000546211337745305015245 0ustar schroerschroer/*************************************************************************** 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 #define TXOFF_CODE -1 // control codes that can be placed in the input #define TXON_CODE -2 // queue for various control functions #define TXTOG_CODE -3 #define FFT_SIZE 2048 #define FFT_SAMPLERATEX2 11025 // 2 x the fft sample rate(so is an integer) #define TXBUFFER_LENGTH 1000 #define BUF_SIZE 4096 //size of data chunks to process at a time from // the soundcard #define RXWINDOWBUFFER 50 // Max Number of Lines in the RX ScrollBuffer // define some constants #define PI2 ( M_PI + M_PI ) // 2 Pi #define Ts (.032+.000000) // Ts == symbol period(correct for +/- .23%error) #define M_PI_3_2 (M_PI_2+M_PI) // 3Pi/2 #define M_PI_3_4 (M_PI_2+M_PI_4) // 3Pi/4 #define M_PI_5_4 (M_PI + M_PI_4) // 5Pi/4 #define M_PI_7_4 (M_PI + M_PI_2 + M_PI_4) // 7Pi/4 enum Mode {BPSK=0,QPSK,RTTY,MFSK16}; enum AfcMode {Off,Narrow,Wide}; enum Paritaet {None,Even,Odd}; enum StopBits {One,Onepoint5,Two}; enum RxTxParameterType{Reverse,Offset,Parity,Extra,Standard}; enum StateOfReception { WaitingForMark,WaitingForSpace, CheckingStartBit,SkipRestOfStartBit,CollectingByte, CheckingParity, WaitingForStopBits,ThrowHalfBit}; typedef struct { bool reverse; Paritaet parity; int offset; StopBits stopbits; } ExtraParameter; typedef struct { AfcMode afc; bool Squelch; int Threshold; } Controls; typedef struct { QString RemoteCallsign; QString OpName; QString Qth; QString Locator; QString QsoFrequency; QString HisRST; QString MyRST; QDate QsoDate; QTime QsoTime; QString mainPrefix; QString continent; QString wazZone; QString ituZone; QString countryName; QString worked; } QsoInfo; #define HilbertFilterLength 37 #endif linpsk/src/ctxwindow.h0000644000175000017500000000355411337745305015257 0ustar schroerschroer/*************************************************************************** |FILENAME| - description ------------------- begin : |DATE| copyright : (C) |YEAR| by |AUTHOR| email : |EMAIL| ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * The PSK part is based on WinPSK 1.0 by Moe Wheatley, AE4JY * ***************************************************************************/ #ifndef CTXWINDOW_H #define CTXWINDOW_H #include class QLineEdit; class QPushButton; class CTxBuffer; class QString; class CTxWindow : public QFrame { Q_OBJECT public: CTxWindow( QWidget* parent = 0); ~CTxWindow(); QPushButton* Clear; void setTxBuffer(CTxBuffer *); public slots: signals: protected: virtual void resizeEvent( QResizeEvent * e ); virtual void mousePressEvent( QMouseEvent * ); protected slots: virtual void languageChange(); void pasteText(const QString &); private: unsigned int Zeile; unsigned int Spalte; QLineEdit* Zeile2; QLineEdit* Zeile1; QLineEdit* Zeile3; void calculateSizeofComponents(); void keyPressEvent(QKeyEvent *); CTxBuffer * Buffer; void backspace(); void insert(unsigned char); private slots: virtual void clear(); void gotoNextLine(); }; #endif // CTXWINDOW_H linpsk/src/csound.h0000644000175000017500000000375011337745305014522 0ustar schroerschroer/*************************************************************************** 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(); protected: void run(); int free, freePointer, available, readPointer,toBePlayed; }; #endif linpsk/src/ctxbuffer.h0000644000175000017500000000261711337745305015220 0ustar schroerschroer/*************************************************************************** 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(); private: int txbuffer[TXBUFFER_LENGTH]; int filled; int inpos; int outpos; }; #endif linpsk/src/pskmodulator.h0000644000175000017500000000565611337745305015762 0ustar schroerschroer////////////////////////////////////////////////////////////////////// // PSKMod.h: interface for the CPSKMod class. // ////////////////////////////////////////////////////////////////////// // PSK31/CW modulator // Copyright 1999. Moe Wheatley AE4JY // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License //as published by the Free Software Foundation; either version 2 //of the License, or any later version. // //This program is distributed in the hope that it will be useful, //but WITHOUT ANY WARRANTY; without even the implied warranty of //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //GNU General Public License for more details. // //You should have received a copy of the GNU General Public License //along with this program; if not, write to the Free Software //Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // ////////////////////////////////////////////////////////////////////// // // Modified by Volker Schroer, DL1KSV, for use in LinPsk #ifndef PSKMOD_H #define PSKMOD_H #include #include #include "ctxdisplay.h" #include "ctxwindow.h" #include "cmodulator.h" class CTxBuffer; class PSKModulator : public CModulator { Q_OBJECT public: PSKModulator(int,double,CTxBuffer *); virtual ~PSKModulator(); // PSK31 and CW modulator int CalcSignal( double* pData , int n); /** length = CalcSignal (double *pData, int n) Reads tx Buffer and calculates the signal values to be transmitted double *pData pointer to array for computed signal values n length of array length number of calculated values , normally n -length at the end of transmission */ private: QString m_TestString; unsigned int m_AmblePtr; int m_Preamble[33]; int m_Postamble[33]; // PSK31 and CW generator variables double m_t; int m_Ramp; /// double m_RMSConstant; double m_PSKSecPerSamp; double m_PSKTime; double m_PSKPeriodUpdate; double m_PSKPhaseInc; double* m_pPSKtxI; double* m_pPSKtxQ; int m_PresentPhase; int m_CWState; int m_CWtimer; // PSK31 and CW modulator private functions // char GetNextBPSKSymbol(void); // char GetNextQPSKSymbol(void); virtual char GetNextSymbol(void)=0; char GetNextCWSymbol(void); protected: char m_Lastsymb; unsigned short int m_TxShiftReg; int GetChar(); bool m_AddEndingZero; static const unsigned short int VARICODE_TABLE[]; enum Status { TX_END_STATE, //Xmitting should be stoped TX_OFF_STATE, //TX is off, so we are receiving TX_SENDING_STATE, //TX is sending text TX_PAUSED_STATE , //TX is paused TX_PREAMBLE_STATE, //TX sending starting preamble TX_POSTAMBLE_STATE, //TX sending ending posteamble TX_CWID_STATE, //TX sending CW ID TX_TUNE_STATE //TX is tuning mode }; Status status; public slots: signals: // Signals /** Tx finished */ // void finished(); // void charSend(char); }; #endif linpsk/src/frequencyselect.cpp0000644000175000017500000001125411337745305016761 0ustar schroerschroer/*************************************************************************** |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( 300 ); frequency = 1000; Frequency->setValue( (int) frequency ); languageChange(); connect(Frequency,SIGNAL(valueChanged(int)),this,SLOT(checkFrequency(int))); connect(AfcWide,SIGNAL(clicked()),this,SLOT(toggleWide())); connect(Activate,SIGNAL(clicked()),this,SLOT(toggleActivate())); } /* * Destroys the object and frees any allocated resources */ FrequencySelect::~FrequencySelect() { // no need to delete child widgets, Qt does it all for us } /* * Sets the strings of the subwidgets using the current * language. */ void FrequencySelect::languageChange() { Activate->setText( tr( "Frequency" ) ); } double FrequencySelect::getFrequency() { return frequency; } void FrequencySelect::setFunctionText( QString Text) { Activate->setText(Text); } void FrequencySelect::calculateSizeofComponents() { #define LEFTANDRIGHTMARGIN 6 #define TOPANDBOTTOM 30 #define LABELHEIGHT 35 int width,height,xpos,ypos,innerwidth,innerheight; width=this->width(); height=this->height(); xpos=width*LEFTANDRIGHTMARGIN/100; ypos=height*TOPANDBOTTOM/100; innerwidth=width-2*xpos; innerheight=height*LABELHEIGHT/100; Frequency->setGeometry(xpos,ypos,innerwidth,innerheight); ypos=ypos+innerheight; innerwidth=innerwidth/2; xpos = xpos -2; Activate->setGeometry(xpos,ypos,innerwidth,innerheight); AfcWide->setText("Wide"); AfcWide->setGeometry(xpos+innerwidth+1,ypos,innerwidth,innerheight); resize(width,height); } void FrequencySelect::resizeEvent( QResizeEvent * ) { calculateSizeofComponents(); } void FrequencySelect::setFrequency( double freq) { Frequency->setValue( (int) freq); frequency=freq; } void FrequencySelect::checkFrequency(int freq) { if ((unsigned int) freq != (unsigned int)frequency) { frequency= freq; emit FrequencyChanged(frequency); } } AfcMode FrequencySelect::getAfcMode() { return modus; } void FrequencySelect::setAfcMode(AfcMode mode) { modus=mode; if ( modus == Narrow ) { Activate->setChecked(true); AfcWide->setChecked(false); } else if ( modus == Wide ) { Activate->setChecked(false); AfcWide->setChecked(true); } else { Activate->setChecked(false); AfcWide->setChecked(false); } } void FrequencySelect::setAfcDisplayMode(AfcMode Mode) { switch (Mode) { case Off: Activate->hide(); AfcWide->hide(); break; case Narrow: Activate->show(); AfcWide->hide(); break; case Wide: Activate->show(); AfcWide->show(); break; } } void FrequencySelect::toggleWide() { bool OnOff=AfcWide->isChecked(); Activate->setChecked(false); AfcWide->setChecked(OnOff); if( OnOff ) modus=Wide; else modus=Off; } void FrequencySelect::toggleActivate() { bool OnOff=Activate->isChecked(); AfcWide->setChecked(false); Activate->setChecked(OnOff); if( OnOff ) modus=Narrow; else modus=Off; } linpsk/src/viterbi.cpp0000644000175000017500000000623311337745306015226 0ustar schroerschroer/*************************************************************************** viterbi.cpp - description ------------------- begin : Sam Mr 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,const double (*d)(double *,int)) { int i; dist = d; NumberofStates= 1 << K; // 2 ** K Metric = new double[NumberofStates/2]; PathMem= new long long int [NumberofStates/2]; StateTable = new unsigned int[NumberofStates]; distance = new double[NumberofStates]; bitestimate = new long long int [NumberofStates]; Metric[0]=0.0; for(i=1; i < NumberofStates/2; i++) Metric[i]=10000.; for(i=0; i < NumberofStates/2;i++) { PathMem[i]=0; bitestimate[i]=0; } /** Calculate State Table **/ for(i=0; i < NumberofStates; i++) { unsigned int k,count; k = PolyA & i; count = 0; while ( k > 0) { if ( k & 1) count ++; k = k >>1; } StateTable[i]= (count &1) << 1; k = PolyB & i; count = 0; while ( k > 0) { if ( k & 1) count ++; k = k >>1; } StateTable[i]= StateTable[i] | (count & 1 ) ; } CoderState=0; } Viterbi::~Viterbi() { if ( Metric !=0 ) delete Metric; if ( PathMem !=0 ) delete PathMem; if ( StateTable != 0) delete StateTable; if (distance !=0 ) delete distance; if (bitestimate !=0 ) delete bitestimate; } int Viterbi::encode(int i) { CoderState= (( CoderState << 1 ) | ( i & 0x03)) & (NumberofStates - 1); return StateTable[CoderState]; } void Viterbi::decode(double *c) { double min; int i; min=1.0E99; MinimumPath=0; for(i=0; i > i ) & 1; } int Viterbi::getbitinvers(unsigned int i) { return (~( PathMem[MinimumPath] >> i )) & 1; } linpsk/src/processlogdata.h0000644000175000017500000000444611337745306016245 0ustar schroerschroer/*************************************************************************** * 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 requestCallSign ( QLabel **, QString s ); void run(); private: enum RequestType {Save = 0, Request}; RequestType requestType; QString actionString; QTcpSocket *tcpSocket; QLabel * results[6]; bool connectionEstablished; bool connectionError; private slots: void doAction(); void connectionClosedbyHost(); void readAnswer(); void setConnected(); void setError ( QAbstractSocket::SocketError ); signals: void unabletoConnect(); void answerAvailable(); }; #endif linpsk/src/bpskdemodulator.h0000644000175000017500000000267111337745306016430 0ustar schroerschroer/*************************************************************************** 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(); protected: /** Decodes a BPSK Symbol */ void DecodeSymbol( double); void CalcQuality(double); private: bool GetBPSKSymb(); double ave1; double ave2; }; #endif linpsk/src/qpskdemodulator.cpp0000644000175000017500000000754611337745306017010 0ustar schroerschroer/*************************************************************************** qpskdemodulator.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 "qpskdemodulator.h" #include "viterbi.h" // phase wraparound correction table for viterbi decoder //static const double AngleTbl1[4] = { M_PI_3_2, 0.0, M_PI/2.0, M_PI}; //static const double AngleTbl2[4] = { M_PI_3_2, PI2, M_PI/2.0, M_PI}; //static const double AngleTbl1[4] = { M_PI_2, -M_PI, -M_PI_2,0.0}; //static const double AngleTbl2[4] = { M_PI_2, M_PI, M_PI_3_2,0.0}; static const double AngleTbl1[4] = { 0.0, -M_PI_2, -M_PI,-M_PI_3_2}; static const double AngleTbl2[4] = { 0.0, M_PI_3_2, M_PI,M_PI_2}; static const double qdistance(double *x,int i) { const double *pAngle; if ( *x >0.0) pAngle = AngleTbl2; else pAngle = AngleTbl1; //i = (~i) & 0x03; i= i & 0x03; return fabs(*x - pAngle[i]); } QPskDemodulator::QPskDemodulator():CPskDemodulator() { ave1=1.0; ave2=1.0; v=new Viterbi(5,0x19,0x17,qdistance); } QPskDemodulator::~QPskDemodulator() { } void QPskDemodulator::DecodeSymbol(double angle) { int bit; char ch =0; CalcQuality(angle); v->decode( &angle); bit = v->getbitinvers(32); if( (bit==0) && m_LastBitZero ) //if character delimiter { if(m_BitAcc != 0 ) { m_BitAcc >>= 2; //get rid of last zero and one m_BitAcc &= 0x07FF; ch = m_VaricodeDecTbl[m_BitAcc]; m_BitAcc = 0; if( (ch!=0) && ( !Squelch || (Squelch && (fastSquelch || ( ( unsigned int ) m_DevAve > Threshold )))) // Squelch Part ) { emit newSymbol(ch); if (fastSquelch && (( unsigned int ) m_DevAve < Threshold) ) fastSquelch = false; } } } else { m_BitAcc <<= 1; m_BitAcc |= bit; if(bit==0) m_LastBitZero = true; else m_LastBitZero = false; } if (bit) { m_OffCount=0; if (m_OnCount++ >20) fastSquelch=true; } else { m_OnCount=0; if (m_OffCount++ > 20) fastSquelch=false; } } ////////////////////////////////////////////////////////////////////// // Calculate signal quality based on the statistics of the phase // difference angle. The more dispersion of the "0" and "180" degree // phase shifts, the worse the signal quality. This information is used // to activate the squelch control. If 20 consecutive "180" degree shifts // occur, the squelch is forced on, and if 20 consecutive "0" degree // shifts occur, the squelch is forced off quickly. ////////////////////////////////////////////////////////////////////// void QPskDemodulator::CalcQuality( double angle ) { double temp; double absangle; absangle= fabs(angle); if ( absangle < M_PI_4) temp= angle; else { if ( absangle < M_PI_3_4 ) temp = M_PI_2 - absangle; else temp = M_PI - absangle; } if ( angle < 0.0 ) temp = -temp; m_QFreqError = temp; temp = fabs(temp); // m_DevAve =0.47 * ave1 + 0.46 * ave2 + 0.07 *temp; m_DevAve =0.5 * ave1 + 0.45 * ave2 + 0.05*temp; ave2=ave1; ave1=m_DevAve; // And now norm m_DevAve for use in Squelch m_DevAve = 100. -m_DevAve *110.; } linpsk/src/ctrigger.cpp0000644000175000017500000000301411337745306015362 0ustar schroerschroer #include "ctrigger.h" #include #include /* * Constructs a CTrigger which is a child of 'parent', with the * name 'name'.' */ CTrigger::CTrigger(const QString name, QWidget* parent ) : QGroupBox(name, parent) { // setFrameShape( QGroupBox::WinPanel ); // setFrameShadow( QGroupBox::Raised ); setAlignment( Qt::AlignHCenter ); TriggerText = new QLineEdit( this ); // TriggerText->setMaxLength( 80 ); Activate = new QRadioButton( "Activate", this ); languageChange(); } /* * Destroys the object and frees any allocated resources */ CTrigger::~CTrigger() { // no need to delete child widgets, Qt does it all for us } /* * Sets the strings of the subwidgets using the current * language. */ void CTrigger::languageChange() { setTitle( tr( "Trigger" ) ); TriggerText->setText( tr( "CQ CQ" ) ); Activate->setText( tr( "Activate" ) ); } void CTrigger::resizeEvent( QResizeEvent * ) { calculateSizeofComponents(); } void CTrigger::calculateSizeofComponents() { #define LEFTANDRIGHTMARGIN 5 #define TOP 30 #define LABELHEIGHT 30 int xpos,ypos,width,height,innerwidth,innerheight; width=this->width(); height=this->height(); xpos=width*LEFTANDRIGHTMARGIN/100; ypos=height*TOP/100; innerwidth=width-2*xpos; innerheight=height*LABELHEIGHT/100; TriggerText->setGeometry(xpos,ypos,innerwidth,innerheight); ypos=ypos+innerheight; Activate->setGeometry(xpos+1,ypos,innerwidth-2,innerheight); //this->setFrameRect(QRect(0,0,width,height)); resize(width,height); } linpsk/src/macros.cpp0000644000175000017500000002015511337745306015045 0ustar schroerschroer/*************************************************************************** Macros.cpp - description ------------------- begin : Sam Mai 10 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 "macros.h" #include "parameter.h" #include "ctxbuffer.h" #include #include #include "constants.h" #include #include extern Parameter settings; Macros::Macros() { Words << "@CALLSIGN@" << "@DATE@" << "@Replace by filename@" << "@RX@" << "@THEIRCALL@" << "@THEIRNAME@" << "@TIMELOCAL@" << "@TIMEUTC@" << "@TX@" << "@RSTGIVEN@" << "@RSTRCVD@"; NumberofMacros = 0; } Macros::~Macros() { } void Macros::insert ( QString Name, QString Definition, QString Acc, int position ) { if ( position <= NumberofMacros ) { MacroNames.replace ( position - 1, Name ); MacroText.replace ( position - 1, Definition ); Accelerator.replace ( position - 1, Acc ); } else { MacroNames << Name; MacroText << Definition; Accelerator << Acc; } NumberofMacros++; } void Macros::executeMacro ( int MacroNumber, CTxBuffer *TxBuffer ) { QString Macro = MacroText[MacroNumber]; QString Token; int anzahl = Macro.count ( '@' ) / 2; if ( anzahl > 0 ) { int indexbis, indexvon = 0; for ( int i = 0; i < anzahl; i++ ) { indexbis = Macro.indexOf ( '@', indexvon ); indexvon = indexbis; indexbis = Macro.indexOf ( '@', indexvon + 1 ); Token = Macro.mid ( indexvon, indexbis - indexvon + 1 ); if ( Token == Words[0] ) // callsign { Macro.replace ( indexvon, Words[0].length(), settings.callsign ); } else if ( Token == Words[1] ) // Date { QDate t = QDate::currentDate(); Macro.replace ( indexvon, Words[1].length(), t.toString ( QString ( "d.MM.yyyy" ) ) ); } else if ( Token == Words[3] ) // RX { Macro.remove ( indexvon, 4 ); if ( settings.Status == ON ) { TxBuffer->insert ( Macro, indexvon ); emit StartRx(); } return; } else if ( Token == Words[4] ) // Remote callsign { Macro.replace ( indexvon, Words[4].length(), settings.QslData->RemoteCallsign ); } else if ( Token == Words[5] ) // Remote op's name { Macro.replace ( indexvon, Words[5].length(), settings.QslData->OpName ); } else if ( Token == Words[6] ) // Time Local { QDateTime t; t = QDateTime::currentDateTime(); Macro.replace ( indexvon, Words[6].length(), t.toString ( "h:mm" ) ); } else if ( Token == Words[7] ) // Time UTC { QDateTime t; t = QDateTime::currentDateTime(); t = t.addSecs ( settings.timeoffset * 3600 ); Macro.replace ( indexvon, Words[7].length(), t.toString ( "h:mm" ) ); } else if ( Token == Words[8] ) // TX { if ( settings.Status == UNDEF ) { QMessageBox::warning ( 0, "Warning", "Please listen before transmitting", QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton ); return; } Macro.remove ( indexvon, 4 ); if ( settings.Status == OFF ) emit StartTx(); } else if ( Token == Words[9] ) // RST given { Macro.replace ( indexvon, Words[9].length(), settings.QslData->MyRST ); } else if ( Token == Words[10] ) // RST received { Macro.replace ( indexvon, Words[10].length(), settings.QslData->HisRST ); } else // Must be File { Macro.remove ( indexvon, Token.length() ); if ( indexvon > 0 ) { TxBuffer->insert ( Macro, indexvon ); Macro.remove ( 0, indexvon ); indexvon = 0; } Token = Token.mid ( 1, Token.length() - 2 ); QFile MacroFile ( settings.Directory + QString ( "/" ) + Token ); if ( MacroFile.open ( QIODevice::ReadOnly ) ) { QTextStream line ( &MacroFile ); while ( !line.atEnd() ) { QString Txstring = line.readLine(); if(settings.autoCrLf) // AutoCrLF ?? Txstring += '\r'; Txstring += "\n"; TxBuffer->insert ( Txstring, Txstring.length() ); } MacroFile.close(); } else QMessageBox::warning ( 0, "Warning", "File " + Token + " not found ", QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton ); } } } TxBuffer->insert ( Macro, Macro.length() ); } void Macros::deleteMacro ( int number ) { if ( number < 0 || number >= NumberofMacros ) return; MacroNames.erase ( MacroNames.begin() + number ); MacroText.erase ( MacroText.begin() + number ); Accelerator.erase ( Accelerator.begin() + number ); if ( NumberofMacros > 0 ) NumberofMacros--; } QString Macros::getMacroName ( int number ) { if ( number < 0 || number >= NumberofMacros ) return QString ( "" ); QString s = MacroNames.at ( number ); return s; } int Macros::count() { return NumberofMacros; } QString Macros::getDefinition ( int number ) { if ( number < 0 || number >= NumberofMacros ) return QString ( "" ); return MacroText[number]; } QString Macros::getAccelerator ( int number ) { if ( number < 0 || number >= NumberofMacros ) return QString ( "" ); return Accelerator[number]; } int Macros::Keywordcount() { return Words.size();; } QString Macros::getKeyword ( int number ) { if ( number < 0 || number >= Keywordcount() ) return QString ( "" ); return Words[number]; } void Macros::setDefinition ( QString s, int position ) { if ( position < MacroText.size() ) MacroText.replace ( position, s ); else MacroText << s; } void Macros::setAccelerator ( QString s, int position ) { if ( position < Accelerator.size() ) Accelerator.replace ( position, s ); else Accelerator << s; } void Macros::setMacroName ( QString s, int MacroNumber ) { if ( MacroNumber < MacroNames.size() ) MacroNames.replace ( MacroNumber, s ); else MacroNames << s; } QStringList Macros::getKeyWordList() { return Words; } QStringList Macros::getMacroList() { return MacroNames; } linpsk/src/psktable.h0000644000175000017500000001222511337745306015032 0ustar schroerschroer#if !defined(PSKTablesXYZ) #define PSKTablesXYZ ////////////////////////////////////////////////////////////////////// // Copyright 1999. Moe Wheatley AE4JY // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License //as published by the Free Software Foundation; either version 2 //of the License, or any later version. // //This program is distributed in the hope that it will be useful, //but WITHOUT ANY WARRANTY; without even the implied warranty of //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //GNU General Public License for more details. // //You should have received a copy of the GNU General Public License //along with this program; if not, write to the Free Software //Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // ////////////////////////////////////////////////////////////////////// // //////////////////// Various constant tabels ////////////////////////// // The word in the CW table is divided into 8 groups of two bits starting // at the msb side. The two bits represent one of four possible states. // 00 - end of character // 01 - DOT // 10 - DASH // 11 - SPACE of two dot times const unsigned short int CW_TABLE[59]= { 0xF000, // 1111 0000 0000 0000b ( 32) WORD SPACE 0x0000, // 0000 0000 0000 0000b ( 33) ! 0x0000, // 0000 0000 0000 0000b ( 34) " 0x0000, // 0000 0000 0000 0000b ( 35) # 0x0000, // 0000 0000 0000 0000b ( 36) $ 0x0000, // 0000 0000 0000 0000b ( 37) % 0x0000, // 0000 0000 0000 0000b ( 38) & 0x0000, // 0000 0000 0000 0000b ( 39) ' 0x0000, // 0000 0000 0000 0000b ( 40) ( 0x0000, // 0000 0000 0000 0000b ( 41) ) 0x566C, // 0101 0110 0110 1100b ( 42) * ...-.- SK 0x6670, // 0110 0110 0111 0000b ( 43) + .-.-. AR 0xA5AC, // 1010 0101 1010 1100b ( 44) , --..-- 0x0000, // 0000 0000 0000 0000b ( 45) - 0x666C, // 0110 0110 0110 1100b ( 46) . .-.-.- 0x9670, // 1001 0110 0111 0000b ( 47) / -..-. 0xAAB0, // 1010 1010 1011 0000b ( 48) 0 ----- 0x6AB0, // 0110 1010 1011 0000b ( 49) 1 .---- 0x5AB0, // 0101 1010 1011 0000b ( 50) 2 ..--- 0x56B0, // 0101 0110 1011 0000b ( 51) 3 ...-- 0x55B0, // 0101 0101 1011 0000b ( 52) 4 ....- 0x5570, // 0101 0101 0111 0000b ( 53) 5 ..... 0x9570, // 1001 0101 0111 0000b ( 54) 6 -.... 0xA570, // 1010 0101 0111 0000b ( 55) 7 --... 0xA970, // 1010 1001 0111 0000b ( 56) 8 ---.. 0xAA70, // 1010 1010 0111 0000b ( 57) 9 ----. 0x0000, // 0000 0000 0000 0000b ( 58) : 0x0000, // 0000 0000 0000 0000b ( 59) ; 0x0000, // 0000 0000 0000 0000b ( 60) < 0x95B0, // 1001 0101 1011 0000b ( 61) = -...- BT 0x0000, // 0000 0000 0000 0000b ( 62) > 0x5A5C, // 0101 1010 0101 1100b ( 63) ? ..--.. 0x0000, // 0000 0000 0000 0000b ( 64) @ 0x6C00, // 0110 1100 0000 0000b ( 65) A .- 0x95C0, // 1001 0101 1100 0000b ( 66) B -... 0x99C0, // 1001 1001 1100 0000b ( 67) C -.-. 0x9700, // 1001 0111 0000 0000b ( 68) D -.. 0x7000, // 0111 0000 0000 0000b ( 69) E . 0x59C0, // 0101 1001 1100 0000b ( 70) F ..-. 0xA700, // 1010 0111 0000 0000b ( 71) G --. 0x55C0, // 0101 0101 1100 0000b ( 72) H .... 0x5C00, // 0101 1100 0000 0000b ( 73) I .. 0x6AC0, // 0110 1010 1100 0000b ( 74) J .--- 0x9B00, // 1001 1011 0000 0000b ( 75) K -.- 0x65C0, // 0110 0101 1100 0000b ( 76) L .-.. 0xAC00, // 1010 1100 0000 0000b ( 77) M -- 0x9C00, // 1001 1100 0000 0000b ( 78) N -. 0xAB00, // 1010 1011 0000 0000b ( 79) O --- 0x69C0, // 0110 1001 1100 0000b ( 80) P .--. 0xA6C0, // 1010 0110 1100 0000b ( 81) Q --.- 0x6700, // 0110 0111 0000 0000b ( 82) R .-. 0x5700, // 0101 0111 0000 0000b ( 83) S ... 0xB000, // 1011 0000 0000 0000b ( 84) T - 0x5B00, // 0101 1011 0000 0000b ( 85) U ..- 0x56C0, // 0101 0110 1100 0000b ( 86) V ...- 0x6B00, // 0110 1011 0000 0000b ( 87) W .-- 0x96C0, // 1001 0110 1100 0000b ( 88) X -..- 0x9AC0, // 1001 1010 1100 0000b ( 89) Y -.-- 0xA5C0 // 1010 0101 1100 0000b ( 90) Z --.. }; // For the QPSK modulator/demodulator, rate 1/2 constraint length 5 // convolutional FEC coding is used. // The generator polynomials used are: // g1(x) = x^4 + x^3 + 1 = 0x19 // g0(x) = x^4 + x^2 + x + 1 = 0x17 // // g1(x) // /----+--------+--------------------------+ // / | | | // symbol msb --- --- --- --- --- // | b4|<---| b3|<---| b2|<---| b1|<---| b0| <-- inverted data in // symbol lsb --- --- --- --- --- // \ | | | | // \----+-----------------+--------+--------+ // g0(x) // // Lookup table to get symbol from non-inverted data stream /** static const unsigned char ConvolutionCodeTable[32] = { 2, 1, 3, 0, 3, 0, 2, 1, 0, 3, 1, 2, 1, 2, 0, 3, 1, 2, 0, 3, 0, 3, 1, 2, 3, 0, 2, 1, 2, 1, 3, 0 }; **/ #endif linpsk/src/ctrigger.h0000644000175000017500000000277211337745306015041 0ustar schroerschroer/*************************************************************************** |FILENAME| - description ------------------- begin : |DATE| copyright : (C) |YEAR| by |AUTHOR| email : |EMAIL| ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * The PSK part is based on WinPSK 1.0 by Moe Wheatley, AE4JY * ***************************************************************************/ #ifndef CTRIGGER_H #define CTRIGGER_H #include class QVBoxLayout; class QHBoxLayout; class QGridLayout; class QLineEdit; class QRadioButton; class CTrigger : public QGroupBox { Q_OBJECT public: CTrigger(const QString, QWidget* parent = 0 ); ~CTrigger(); QLineEdit* TriggerText; QRadioButton* Activate; public slots: protected: void resizeEvent( QResizeEvent * ); protected slots: virtual void languageChange(); private: void calculateSizeofComponents(); }; #endif // CTRIGGER_H linpsk/src/macros.h0000644000175000017500000000356011337745306014513 0ustar schroerschroer/*************************************************************************** keywords.h - description ------------------- begin : Sam Mai 10 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 MACROS_H #define MACROS_H #include #include /**Contains the Keywords for Macro Processing Offers the methods for processing the Keywords *@author Volker Schroer */ class CTxBuffer; class Macros : public QObject { Q_OBJECT public: Macros(); ~Macros(); void executeMacro(int,CTxBuffer *); void insert(QString ,QString , QString,int); void deleteMacro(int); QString getMacroName(int); QString getDefinition(int); void setDefinition(QString,int); void setAccelerator(QString,int); void setMacroName(QString,int); QString getAccelerator(int); QString getKeyword(int); QStringList getKeyWordList(); QStringList getMacroList(); int count(); int Keywordcount(); private: QStringList Words; QStringList MacroNames ; QStringList MacroText; QStringList Accelerator; int NumberofMacros; signals: void StartRx(); void StartTx(); }; #endif linpsk/src/pskmodulator.cpp0000644000175000017500000005161111337745306016306 0ustar schroerschroer////////////////////////////////////////////////////////////////////// // PSKMod.cpp: implementation of the PSKModulator class. // ////////////////////////////////////////////////////////////////////// // PSK31/CW modulator // Copyright 1999. Moe Wheatley AE4JY // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License //as published by the Free Software Foundation; either version 2 //of the License, or any later version. // //This program is distributed in the hope that it will be useful, //but WITHOUT ANY WARRANTY; without even the implied warranty of //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //GNU General Public License for more details. // //You should have received a copy of the GNU General Public License //along with this program; if not, write to the Free Software //Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // ////////////////////////////////////////////////////////////////////// // // modified by Volker Schroer , DL1KSV for use in LinPsk #include #include "psktable.h" #include "pskmodulator.h" #include "ctxbuffer.h" // local defines................. #define PHZ_0 0 //specify various signal phase states #define PHZ_90 1 #define PHZ_180 2 #define PHZ_270 3 #define PHZ_OFF 4 #define SYM_NOCHANGE 0 //Stay the same phase #define SYM_P90 1 //Plus 90 deg #define SYM_P180 2 //Plus 180 deg #define SYM_M90 3 //Minus 90 deg #define SYM_OFF 4 //No output #define SYM_ON 5 //constant output #define SYMBOL_RATE 31.25 // 31.25 Symbols per Second #define MAXRAMP_SIZE (((100*11100)/3125)+1) // max number of envelope ramp steps per symbol /** Not needed any longer #define TX_CONSTANT 23000.0 // TX Amplitude Factor **/ #define CW_SPEED 1 //bigger is slower. 1 is fastest. // The use of static's here preclude having multiple instantiations // of this class but should not be an issue since only one soundcard. //Ramp shape tables that are loaded with cosine shaped functions at init static double PSKShapeTbl_Z[MAXRAMP_SIZE]; // 0 static double PSKShapeTbl_P[MAXRAMP_SIZE]; // +1 static double PSKShapeTbl_M[MAXRAMP_SIZE]; // -1 static double PSKShapeTbl_ZP[MAXRAMP_SIZE]; // 0 to +1 static double PSKShapeTbl_PZ[MAXRAMP_SIZE]; // +1 to 0 static double PSKShapeTbl_MZ[MAXRAMP_SIZE]; // -1 to 0 static double PSKShapeTbl_PM[MAXRAMP_SIZE]; // +1 to -1 static double PSKShapeTbl_MP[MAXRAMP_SIZE]; // -1 to +1 // each character is separated by two zeros. The bits are sent msbit first. const unsigned short int PSKModulator::VARICODE_TABLE[] = { 0xAAC0, // ASCII = 0 1010101011 0xB6C0, // ASCII = 1 1011011011 0xBB40, // ASCII = 2 1011101101 0xDDC0, // ASCII = 3 1101110111 0xBAC0, // ASCII = 4 1011101011 0xD7C0, // ASCII = 5 1101011111 0xBBC0, // ASCII = 6 1011101111 0xBF40, // ASCII = 7 1011111101 0xBFC0, // ASCII = 8 1011111111 0xEF00, // ASCII = 9 11101111 0xE800, // ASCII = 10 11101 0xDBC0, // ASCII = 11 1101101111 0xB740, // ASCII = 12 1011011101 0xF800, // ASCII = 13 11111 0xDD40, // ASCII = 14 1101110101 0xEAC0, // ASCII = 15 1110101011 0xBDC0, // ASCII = 16 1011110111 0xBD40, // ASCII = 17 1011110101 0xEB40, // ASCII = 18 1110101101 0xEBC0, // ASCII = 19 1110101111 0xD6C0, // ASCII = 20 1101011011 0xDAC0, // ASCII = 21 1101101011 0xDB40, // ASCII = 22 1101101101 0xD5C0, // ASCII = 23 1101010111 0xDEC0, // ASCII = 24 1101111011 0xDF40, // ASCII = 25 1101111101 0xEDC0, // ASCII = 26 1110110111 0xD540, // ASCII = 27 1101010101 0xD740, // ASCII = 28 1101011101 0xEEC0, // ASCII = 29 1110111011 0xBEC0, // ASCII = 30 1011111011 0xDFC0, // ASCII = 31 1101111111 0x8000, // ASCII = ' ' 1 0xFF80, // ASCII = '!' 111111111 0xAF80, // ASCII = '"' 101011111 0xFA80, // ASCII = '#' 111110101 0xED80, // ASCII = '$' 111011011 0xB540, // ASCII = '%' 1011010101 0xAEC0, // ASCII = '&' 1010111011 0xBF80, // ASCII = ''' 101111111 0xFB00, // ASCII = '(' 11111011 0xF700, // ASCII = ')' 11110111 0xB780, // ASCII = '*' 101101111 0xEF80, // ASCII = '+' 111011111 0xEA00, // ASCII = ',' 1110101 0xD400, // ASCII = '-' 110101 0xAE00, // ASCII = '.' 1010111 0xD780, // ASCII = '/' 110101111 0xB700, // ASCII = '0' 10110111 0xBD00, // ASCII = '1' 10111101 0xED00, // ASCII = '2' 11101101 0xFF00, // ASCII = '3' 11111111 0xBB80, // ASCII = '4' 101110111 0xAD80, // ASCII = '5' 101011011 0xB580, // ASCII = '6' 101101011 0xD680, // ASCII = '7' 110101101 0xD580, // ASCII = '8' 110101011 0xDB80, // ASCII = '9' 110110111 0xF500, // ASCII = ':' 11110101 0xDE80, // ASCII = ';' 110111101 0xF680, // ASCII = '<' 111101101 0xAA00, // ASCII = '=' 1010101 0xEB80, // ASCII = '>' 111010111 0xABC0, // ASCII = '?' 1010101111 0xAF40, // ASCII = '@' 1010111101 0xFA00, // ASCII = 'A' 1111101 0xEB00, // ASCII = 'B' 11101011 0xAD00, // ASCII = 'C' 10101101 0xB500, // ASCII = 'D' 10110101 0xEE00, // ASCII = 'E' 1110111 0xDB00, // ASCII = 'F' 11011011 0xFD00, // ASCII = 'G' 11111101 0xAA80, // ASCII = 'H' 101010101 0xFE00, // ASCII = 'I' 1111111 0xFE80, // ASCII = 'J' 111111101 0xBE80, // ASCII = 'K' 101111101 0xD700, // ASCII = 'L' 11010111 0xBB00, // ASCII = 'M' 10111011 0xDD00, // ASCII = 'N' 11011101 0xAB00, // ASCII = 'O' 10101011 0xD500, // ASCII = 'P' 11010101 0xEE80, // ASCII = 'Q' 111011101 0xAF00, // ASCII = 'R' 10101111 0xDE00, // ASCII = 'S' 1101111 0xDA00, // ASCII = 'T' 1101101 0xAB80, // ASCII = 'U' 101010111 0xDA80, // ASCII = 'V' 110110101 0xAE80, // ASCII = 'W' 101011101 0xBA80, // ASCII = 'X' 101110101 0xBD80, // ASCII = 'Y' 101111011 0xAB40, // ASCII = 'Z' 1010101101 0xFB80, // ASCII = '[' 111110111 0xF780, // ASCII = '\' 111101111 0xFD80, // ASCII = ']' 111111011 0xAFC0, // ASCII = '^' 1010111111 0xB680, // ASCII = '_' 101101101 0xB7C0, // ASCII = '`' 1011011111 0xB000, // ASCII = 'a' 1011 0xBE00, // ASCII = 'b' 1011111 0xBC00, // ASCII = 'c' 101111 0xB400, // ASCII = 'd' 101101 0xC000, // ASCII = 'e' 11 0xF400, // ASCII = 'f' 111101 0xB600, // ASCII = 'g' 1011011 0xAC00, // ASCII = 'h' 101011 0xD000, // ASCII = 'i' 1101 0xF580, // ASCII = 'j' 111101011 0xBF00, // ASCII = 'k' 10111111 0xD800, // ASCII = 'l' 11011 0xEC00, // ASCII = 'm' 111011 0xF000, // ASCII = 'n' 1111 0xE000, // ASCII = 'o' 111 0xFC00, // ASCII = 'p' 111111 0xDF80, // ASCII = 'q' 110111111 0xA800, // ASCII = 'r' 10101 0xB800, // ASCII = 's' 10111 0xA000, // ASCII = 't' 101 0xDC00, // ASCII = 'u' 110111 0xF600, // ASCII = 'v' 1111011 0xD600, // ASCII = 'w' 1101011 0xDF00, // ASCII = 'x' 11011111 0xBA00, // ASCII = 'y' 1011101 0xEA80, // ASCII = 'z' 111010101 0xADC0, // ASCII = '{' 1010110111 0xDD80, // ASCII = '|' 110111011 0xAD40, // ASCII = '}' 1010110101 0xB5C0, // ASCII = '~' 1011010111 0xED40, // ASCII = 127 1110110101 0xEF40, // ASCII = 128 1110111101 0xEFC0, // ASCII = 129 1110111111 0xF540, // ASCII = 130 1111010101 0xF5C0, // ASCII = 131 1111010111 0xF6C0, // ASCII = 132 1111011011 0xF740, // ASCII = 133 1111011101 0xF7C0, // ASCII = 134 1111011111 0xFAC0, // ASCII = 135 1111101011 0xFB40, // ASCII = 136 1111101101 0xFBC0, // ASCII = 137 1111101111 0xFD40, // ASCII = 138 1111110101 0xFDC0, // ASCII = 139 1111110111 0xFEC0, // ASCII = 140 1111111011 0xFF40, // ASCII = 141 1111111101 0xFFC0, // ASCII = 142 1111111111 0xAAA0, // ASCII = 143 10101010101 0xAAE0, // ASCII = 144 10101010111 0xAB60, // ASCII = 145 10101011011 0xABA0, // ASCII = 146 10101011101 0xABE0, // ASCII = 147 10101011111 0xAD60, // ASCII = 148 10101101011 0xADA0, // ASCII = 149 10101101101 0xADE0, // ASCII = 150 10101101111 0xAEA0, // ASCII = 151 10101110101 0xAEE0, // ASCII = 152 10101110111 0xAF60, // ASCII = 153 10101111011 0xAFA0, // ASCII = 154 10101111101 0xAFE0, // ASCII = 155 10101111111 0xB560, // ASCII = 156 10110101011 0xB5A0, // ASCII = 157 10110101101 0xB5E0, // ASCII = 158 10110101111 0xB6A0, // ASCII = 159 10110110101 0xB6E0, // ASCII = 160 10110110111 0xB760, // ASCII = 161 10110111011 0xB7A0, // ASCII = 162 10110111101 0xB7E0, // ASCII = 163 10110111111 0xBAA0, // ASCII = 164 10111010101 0xBAE0, // ASCII = 165 10111010111 0xBB60, // ASCII = 166 10111011011 0xBBA0, // ASCII = 167 10111011101 0xBBE0, // ASCII = 168 10111011111 0xBD60, // ASCII = 169 10111101011 0xBDA0, // ASCII = 170 10111101101 0xBDE0, // ASCII = 171 10111101111 0xBEA0, // ASCII = 172 10111110101 0xBEE0, // ASCII = 173 10111110111 0xBF60, // ASCII = 174 10111111011 0xBFA0, // ASCII = 175 10111111101 0xBFE0, // ASCII = 176 10111111111 0xD560, // ASCII = 177 11010101011 0xD5A0, // ASCII = 178 11010101101 0xD5E0, // ASCII = 179 11010101111 0xD6A0, // ASCII = 180 11010110101 0xD6E0, // ASCII = 181 11010110111 0xD760, // ASCII = 182 11010111011 0xD7A0, // ASCII = 183 11010111101 0xD7E0, // ASCII = 184 11010111111 0xDAA0, // ASCII = 185 11011010101 0xDAE0, // ASCII = 186 11011010111 0xDB60, // ASCII = 187 11011011011 0xDBA0, // ASCII = 188 11011011101 0xDBE0, // ASCII = 189 11011011111 0xDD60, // ASCII = 190 11011101011 0xDDA0, // ASCII = 191 11011101101 0xDDE0, // ASCII = 192 11011101111 0xDEA0, // ASCII = 193 11011110101 0xDEE0, // ASCII = 194 11011110111 0xDF60, // ASCII = 195 11011111011 0xDFA0, // ASCII = 196 11011111101 0xDFE0, // ASCII = 197 11011111111 0xEAA0, // ASCII = 198 11101010101 0xEAE0, // ASCII = 199 11101010111 0xEB60, // ASCII = 200 11101011011 0xEBA0, // ASCII = 201 11101011101 0xEBE0, // ASCII = 202 11101011111 0xED60, // ASCII = 203 11101101011 0xEDA0, // ASCII = 204 11101101101 0xEDE0, // ASCII = 205 11101101111 0xEEA0, // ASCII = 206 11101110101 0xEEE0, // ASCII = 207 11101110111 0xEF60, // ASCII = 208 11101111011 0xEFA0, // ASCII = 209 11101111101 0xEFE0, // ASCII = 210 11101111111 0xF560, // ASCII = 211 11110101011 0xF5A0, // ASCII = 212 11110101101 0xF5E0, // ASCII = 213 11110101111 0xF6A0, // ASCII = 214 11110110101 0xF6E0, // ASCII = 215 11110110111 0xF760, // ASCII = 216 11110111011 0xF7A0, // ASCII = 217 11110111101 0xF7E0, // ASCII = 218 11110111111 0xFAA0, // ASCII = 219 11111010101 0xFAE0, // ASCII = 220 11111010111 0xFB60, // ASCII = 221 11111011011 0xFBA0, // ASCII = 222 11111011101 0xFBE0, // ASCII = 223 11111011111 0xFD60, // ASCII = 224 11111101011 0xFDA0, // ASCII = 225 11111101101 0xFDE0, // ASCII = 226 11111101111 0xFEA0, // ASCII = 227 11111110101 0xFEE0, // ASCII = 228 11111110111 0xFF60, // ASCII = 229 11111111011 0xFFA0, // ASCII = 230 11111111101 0xFFE0, // ASCII = 231 11111111111 0xAAB0, // ASCII = 232 101010101011 0xAAD0, // ASCII = 233 101010101101 0xAAF0, // ASCII = 234 101010101111 0xAB50, // ASCII = 235 101010110101 0xAB70, // ASCII = 236 101010110111 0xABB0, // ASCII = 237 101010111011 0xABD0, // ASCII = 238 101010111101 0xABF0, // ASCII = 239 101010111111 0xAD50, // ASCII = 240 101011010101 0xAD70, // ASCII = 241 101011010111 0xADB0, // ASCII = 242 101011011011 0xADD0, // ASCII = 243 101011011101 0xADF0, // ASCII = 244 101011011111 0xAEB0, // ASCII = 245 101011101011 0xAED0, // ASCII = 246 101011101101 0xAEF0, // ASCII = 247 101011101111 0xAF50, // ASCII = 248 101011110101 0xAF70, // ASCII = 249 101011110111 0xAFB0, // ASCII = 250 101011111011 0xAFD0, // ASCII = 251 101011111101 0xAFF0, // ASCII = 252 101011111111 0xB550, // ASCII = 253 101101010101 0xB570, // ASCII = 254 101101010111 0xB5B0 // ASCII = 255 101101011011 }; struct PSKStruct { double* iptr; double* qptr; int next; }; typedef PSKStruct PSKSTATE; //Lookup table for determining the next ramp shape depending on the // next symbol and the present output phase. // indexing format is [symbol][presentPhase] //returns the PSKSTRUCT containing the next phase and the I and Q // ramp table pointers. static PSKSTATE PSKPhaseLookupTable[6][5] ={ // SYMBOL = 0 = SYM_NOCHANGE // I ramp shape Q ramp shape Next Phase { {PSKShapeTbl_P, PSKShapeTbl_P, PHZ_0}, //present PHZ_0 {PSKShapeTbl_M, PSKShapeTbl_P, PHZ_90}, //present PHZ_90 {PSKShapeTbl_M, PSKShapeTbl_M, PHZ_180}, //present PHZ_180 {PSKShapeTbl_P, PSKShapeTbl_M, PHZ_270}, //present PHZ_270 {PSKShapeTbl_Z, PSKShapeTbl_Z, PHZ_OFF}}, //present PHZ_OFF // SYMBOL = 1 = SYM_P90 = Advance 90 degrees // I ramp shape Q ramp shape Next Phase { {PSKShapeTbl_PM, PSKShapeTbl_P, PHZ_90}, //present PHZ_0 {PSKShapeTbl_M, PSKShapeTbl_PM, PHZ_180}, //present PHZ_90 {PSKShapeTbl_MP, PSKShapeTbl_M, PHZ_270}, //present PHZ_180 {PSKShapeTbl_P, PSKShapeTbl_MP, PHZ_0}, //present PHZ_270 {PSKShapeTbl_ZP, PSKShapeTbl_ZP, PHZ_0}}, //present PHZ_OFF // SYMBOL = 2 = SYM_P180 = Advance 180 degrees // I ramp shape Q ramp shape Next Phase { {PSKShapeTbl_PM, PSKShapeTbl_PM, PHZ_180}, //present PHZ_0 {PSKShapeTbl_MP, PSKShapeTbl_PM, PHZ_270}, //present PHZ_90 {PSKShapeTbl_MP, PSKShapeTbl_MP, PHZ_0}, //present PHZ_180 {PSKShapeTbl_PM, PSKShapeTbl_MP, PHZ_90}, //present PHZ_270 {PSKShapeTbl_ZP, PSKShapeTbl_ZP, PHZ_0}}, //present PHZ_OFF // SYMBOL = 3 = SYM_M90 = retard 90 degrees // I ramp shape Q ramp shape Next Phase { {PSKShapeTbl_P, PSKShapeTbl_PM, PHZ_270}, //present PHZ_0 {PSKShapeTbl_MP, PSKShapeTbl_P, PHZ_0}, //present PHZ_90 {PSKShapeTbl_M, PSKShapeTbl_MP, PHZ_90}, //present PHZ_180 {PSKShapeTbl_PM, PSKShapeTbl_M, PHZ_180}, //present PHZ_270 {PSKShapeTbl_ZP, PSKShapeTbl_ZP, PHZ_0}}, //present PHZ_OFF // SYMBOL = 4 = SYM_OFF // I ramp shape Q ramp shape Next Phase { {PSKShapeTbl_PZ, PSKShapeTbl_PZ, PHZ_OFF}, //present PHZ_0 {PSKShapeTbl_MZ, PSKShapeTbl_PZ, PHZ_OFF}, //present PHZ_90 {PSKShapeTbl_MZ, PSKShapeTbl_MZ, PHZ_OFF}, //present PHZ_180 {PSKShapeTbl_PZ, PSKShapeTbl_MZ, PHZ_OFF}, //present PHZ_270 {PSKShapeTbl_Z, PSKShapeTbl_Z, PHZ_OFF}}, //present PHZ_OFF // SYMBOL = 5 = SYM_ON // I ramp shape Q ramp shape Next Phase { {PSKShapeTbl_P, PSKShapeTbl_P, PHZ_0}, //present PHZ_0 {PSKShapeTbl_MP, PSKShapeTbl_P, PHZ_0}, //present PHZ_90 {PSKShapeTbl_MP, PSKShapeTbl_MP, PHZ_0}, //present PHZ_180 {PSKShapeTbl_P, PSKShapeTbl_MP, PHZ_0}, //present PHZ_270 {PSKShapeTbl_ZP, PSKShapeTbl_ZP, PHZ_0}} //present PHZ_OFF }; ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// PSKModulator::PSKModulator(int FS, double freq, CTxBuffer *TxBuffer) : CModulator(FS, TxBuffer) { m_AmblePtr = 0; int RampSize; int i; m_PSKPhaseInc = PI2 * freq / (double) SampleRate; //carrier frequency m_PSKSecPerSamp = 1.0 / (double) SampleRate; m_PSKTime = 0.0; m_t = 0.0; m_Ramp = 0; m_PSKPeriodUpdate = 1.0 / SYMBOL_RATE; //symbol period m_Lastsymb = SYM_OFF; m_AddEndingZero = true; m_CWState = 0; m_CWtimer = 0; // Generate cosine ramp envelope lookup tables RampSize = (((100 * SampleRate) / 3125) + 1); // number of envelope ramp steps per symbol for (i = 0; i < RampSize; i++) { PSKShapeTbl_Z[i] = 0.0; PSKShapeTbl_P[i] = 1.0; PSKShapeTbl_M[i] = -1.0; PSKShapeTbl_PM[i] = cos((double) i * PI2 / (RampSize * 2)); PSKShapeTbl_MP[i] = -PSKShapeTbl_PM[i]; if (i < RampSize / 2) { PSKShapeTbl_PZ[i] = cos((double) i * PI2 / (RampSize * 2)); PSKShapeTbl_MZ[i] = -PSKShapeTbl_PZ[i]; PSKShapeTbl_ZP[i] = 0.0; } else { PSKShapeTbl_ZP[i] = -cos((double) i * PI2 / (RampSize * 2)); PSKShapeTbl_PZ[i] = 0.0; PSKShapeTbl_MZ[i] = 0.0; } } i = 0; while (i < 32) //create post/preamble tables { m_Preamble[i] = TXTOG_CODE; m_Postamble[i++] = TXON_CODE; } m_Preamble[i] = 0; // null terminate these tables m_Postamble[i] = 0; m_pPSKtxI = PSKShapeTbl_Z; m_pPSKtxQ = PSKShapeTbl_Z; m_PresentPhase = PHZ_OFF; m_TxShiftReg = 0; status = TX_PREAMBLE_STATE; } PSKModulator::~PSKModulator() { } ///////////++++++++++++++++++++++++++++++++++//////////////// /////////// P S K 3 1 M O D U L A T O R //////////////// ///////////++++++++++++++++++++++++++++++++++//////////////// ///////////////////////////////////////////////////////////// // generates n samples of psk31 waveform in data array pData ///////////////////////////////////////////////////////////// int PSKModulator::CalcSignal(double *pData, int n) { int symbol; int i; // m_RMSConstant = TX_CONSTANT; for (i = 0; i < n; i++) //calculate n samples of tx data stream { m_t += m_PSKPhaseInc; // increment radian phase count pData[i] = 0.45 * (m_pPSKtxI[m_Ramp] * sin(m_t) + m_pPSKtxQ[m_Ramp++] * cos(m_t)); m_PSKTime += m_PSKSecPerSamp; if (m_PSKTime >= m_PSKPeriodUpdate)//if time to update envelope ramp index { m_PSKTime -= m_PSKPeriodUpdate; //keep time bounded m_Ramp = 0; // time to update symbol m_t = fmod(m_t, PI2); //keep radian counter bounded if (status == TX_CWID_STATE) symbol = GetNextCWSymbol(); else symbol = GetNextSymbol(); //get new I/Q ramp tables and next phase m_pPSKtxI = PSKPhaseLookupTable[symbol][m_PresentPhase].iptr; m_pPSKtxQ = PSKPhaseLookupTable[symbol][m_PresentPhase].qptr; m_PresentPhase = PSKPhaseLookupTable[symbol][m_PresentPhase].next; } if (status == TX_END_STATE) // We have reached end of Transmission return -i; } return n; } ///////////////////////////////////////////////////////////// // called every symbol time to get next CW symbol and get the // next character from the character Queue if no more symbols // are left to send. ///////////////////////////////////////////////////////////// char PSKModulator::GetNextCWSymbol(void) { char symb; int ch; symb = m_Lastsymb; //use last symbol unless it needs to change if ((m_TxShiftReg == 0) && (m_CWState == 0)) { ch = GetChar(); //get next character to xmit if (ch >= 0) //if is not a control code { ch &= 0xFF; ch = (int) toupper((char) ch); //make upper case if (ch >= ' ' && ch <= 'Z') m_TxShiftReg = CW_TABLE[ ch - ' ']; //look up pattern } else // is a control code { if (ch == TXON_CODE) symb = SYM_ON; else symb = SYM_OFF; return symb; } m_CWState = 0; } switch (m_CWState) // CW timing state machine { case 0: //get next cw symbol state from pattern switch (m_TxShiftReg & 0xC000) { case 0x4000: //dot m_CWState = 1; m_CWtimer = 1 * CW_SPEED; symb = SYM_ON; break; case 0x8000: //dash m_CWState = 1; m_CWtimer = 3 * CW_SPEED; symb = SYM_ON; break; case 0xC000: //inter char space m_CWState = 2; m_CWtimer = 3 * CW_SPEED; symb = SYM_OFF; break; default: symb = SYM_OFF; break; } m_TxShiftReg = m_TxShiftReg << 2; // break; case 1: //On time state if (--m_CWtimer <= 0) { m_CWState = 2; m_CWtimer = 1 * CW_SPEED; //inter symbol time symb = SYM_OFF; } else symb = SYM_NOCHANGE; break; case 2: //Off time state if (--m_CWtimer <= 0) m_CWState = 0; break; } m_Lastsymb = symb; return symb; } ///////////////////////////////////////////////////////////// //get next character/symbol depending on TX state. ///////////////////////////////////////////////////////////// int PSKModulator::GetChar() { int ch; static int last = 0; switch (status) { case TX_OFF_STATE: //is receiving ch = TXOFF_CODE; //else turn off break; case TX_TUNE_STATE: ch = TXON_CODE; // steady carrier break; case TX_PAUSED_STATE: ch = TXTOG_CODE; // steady idle symbol break; case TX_POSTAMBLE_STATE: // ending sequence /// if( !(ch = m_Postamble[m_AmblePtr++] )) //m_Postamble is 0 terminated ch = m_Postamble[m_AmblePtr++]; if (ch == 0) //m_Postamble is 0 terminated { m_AmblePtr = 0; ch = TXOFF_CODE; status = TX_END_STATE; } break; case TX_PREAMBLE_STATE: //starting sequence if (!(ch = m_Preamble[m_AmblePtr++])) { status = TX_SENDING_STATE; m_AmblePtr = 0; ch = TXTOG_CODE; } break; case TX_CWID_STATE: // id sending CW ID /** if( m_AmblePtr >= settings.CWIdString.length() ) { m_AmblePtr = 0; ch = TXOFF_CODE; status = TX_END_STATE; } else ch = settings.CWIdString.at(m_AmblePtr++).cell(); **/ break; case TX_SENDING_STATE: //if sending text from TX window ch = Buffer->getTxChar(); if (ch > 0) { emit charSend((char) ch); m_AmblePtr = 0; } else if (ch == TXOFF_CODE) status = TX_POSTAMBLE_STATE; m_AmblePtr = 0; break; case TX_END_STATE: break; } last = ch; return ( ch); } linpsk/src/viterbisoft.cpp0000644000175000017500000006615711337745306016135 0ustar schroerschroer/*************************************************************************** viterbi.cpp - description ------------------- begin : Sam Mr 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 "viterbisoft.h" #include using namespace std; ViterbiSoft::ViterbiSoft ( const double ( *d ) ( double *, int ) ) { int i; dist = d; NumberofStates = NumberOfRTTYSampleStates; for ( i = 0; i < NumberofStates ; i++ ) { Metric[i] = 10000.; PathMem[i][0] = Stop16; // bitestimate[i][0] = Stop3; // bitestimate[i+NumberofStates][0]=Stop3; } Metric[Stop16] = 0.0; pathPointer = 1; /** Set State Table **/ StateTable[0][Start1] = Start2; StateTable[1][Start1] = Start2; // ?? StateTable[0][Start2] = Start3; StateTable[1][Start2]= Start3; StateTable[0][Start3]= Start4; StateTable[1][Start3]= Start4; StateTable[0][Start4]= Start5; StateTable[1][Start4]= Start5; StateTable[0][Start5]= Start6; StateTable[1][Start5]= Start6; StateTable[0][Start6]= Start7; StateTable[1][Start6]= Start7; StateTable[0][Start7]= Start8; StateTable[1][Start7]= Start8; StateTable[0][Start8]= Start9; StateTable[1][Start8]= Start9; StateTable[0][Start9]= Start10; StateTable[1][Start9]= Start10; StateTable[0][Start10]= Start11; StateTable[1][Start10]= Start11; StateTable[0][Start11] = D1_0_1; StateTable[1][Start11] = D1_1_1; StateTable[0][Stop1] = Stop2; // ?? StateTable[1][Stop1] = Stop2; StateTable[0][Stop2] = Stop3; // ?? StateTable[1][Stop2] = Stop3; StateTable[0][Stop3] = Stop4; StateTable[1][Stop3] = Stop4; StateTable[0][Stop4] = Stop5; StateTable[1][Stop4] = Stop5; StateTable[0][Stop5] = Stop6; StateTable[1][Stop5] = Stop6; StateTable[0][Stop6] = Stop7; StateTable[1][Stop6] = Stop7; StateTable[0][Stop7] = Stop8; StateTable[1][Stop7] = Stop8; StateTable[0][Stop8] = Stop9; StateTable[1][Stop8] = Stop9; StateTable[0][Stop9] = Stop10; StateTable[1][Stop9] = Stop10; StateTable[0][Stop10] = Stop11; StateTable[1][Stop10] = Stop11; StateTable[0][Stop11] = Stop12; StateTable[1][Stop11] = Stop12; StateTable[0][Stop12] = Stop13; StateTable[1][Stop12] = Stop13; StateTable[0][Stop13] = Stop14; StateTable[1][Stop13] = Stop14; StateTable[0][Stop14] = Stop15; StateTable[1][Stop14] = Stop15; StateTable[0][Stop15] = Stop16; StateTable[1][Stop15] = Stop16; StateTable[0][Stop16] = Start1; StateTable[1][Stop16] = Stop16; StateTable[0][D1_0_1] = D1_0_2; StateTable[1][D1_0_1] = D1_0_2; //?? StateTable[0][D1_0_2] = D1_0_3; StateTable[1][D1_0_2] = D1_0_3; StateTable[0][D1_0_3] = D1_0_4; StateTable[1][D1_0_3] = D1_0_4; StateTable[0][D1_0_4] = D1_0_5; StateTable[1][D1_0_4] = D1_0_5; StateTable[0][D1_0_5] = D1_0_6; StateTable[1][D1_0_5] = D1_0_6; StateTable[0][D1_0_6] = D1_0_7; StateTable[1][D1_0_6] = D1_0_7; StateTable[0][D1_0_7] = D1_0_8; StateTable[1][D1_0_7] = D1_0_8; StateTable[0][D1_0_8] = D1_0_9; StateTable[1][D1_0_8] = D1_0_9; StateTable[0][D1_0_9] = D1_0_10; StateTable[1][D1_0_9] = D1_0_10; StateTable[0][D1_0_10] = D1_0_11; StateTable[1][D1_0_10] = D1_0_11; StateTable[0][D1_0_11] = D2_0_1; StateTable[1][D1_0_11] = D2_1_1; StateTable[0][D1_1_1] = D1_1_2; StateTable[1][D1_1_1] = D1_1_2; StateTable[0][D1_1_2] = D1_1_3; StateTable[1][D1_1_2] = D1_1_3; StateTable[0][D1_1_3] = D1_1_4; StateTable[1][D1_1_3] = D1_1_4; StateTable[0][D1_1_4] = D1_1_5; StateTable[1][D1_1_4] = D1_1_5; StateTable[0][D1_1_5] = D1_1_6; StateTable[1][D1_1_5] = D1_1_6; StateTable[0][D1_1_6] = D1_1_7; StateTable[1][D1_1_6] = D1_1_7; StateTable[0][D1_1_7] = D1_1_8; StateTable[1][D1_1_7] = D1_1_8; StateTable[0][D1_1_8] = D1_1_9; StateTable[1][D1_1_8] = D1_1_9; StateTable[0][D1_1_9] = D1_1_10; StateTable[1][D1_1_9] = D1_1_10; StateTable[0][D1_1_10] = D1_1_11; StateTable[1][D1_1_10] = D1_1_11; StateTable[0][D1_1_11] = D2_0_1; StateTable[1][D1_1_11] = D2_1_1; StateTable[0][D2_0_1] = D2_0_2; StateTable[1][D2_0_1] = D2_0_2; StateTable[0][D2_0_2] = D2_0_3; StateTable[1][D2_0_2] = D2_0_3; StateTable[0][D2_0_3] = D2_0_4; StateTable[1][D2_0_3] = D2_0_4; StateTable[0][D2_0_4] = D2_0_5; StateTable[1][D2_0_4] = D2_0_5; StateTable[0][D2_0_5] = D2_0_6; StateTable[1][D2_0_5] = D2_0_6; StateTable[0][D2_0_6] = D2_0_7; StateTable[1][D2_0_6] = D2_0_7; StateTable[0][D2_0_7] = D2_0_8; StateTable[1][D2_0_7] = D2_0_8; StateTable[0][D2_0_8] = D2_0_9; StateTable[1][D2_0_8] = D2_0_9; StateTable[0][D2_0_9] = D2_0_10; StateTable[1][D2_0_9] = D2_0_10; StateTable[0][D2_0_10] = D2_0_11; StateTable[1][D2_0_10] = D2_0_11; StateTable[0][D2_0_11] = D3_0_1; StateTable[1][D2_0_11] = D3_1_1; StateTable[0][D2_1_1] = D2_1_2; StateTable[1][D2_1_1] = D2_1_2; StateTable[0][D2_1_2] = D2_1_3; StateTable[1][D2_1_2] = D2_1_3; StateTable[0][D2_1_3] = D2_1_4; StateTable[1][D2_1_3] = D2_1_4; StateTable[0][D2_1_4] = D2_1_5; StateTable[1][D2_1_4] = D2_1_5; StateTable[0][D2_1_5] = D2_1_6; StateTable[1][D2_1_5] = D2_1_6; StateTable[0][D2_1_6] = D2_1_7; StateTable[1][D2_1_6] = D2_1_7; StateTable[0][D2_1_7] = D2_1_8; StateTable[1][D2_1_7] = D2_1_8; StateTable[0][D2_1_8] = D2_1_9; StateTable[1][D2_1_8] = D2_1_9; StateTable[0][D2_1_9] = D2_1_10; StateTable[1][D2_1_9] = D2_1_10; StateTable[0][D2_1_10] = D2_1_11; StateTable[1][D2_1_10] = D2_1_11; StateTable[0][D2_1_11] = D3_0_1; StateTable[1][D2_1_11] = D3_1_1; StateTable[0][D3_0_1] = D3_0_2; StateTable[1][D3_0_1] = D3_0_2; // ?? StateTable[0][D3_0_2] = D3_0_3; StateTable[1][D3_0_2] = D3_0_3; StateTable[0][D3_0_3] = D3_0_4; StateTable[1][D3_0_3] = D3_0_4; StateTable[0][D3_0_4] = D3_0_5; StateTable[1][D3_0_4] = D3_0_5; StateTable[0][D3_0_5] = D3_0_6; StateTable[1][D3_0_5] = D3_0_6; StateTable[0][D3_0_6] = D3_0_7; StateTable[1][D3_0_6] = D3_0_7; StateTable[0][D3_0_7] = D3_0_8; StateTable[1][D3_0_7] = D3_0_8; StateTable[0][D3_0_8] = D3_0_9; StateTable[1][D3_0_8] = D3_0_9; StateTable[0][D3_0_9] = D3_0_10; StateTable[1][D3_0_9] = D3_0_10; StateTable[0][D3_0_10] = D3_0_11; StateTable[1][D3_0_10] = D3_0_11; StateTable[0][D3_0_11] = D4_0_1; // ?? StateTable[1][D3_0_11] = D4_1_1; StateTable[0][D3_1_1] = D3_1_2; StateTable[1][D3_1_1] = D3_1_2; StateTable[0][D3_1_2] = D3_1_3; StateTable[1][D3_1_2] = D3_1_3; StateTable[0][D3_1_3] = D3_1_4; StateTable[1][D3_1_3] = D3_1_4; StateTable[0][D3_1_4] = D3_1_5; StateTable[1][D3_1_4] = D3_1_5; StateTable[0][D3_1_5] = D3_1_6; StateTable[1][D3_1_5] = D3_1_6; StateTable[0][D3_1_6] = D3_1_7; StateTable[1][D3_1_6] = D3_1_7; StateTable[0][D3_1_7] = D3_1_8; StateTable[1][D3_1_7] = D3_1_8; StateTable[0][D3_1_8] = D3_1_9; StateTable[1][D3_1_8] = D3_1_9; StateTable[0][D3_1_9] = D3_1_10; StateTable[1][D3_1_9] = D3_1_10; StateTable[0][D3_1_10] = D3_1_11; StateTable[1][D3_1_10] = D3_1_11; StateTable[0][D3_1_11] = D4_0_1; StateTable[1][D3_1_11] = D4_1_1; StateTable[0][D4_0_1] = D4_0_2; StateTable[1][D4_0_1] = D4_0_2; // ?? StateTable[0][D4_0_2] = D4_0_3; StateTable[1][D4_0_2] = D4_0_3; StateTable[0][D4_0_3] = D4_0_4; StateTable[1][D4_0_3] = D4_0_4; StateTable[0][D4_0_4] = D4_0_5; StateTable[1][D4_0_4] = D4_0_5; StateTable[0][D4_0_5] = D4_0_6; StateTable[1][D4_0_5] = D4_0_6; StateTable[0][D4_0_6] = D4_0_7; StateTable[1][D4_0_6] = D4_0_7; StateTable[0][D4_0_7] = D4_0_8; StateTable[1][D4_0_7] = D4_0_8; StateTable[0][D4_0_8] = D4_0_9; StateTable[1][D4_0_8] = D4_0_9; StateTable[0][D4_0_9] = D4_0_10; StateTable[1][D4_0_9] = D4_0_10; StateTable[0][D4_0_10] = D4_0_11; StateTable[1][D4_0_10] = D4_0_11; StateTable[0][D4_0_11] = D5_0_1; StateTable[1][D4_0_11] = D5_1_1; StateTable[0][D4_1_1] = D4_1_2; // ?? StateTable[1][D4_1_1] = D4_1_2; StateTable[0][D4_1_2] = D4_1_3; StateTable[1][D4_1_2] = D4_1_3; StateTable[0][D4_1_3] = D4_1_4; StateTable[1][D4_1_3] = D4_1_4; StateTable[0][D4_1_4] = D4_1_5; StateTable[1][D4_1_4] = D4_1_5; StateTable[0][D4_1_5] = D4_1_6; StateTable[1][D4_1_5] = D4_1_6; StateTable[0][D4_1_6] = D4_1_7; StateTable[1][D4_1_6] = D4_1_7; StateTable[0][D4_1_7] = D4_1_8; StateTable[1][D4_1_7] = D4_1_8; StateTable[0][D4_1_8] = D4_1_9; StateTable[1][D4_1_8] = D4_1_9; StateTable[0][D4_1_9] = D4_1_10; StateTable[1][D4_1_9] = D4_1_10; StateTable[0][D4_1_10] = D4_1_11; StateTable[1][D4_1_10] = D4_1_11; StateTable[0][D4_1_11] = D5_0_1; StateTable[1][D4_1_11] = D5_1_1; StateTable[0][D5_0_1] = D5_0_2; StateTable[1][D5_0_1] = D5_0_2; // ?? StateTable[0][D5_0_2] = D5_0_3; StateTable[1][D5_0_2] = D5_0_3; StateTable[0][D5_0_3] = D5_0_4; StateTable[1][D5_0_3] = D5_0_4; StateTable[0][D5_0_4] = D5_0_5; StateTable[1][D5_0_4] = D5_0_5; StateTable[0][D5_0_5] = D5_0_6; StateTable[1][D5_0_5] = D5_0_6; StateTable[0][D5_0_6] = D5_0_7; StateTable[1][D5_0_6] = D5_0_7; StateTable[0][D5_0_7] = D5_0_8; StateTable[1][D5_0_7] = D5_0_8; StateTable[0][D5_0_8] = D5_0_9; StateTable[1][D5_0_8] = D5_0_9; StateTable[0][D5_0_9] = D5_0_10; StateTable[1][D5_0_9] = D5_0_10; StateTable[0][D5_0_10] = D5_0_11; StateTable[1][D5_0_10] = D5_0_11; StateTable[0][D5_0_11] = D6_0_1; // ?? StateTable[1][D5_0_11] = D6_1_1; StateTable[0][D5_1_1] = D5_1_2; // ?? StateTable[1][D5_1_1] = D5_1_2; StateTable[0][D5_1_2] = D5_1_3; StateTable[1][D5_1_2] = D5_1_3; StateTable[0][D5_1_3] = D5_1_4; StateTable[1][D5_1_3] = D5_1_4; StateTable[0][D5_1_4] = D5_1_5; StateTable[1][D5_1_4] = D5_1_5; StateTable[0][D5_1_5] = D5_1_6; StateTable[1][D5_1_5] = D5_1_6; StateTable[0][D5_1_6] = D5_1_7; StateTable[1][D5_1_6] = D5_1_7; StateTable[0][D5_1_7] = D5_1_8; StateTable[1][D5_1_7] = D5_1_8; StateTable[0][D5_1_8] = D5_1_9; StateTable[1][D5_1_8] = D5_1_9; StateTable[0][D5_1_9] = D5_1_10; StateTable[1][D5_1_9] = D5_1_10; StateTable[0][D5_1_10] = D5_1_11; StateTable[1][D5_1_10] = D5_1_11; StateTable[0][D5_1_11] = D6_0_1; // ?? StateTable[1][D5_1_11] = D6_1_1; StateTable[0][D6_0_1] = D6_0_2; StateTable[1][D6_0_1] = D6_0_2; // ?? StateTable[0][D6_0_2] = D6_0_3; StateTable[1][D6_0_2] = D6_0_3; StateTable[0][D6_0_3] = D6_0_4; StateTable[1][D6_0_3] = D6_0_4; StateTable[0][D6_0_4] = D6_0_5; StateTable[1][D6_0_4] = D6_0_5; StateTable[0][D6_0_5] = D6_0_6; StateTable[1][D6_0_5] = D6_0_6; StateTable[0][D6_0_6] = D6_0_7; StateTable[1][D6_0_6] = D6_0_7; StateTable[0][D6_0_7] = D6_0_8; StateTable[1][D6_0_7] = D6_0_8; StateTable[0][D6_0_8] = D6_0_9; StateTable[1][D6_0_8] = D6_0_9; StateTable[0][D6_0_9] = D6_0_10; StateTable[1][D6_0_9] = D6_0_10; StateTable[0][D6_0_10] = D6_0_11; StateTable[1][D6_0_10] = D6_0_11; StateTable[0][D6_0_11] = D7_0_1; // ?? StateTable[1][D6_0_11] = D7_1_1; StateTable[0][D6_1_1] = D6_1_2; // ?? StateTable[1][D6_1_1] = D6_1_2; StateTable[0][D6_1_2] = D6_1_3; StateTable[1][D6_1_2] = D6_1_3; StateTable[0][D6_1_3] = D6_1_4; StateTable[1][D6_1_3] = D6_1_4; StateTable[0][D6_1_4] = D6_1_5; StateTable[1][D6_1_4] = D6_1_5; StateTable[0][D6_1_5] = D6_1_6; StateTable[1][D6_1_5] = D6_1_6; StateTable[0][D6_1_6] = D6_1_7; StateTable[1][D6_1_6] = D6_1_7; StateTable[0][D6_1_7] = D6_1_8; StateTable[1][D6_1_7] = D6_1_8; StateTable[0][D6_1_8] = D6_1_9; StateTable[1][D6_1_8] = D6_1_9; StateTable[0][D6_1_9] = D6_1_10; StateTable[1][D6_1_9] = D6_1_10; StateTable[0][D6_1_10] = D6_1_11; StateTable[1][D6_1_10] = D6_1_11; StateTable[0][D6_1_11] = D7_0_1; // ?? StateTable[1][D6_1_11] = D7_1_1; StateTable[0][D7_0_1] = D7_0_2; StateTable[1][D7_0_1] = D7_0_2; // ?? StateTable[0][D7_0_2] = D7_0_3; StateTable[1][D7_0_2] = D7_0_3; StateTable[0][D7_0_3] = D7_0_4; StateTable[1][D7_0_3] = D7_0_4; StateTable[0][D7_0_4] = D7_0_5; StateTable[1][D7_0_4] = D7_0_5; StateTable[0][D7_0_5] = D7_0_6; StateTable[1][D7_0_5] = D7_0_6; StateTable[0][D7_0_6] = D7_0_7; StateTable[1][D7_0_6] = D7_0_7; StateTable[0][D7_0_7] = D7_0_8; StateTable[1][D7_0_7] = D7_0_8; StateTable[0][D7_0_8] = D7_0_9; StateTable[1][D7_0_8] = D7_0_9; StateTable[0][D7_0_9] = D7_0_10; StateTable[1][D7_0_9] = D7_0_10; StateTable[0][D7_0_10] = D7_0_11; StateTable[1][D7_0_10] = D7_0_11; StateTable[0][D7_0_11] = D8_0_1; // ?? StateTable[1][D7_0_11] = D8_1_1; StateTable[0][D7_1_1] = D7_1_2; // ?? StateTable[1][D7_1_1] = D7_1_2; StateTable[0][D7_1_2] = D7_1_3; StateTable[1][D7_1_2] = D7_1_3; StateTable[0][D7_1_3] = D7_1_4; StateTable[1][D7_1_3] = D7_1_4; StateTable[0][D7_1_4] = D7_1_5; StateTable[1][D7_1_4] = D7_1_5; StateTable[0][D7_1_5] = D7_1_6; StateTable[1][D7_1_5] = D7_1_6; StateTable[0][D7_1_6] = D7_1_7; StateTable[1][D7_1_6] = D7_1_7; StateTable[0][D7_1_7] = D7_1_8; StateTable[1][D7_1_7] = D7_1_8; StateTable[0][D7_1_8] = D7_1_9; StateTable[1][D7_1_8] = D7_1_9; StateTable[0][D7_1_9] = D7_1_10; StateTable[1][D7_1_9] = D7_1_10; StateTable[0][D7_1_10] = D7_1_11; StateTable[1][D7_1_10] = D7_1_11; StateTable[0][D7_1_11] = D8_0_1; // ?? StateTable[1][D7_1_11] = D8_1_1; StateTable[0][D8_0_1] = D8_0_2; StateTable[1][D8_0_1] = D8_0_2; // ?? StateTable[0][D8_0_2] = D8_0_3; StateTable[1][D8_0_2] = D8_0_3; StateTable[0][D8_0_3] = D8_0_4; StateTable[1][D8_0_3] = D8_0_4; StateTable[0][D8_0_4] = D8_0_5; StateTable[1][D8_0_4] = D8_0_5; StateTable[0][D8_0_5] = D8_0_6; StateTable[1][D8_0_5] = D8_0_6; StateTable[0][D8_0_6] = D8_0_7; StateTable[1][D8_0_6] = D8_0_7; StateTable[0][D8_0_7] = D8_0_8; StateTable[1][D8_0_7] = D8_0_8; StateTable[0][D8_0_8] = D8_0_9; StateTable[1][D8_0_8] = D8_0_9; StateTable[0][D8_0_9] = D8_0_10; StateTable[1][D8_0_9] = D8_0_10; StateTable[0][D8_0_10] = D8_0_11; StateTable[1][D8_0_10] = D8_0_11; StateTable[0][D8_0_11] = D9_0_1; // ?? StateTable[1][D8_0_11] = D9_1_1; StateTable[0][D8_1_1] = D8_1_2; // ?? StateTable[1][D8_1_1] = D8_1_2; StateTable[0][D8_1_2] = D8_1_3; StateTable[1][D8_1_2] = D8_1_3; StateTable[0][D8_1_3] = D8_1_4; StateTable[1][D8_1_3] = D8_1_4; StateTable[0][D8_1_4] = D8_1_5; StateTable[1][D8_1_4] = D8_1_5; StateTable[0][D8_1_5] = D8_1_6; StateTable[1][D8_1_5] = D8_1_6; StateTable[0][D8_1_6] = D8_1_7; StateTable[1][D8_1_6] = D8_1_7; StateTable[0][D8_1_7] = D8_1_8; StateTable[1][D8_1_7] = D8_1_8; StateTable[0][D8_1_8] = D8_1_9; StateTable[1][D8_1_8] = D8_1_9; StateTable[0][D8_1_9] = D8_1_10; StateTable[1][D8_1_9] = D8_1_10; StateTable[0][D8_1_10] = D8_1_11; StateTable[1][D8_1_10] = D8_1_11; StateTable[0][D8_1_11] = D9_0_1; // ?? StateTable[1][D8_1_11] = D9_1_1; StateTable[0][D9_0_1] = D9_0_2; StateTable[1][D9_0_1] = D9_0_2; // ?? StateTable[0][D9_0_2] = D9_0_3; StateTable[1][D9_0_2] = D9_0_3; StateTable[0][D9_0_3] = D9_0_4; StateTable[1][D9_0_3] = D9_0_4; StateTable[0][D9_0_4] = D9_0_5; StateTable[1][D9_0_4] = D9_0_5; StateTable[0][D9_0_5] = D9_0_6; StateTable[1][D9_0_5] = D9_0_6; StateTable[0][D9_0_6] = D9_0_7; StateTable[1][D9_0_6] = D9_0_7; StateTable[0][D9_0_7] = D9_0_8; StateTable[1][D9_0_7] = D9_0_8; StateTable[0][D9_0_8] = D9_0_9; StateTable[1][D9_0_8] = D9_0_9; StateTable[0][D9_0_9] = D9_0_10; StateTable[1][D9_0_9] = D9_0_10; StateTable[0][D9_0_10] = D9_0_11; StateTable[1][D9_0_10] = D9_0_11; StateTable[0][D9_0_11] = D10_0_1; // ?? StateTable[1][D9_0_11] = D10_1_1; StateTable[0][D9_1_1] = D9_1_2; // ?? StateTable[1][D9_1_1] = D9_1_2; StateTable[0][D9_1_2] = D9_1_3; StateTable[1][D9_1_2] = D9_1_3; StateTable[0][D9_1_3] = D9_1_4; StateTable[1][D9_1_3] = D9_1_4; StateTable[0][D9_1_4] = D9_1_5; StateTable[1][D9_1_4] = D9_1_5; StateTable[0][D9_1_5] = D9_1_6; StateTable[1][D9_1_5] = D9_1_6; StateTable[0][D9_1_6] = D9_1_7; StateTable[1][D9_1_6] = D9_1_7; StateTable[0][D9_1_7] = D9_1_8; StateTable[1][D9_1_7] = D9_1_8; StateTable[0][D9_1_8] = D9_1_9; StateTable[1][D9_1_8] = D9_1_9; StateTable[0][D9_1_9] = D9_1_10; StateTable[1][D9_1_9] = D9_1_10; StateTable[0][D9_1_10] = D9_1_11; StateTable[1][D9_1_10] = D9_1_11; StateTable[0][D9_1_11] = D10_0_1; // ?? StateTable[1][D9_1_11] = D10_1_1; StateTable[0][D10_0_1] = D10_0_2; StateTable[1][D10_0_1] = D10_0_2; // ?? StateTable[0][D10_0_2] = D10_0_3; StateTable[1][D10_0_2] = D10_0_3; StateTable[0][D10_0_3] = D10_0_4; StateTable[1][D10_0_3] = D10_0_4; StateTable[0][D10_0_4] = D10_0_5; StateTable[1][D10_0_4] = D10_0_5; StateTable[0][D10_0_5] = D10_0_6; StateTable[1][D10_0_5] = D10_0_6; StateTable[0][D10_0_6] = D10_0_7; StateTable[1][D10_0_6] = D10_0_7; StateTable[0][D10_0_7] = D10_0_8; StateTable[1][D10_0_7] = D10_0_8; StateTable[0][D10_0_8] = D10_0_9; StateTable[1][D10_0_8] = D10_0_9; StateTable[0][D10_0_9] = D10_0_10; StateTable[1][D10_0_9] = D10_0_10; StateTable[0][D10_0_10] = D10_0_11; StateTable[1][D10_0_10] = D10_0_11; StateTable[0][D10_0_11] = D11_0_1; // ?? StateTable[1][D10_0_11] = D11_1_1; StateTable[0][D10_1_1] = D10_1_2; // ?? StateTable[1][D10_1_1] = D10_1_2; StateTable[0][D10_1_2] = D10_1_3; StateTable[1][D10_1_2] = D10_1_3; StateTable[0][D10_1_3] = D10_1_4; StateTable[1][D10_1_3] = D10_1_4; StateTable[0][D10_1_4] = D10_1_5; StateTable[1][D10_1_4] = D10_1_5; StateTable[0][D10_1_5] = D10_1_6; StateTable[1][D10_1_5] = D10_1_6; StateTable[0][D10_1_6] = D10_1_7; StateTable[1][D10_1_6] = D10_1_7; StateTable[0][D10_1_7] = D10_1_8; StateTable[1][D10_1_7] = D10_1_8; StateTable[0][D10_1_8] = D10_1_9; StateTable[1][D10_1_8] = D10_1_9; StateTable[0][D10_1_9] = D10_1_10; StateTable[1][D10_1_9] = D10_1_10; StateTable[0][D10_1_10] = D10_1_11; StateTable[1][D10_1_10] = D10_1_11; StateTable[0][D10_1_11] = D11_0_1; // ?? StateTable[1][D10_1_11] = D11_1_1; StateTable[0][D11_0_1] = D11_0_2; StateTable[1][D11_0_1] = D11_0_2; // ?? StateTable[0][D11_0_2] = D11_0_3; StateTable[1][D11_0_2] = D11_0_3; StateTable[0][D11_0_3] = D11_0_4; StateTable[1][D11_0_3] = D11_0_4; StateTable[0][D11_0_4] = D11_0_5; StateTable[1][D11_0_4] = D11_0_5; StateTable[0][D11_0_5] = D11_0_6; StateTable[1][D11_0_5] = D11_0_6; StateTable[0][D11_0_6] = D11_0_7; StateTable[1][D11_0_6] = D11_0_7; StateTable[0][D11_0_7] = D11_0_8; StateTable[1][D11_0_7] = D11_0_8; StateTable[0][D11_0_8] = D11_0_9; StateTable[1][D11_0_8] = D11_0_9; StateTable[0][D11_0_9] = D11_0_10; StateTable[1][D11_0_9] = D11_0_10; StateTable[0][D11_0_10] = D11_0_11; StateTable[1][D11_0_10] = D11_0_11; StateTable[0][D11_0_11] = Stop1; // ?? StateTable[1][D11_0_11] = Stop1; StateTable[0][D11_1_1] = D11_1_2; // ?? StateTable[1][D11_1_1] = D11_1_2; StateTable[0][D11_1_2] = D11_1_3; StateTable[1][D11_1_2] = D11_1_3; StateTable[0][D11_1_3] = D11_1_4; StateTable[1][D11_1_3] = D11_1_4; StateTable[0][D11_1_4] = D11_1_5; StateTable[1][D11_1_4] = D11_1_5; StateTable[0][D11_1_5] = D11_1_6; StateTable[1][D11_1_5] = D11_1_6; StateTable[0][D11_1_6] = D11_1_7; StateTable[1][D11_1_6] = D11_1_7; StateTable[0][D11_1_7] = D11_1_8; StateTable[1][D11_1_7] = D11_1_8; StateTable[0][D11_1_8] = D11_1_9; StateTable[1][D11_1_8] = D11_1_9; StateTable[0][D11_1_9] = D11_1_10; StateTable[1][D11_1_9] = D11_1_10; StateTable[0][D11_1_10] = D11_1_11; StateTable[1][D11_1_10] = D11_1_11; StateTable[0][D11_1_11] = Stop1; // ?? StateTable[1][D11_1_11] = Stop1; BitCount = 0; // StopBitCount = SAMPLESPERSTOPBIT; BitTable[Start1] = 0; BitTable[Start2] = 0; BitTable[Start3]=0; BitTable[Start4]=0; BitTable[Start5]=0; BitTable[Start6]=0; BitTable[Start7]=0; BitTable[Start8]=0; BitTable[Start9]=0; BitTable[Start10]=0; BitTable[Start11]=0; BitTable[ Stop1] = 1; BitTable[Stop2] = 1; BitTable[Stop3] = 1; BitTable[Stop4] = 1; BitTable[Stop5] = 1; BitTable[Stop6] = 1; BitTable[Stop7] = 1; BitTable[Stop8] = 1; BitTable[Stop9] = 1; BitTable[Stop10] = 1; BitTable[Stop11] = 1; BitTable[Stop12] = 1; BitTable[Stop13] = 1; BitTable[Stop14] = 1; BitTable[Stop15] = 1; BitTable[Stop16] = 1; BitTable[ D1_0_1] = 0; BitTable[D1_0_2] = 0; BitTable[D1_0_3] = 0; BitTable[D1_0_4] = 0; BitTable[D1_0_5] = 0; BitTable[D1_0_6] = 0; BitTable[D1_0_7] = 0; BitTable[D1_0_8] = 0; BitTable[D1_0_9] = 0; BitTable[D1_0_10] = 0; BitTable[D1_0_11] = 0; BitTable[ D1_1_1] = 1; BitTable[D1_1_2] = 1; BitTable[ D1_1_3] = 1; BitTable[ D1_1_4] = 1; BitTable[ D1_1_5] = 1; BitTable[ D1_1_6] = 1; BitTable[ D1_1_7] = 1; BitTable[ D1_1_8] = 1; BitTable[ D1_1_9] = 1; BitTable[ D1_1_10] = 1; BitTable[ D1_1_11] = 1; BitTable[ D2_0_1] = 0; BitTable[D2_0_2] = 0; BitTable[D2_0_3] = 0; BitTable[D2_0_4] = 0; BitTable[D2_0_5] = 0; BitTable[D2_0_6] = 0; BitTable[D2_0_7] = 0; BitTable[D2_0_8] = 0; BitTable[D2_0_9] = 0; BitTable[D2_0_10] = 0; BitTable[D2_0_11] = 0; BitTable[ D2_1_1] = 1; BitTable[D2_1_2] = 1; BitTable[D2_1_3] = 1; BitTable[D2_1_4] = 1; BitTable[D2_1_5] = 1; BitTable[D2_1_6] = 1; BitTable[D2_1_7] = 1; BitTable[D2_1_8] = 1; BitTable[D2_1_9] = 1; BitTable[D2_1_10] = 1; BitTable[D2_1_11] = 1; BitTable[ D3_0_1] = 0; BitTable[D3_0_2] = 0; BitTable[D3_0_3] = 0; BitTable[D3_0_4] = 0; BitTable[D3_0_5] = 0; BitTable[D3_0_6] = 0; BitTable[D3_0_7] = 0; BitTable[D3_0_8] = 0; BitTable[D3_0_9] = 0; BitTable[D3_0_10] = 0; BitTable[D3_0_11] = 0; BitTable[ D3_1_1] = 1; BitTable[D3_1_2] = 1; BitTable[D3_1_3] = 1; BitTable[D3_1_4] = 1; BitTable[D3_1_5] = 1; BitTable[D3_1_6] = 1; BitTable[D3_1_7] = 1; BitTable[D3_1_8] = 1; BitTable[D3_1_9] = 1; BitTable[D3_1_10] = 1; BitTable[D3_1_11] = 1; BitTable[D4_0_1] = 0; BitTable[D4_0_2] = 0; BitTable[D4_0_3] = 0; BitTable[D4_0_4] = 0; BitTable[D4_0_5] = 0; BitTable[D4_0_6] = 0; BitTable[D4_0_7] = 0; BitTable[D4_0_8] = 0; BitTable[D4_0_9] = 0; BitTable[D4_0_10] = 0; BitTable[D4_0_11] = 0; BitTable[ D4_1_1] = 1; BitTable[D4_1_2] = 1; BitTable[D4_1_3] = 1; BitTable[D4_1_4] = 1; BitTable[D4_1_5] = 1; BitTable[D4_1_6] = 1; BitTable[D4_1_7] = 1; BitTable[D4_1_8] = 1; BitTable[D4_1_9] = 1; BitTable[D4_1_10] = 1; BitTable[D4_1_11] = 1; BitTable[ D5_0_1] = 0; BitTable[D5_0_2] = 0; BitTable[D5_0_3] = 0; BitTable[D5_0_4] = 0; BitTable[D5_0_5] = 0; BitTable[D5_0_6] = 0; BitTable[D5_0_7] = 0; BitTable[D5_0_8] = 0; BitTable[D5_0_9] = 0; BitTable[D5_0_10] = 0; BitTable[D5_0_11] = 0; BitTable[ D5_1_1] = 1; BitTable[D5_1_2] = 1; BitTable[D5_1_3] = 1; BitTable[D5_1_4] = 1; BitTable[D5_1_5] = 1; BitTable[D5_1_6] = 1; BitTable[D5_1_7] = 1; BitTable[D5_1_8] = 1; BitTable[D5_1_9] = 1; BitTable[D5_1_10] = 1; BitTable[D5_1_11] = 1; BitTable[ D6_0_1] = 0; BitTable[D6_0_2] = 0; BitTable[D6_0_3] = 0; BitTable[D6_0_4] = 0; BitTable[D6_0_5] = 0; BitTable[D6_0_6] = 0; BitTable[D6_0_7] = 0; BitTable[D6_0_8] = 0; BitTable[D6_0_9] = 0; BitTable[D6_0_10] = 0; BitTable[D6_0_11] = 0; BitTable[ D6_1_1] = 1; BitTable[D6_1_2] = 1; BitTable[D6_1_3] = 1; BitTable[D6_1_4] = 1; BitTable[D6_1_5] = 1; BitTable[D6_1_6] = 1; BitTable[D6_1_7] = 1; BitTable[D6_1_8] = 1; BitTable[D6_1_9] = 1; BitTable[D6_1_10] = 1; BitTable[D6_1_11] = 1; BitTable[ D7_0_1] = 0; BitTable[D7_0_2] = 0; BitTable[D7_0_3] = 0; BitTable[D7_0_4] = 0; BitTable[D7_0_5] = 0; BitTable[D7_0_6] = 0; BitTable[D7_0_7] = 0; BitTable[D7_0_8] = 0; BitTable[D7_0_9] = 0; BitTable[D7_0_10] = 0; BitTable[D7_0_11] = 0; BitTable[ D7_1_1] = 1; BitTable[D7_1_2] = 1; BitTable[D7_1_3] = 1; BitTable[D7_1_4] = 1; BitTable[D7_1_5] = 1; BitTable[D7_1_6] = 1; BitTable[D7_1_7] = 1; BitTable[D7_1_8] = 1; BitTable[D7_1_9] = 1; BitTable[D7_1_10] = 1; BitTable[D7_1_11] = 1; BitTable[ D8_0_1] = 0; BitTable[D8_0_2] = 0; BitTable[D8_0_3] = 0; BitTable[D8_0_4] = 0; BitTable[D8_0_5] = 0; BitTable[D8_0_6] = 0; BitTable[D8_0_7] = 0; BitTable[D8_0_8] = 0; BitTable[D8_0_9] = 0; BitTable[D8_0_10] = 0; BitTable[D8_0_11] = 0; BitTable[ D8_1_1] = 1; BitTable[D8_1_2] = 1; BitTable[D8_1_3] = 1; BitTable[D8_1_4] = 1; BitTable[D8_1_5] = 1; BitTable[D8_1_6] = 1; BitTable[D8_1_7] = 1; BitTable[D8_1_8] = 1; BitTable[D8_1_9] = 1; BitTable[D8_1_10] = 1; BitTable[D8_1_11] = 1; BitTable[ D9_0_1] = 0; BitTable[D9_0_2] = 0; BitTable[D9_0_3] = 0; BitTable[D9_0_4] = 0; BitTable[D9_0_5] = 0; BitTable[D9_0_6] = 0; BitTable[D9_0_7] = 0; BitTable[D9_0_8] = 0; BitTable[D9_0_9] = 0; BitTable[D9_0_10] = 0; BitTable[D9_0_11] = 0; BitTable[ D9_1_1] = 1; BitTable[D9_1_2] = 1; BitTable[D9_1_3] = 1; BitTable[D9_1_4] = 1; BitTable[D9_1_5] = 1; BitTable[D9_1_6] = 1; BitTable[D9_1_7] = 1; BitTable[D9_1_8] = 1; BitTable[D9_1_9] = 1; BitTable[D9_1_10] = 1; BitTable[D9_1_11] = 1; BitTable[ D10_0_1] = 0; BitTable[D10_0_2] = 0; BitTable[D10_0_3] = 0; BitTable[D10_0_4] = 0; BitTable[D10_0_5] = 0; BitTable[D10_0_6] = 0; BitTable[D10_0_7] = 0; BitTable[D10_0_8] = 0; BitTable[D10_0_9] = 0; BitTable[D10_0_10] = 0; BitTable[D10_0_11] = 0; BitTable[ D10_1_1] = 1; BitTable[D10_1_2] = 1; BitTable[D10_1_3] = 1; BitTable[D10_1_4] = 1; BitTable[D10_1_5] = 1; BitTable[D10_1_6] = 1; BitTable[D10_1_7] = 1; BitTable[D10_1_8] = 1; BitTable[D10_1_9] = 1; BitTable[D10_1_10] = 1; BitTable[D10_1_11] = 1; BitTable[ D11_0_1] = 0; BitTable[D11_0_2] = 0; BitTable[D11_0_3] = 0; BitTable[D11_0_4] = 0; BitTable[D11_0_5] = 0; BitTable[D11_0_6] = 0; BitTable[D11_0_7] = 0; BitTable[D11_0_8] = 0; BitTable[D11_0_9] = 0; BitTable[D11_0_10] = 0; BitTable[D11_0_11] = 0; BitTable[ D11_1_1] = 1; BitTable[D11_1_2] = 1; BitTable[D11_1_3] = 1; BitTable[D11_1_4] = 1; BitTable[D11_1_5] = 1; BitTable[D11_1_6] = 1; BitTable[D11_1_7] = 1; BitTable[D11_1_8] = 1; BitTable[D11_1_9] = 1; BitTable[D11_1_10] = 1; BitTable[D11_1_11] = 1; } ViterbiSoft::~ViterbiSoft() {} void ViterbiSoft::decode ( double dibit[2] ) { double min; int i, k; min = 1.0E99; MinimumPath = 0; double d[2]; d[0] = dibit[0]; d[1] = dibit[1]; double x; RTTYSampleStates s; double distance[2*NumberOfRTTYSampleStates]; RTTYSampleStates bitestimate[2*NumberOfRTTYSampleStates][MEMORYLENGTH]; for ( i = 0;i < 2*NumberOfRTTYSampleStates;i++ ) distance[i] = 10000.; for ( i = 0; i < NumberofStates; i++ ) { for ( int j = 0; j < 2;j++ ) { s = StateTable[j][i]; // x = Metric[i] + ( *dist ) ( dibit,BitTable[StateTable[j][i]] ); x = Metric[i] + ( *dist ) ( dibit, j ); if ( x < distance[s+j*NumberofStates] ) { distance[s+j*NumberofStates] = x; if ( x < min ) { min = x; MinimumPath = s; } for ( k = 0;k < MEMORYLENGTH;k++ ) bitestimate[s+j*NumberofStates][k] = PathMem[i][k]; bitestimate[s+j*NumberofStates][pathPointer] = StateTable[j][i]; } } } for ( i = 0;i < NumberofStates ;i++ ) { if ( distance[i] < distance[i+NumberofStates] ) { Metric[i] = distance[i] - min; for ( k = 0;k < MEMORYLENGTH;k++ ) PathMem[i][k] = bitestimate[i][k]; } else { Metric[i] = distance[NumberofStates+i] - min; for ( k = 0;k < MEMORYLENGTH;k++ ) PathMem[i][k] = bitestimate[NumberofStates+i][k]; } } pathPointer = ( pathPointer + 1 ) % MEMORYLENGTH; } int ViterbiSoft::getBit ( unsigned int i ) { int pos; pos = ( pathPointer + 127 - i ) % MEMORYLENGTH; return ( BitTable[ PathMem[MinimumPath][pos]] ); } ViterbiSoft::RTTYSampleStates ViterbiSoft::getState(unsigned int i) { int pos; pos = ( pathPointer + 127 - i ) % MEMORYLENGTH; return ( PathMem[MinimumPath][pos] ); } linpsk/src/parameter.cpp0000644000175000017500000000305311337745306015537 0ustar schroerschroer/*************************************************************************** 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 MinimumWindowWidth=640; MinimumWindowHeight=555; callsign=""; QslData=0; serial=-1; // Serial none SerialDevice="none"; QSOFileName="QSOData.adif"; timeoffset=-2; DemoMode=true; DemoModeFileType[0]="*.wav"; DemoModeFileType[1]="*.out"; DemoTypeNumber=0; slashed0=false; RxChannels=1; ActChannel = 0; // Pointer to the active Channel ChannelChain = 0; // Pointer to the Start of the Rx - ChannelChain ApplicationFont =0; autoCrLf=true; } Parameter::~Parameter() { } linpsk/src/bpskmodulator.h0000644000175000017500000000244311337745306016114 0ustar schroerschroer/*************************************************************************** bpskmodulator.h - description ------------------- begin : Mon Feb 24 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 BPSKMODULATOR_H #define BPSKMODULATOR_H #include "pskmodulator.h" class CTxBuffer; /** *@author Volker Schroer */ class BPSKModulator : public PSKModulator { public: BPSKModulator(int, double, CTxBuffer *); ~BPSKModulator(); char GetNextSymbol(void); }; #endif linpsk/src/main.cpp0000644000175000017500000000253711337745306014511 0ustar schroerschroer/*************************************************************************** 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/src/controlpanel.h0000644000175000017500000000112711337745306015724 0ustar schroerschroer #ifndef CONTROLPANEL_H #define CONTROLPANEL_H #include #include #include #include using namespace std; class SpectrumDisplay; class QSOData; class MacroWindow; class Macros; class ControlPanel : public QFrame { Q_OBJECT public: ControlPanel(Macros *M, QWidget* parent = 0); ~ControlPanel(); SpectrumDisplay* Display; QSOData *QSO; MacroWindow *MacroBox; protected: void resizeEvent( QResizeEvent * ); public slots: protected slots: private: void calculateSizeofComponents(); }; #endif // CONTROLPANEL_H linpsk/src/fskmodulator.cpp0000644000175000017500000000350211337745306016270 0ustar schroerschroer/*************************************************************************** fskmodulator.cpp - description ------------------- begin : Sam Mr 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/src/bpskmodulator.cpp0000644000175000017500000000503411337745306016446 0ustar schroerschroer/*************************************************************************** bpskmodulator.cpp - description ------------------- begin : Mon Feb 24 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 "bpskmodulator.h" #include "constants.h" #define SYM_NOCHANGE 0 //Stay the same phase #define SYM_P180 2 //Plus 180 deg #define SYM_OFF 4 //No output #define SYM_ON 5 //constant output BPSKModulator::BPSKModulator ( int FS, double freq, CTxBuffer *TxBuffer ) : PSKModulator ( FS, freq, TxBuffer ) { } BPSKModulator::~BPSKModulator() { } char BPSKModulator::GetNextSymbol ( void ) { char symb; int ch; symb = m_Lastsymb; if ( m_TxShiftReg == 0 ) { if ( m_AddEndingZero ) // if is end of code { symb = SYM_P180; // end with a zero m_AddEndingZero = false; } else { ch = GetChar(); //get next character to xmit if ( ch >= 0 ) //if is not a control code { //get next VARICODE codeword to send m_TxShiftReg = VARICODE_TABLE[ ch&0xFF ]; symb = SYM_P180; //Start with a zero } else // is a control code { switch ( ch ) { case TXON_CODE: symb = SYM_ON; break; case TXTOG_CODE: symb = SYM_P180; break; case TXOFF_CODE: symb = SYM_OFF; break; } } } } else // is not end of code word so send next bit { if ( m_TxShiftReg&0x8000 ) symb = SYM_NOCHANGE; else symb = SYM_P180; m_TxShiftReg = m_TxShiftReg << 1; //point to next bit if ( m_TxShiftReg == 0 ) // if at end of codeword m_AddEndingZero = true; // need to send a zero nextime } m_Lastsymb = symb; return symb; } linpsk/src/ctxdisplay.cpp0000644000175000017500000000653011337745306015746 0ustar schroerschroer/*************************************************************************** |FILENAME| - description ------------------- begin : |DATE| copyright : (C) |YEAR| by |AUTHOR| email : |EMAIL| ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #include "ctxdisplay.h" #include "cledbutton.h" #include "ctxwindow.h" #include "frequencyselect.h" /* * Constructs a CTxDisplay which is a child of 'parent', with the * name 'name'.' */ CTxDisplay::CTxDisplay( QWidget* parent ) : QFrame( parent) { setMinimumSize( QSize( 540, 96 ) ); setBaseSize( QSize( 540, 96 ) ); setFrameShape( QFrame::Panel ); setFrameShadow( QFrame::Sunken ); TxWindow = new CTxWindow( this ); TxFreq = new FrequencySelect( this ); TxFreq->setFunctionText("Net"); TxFreq->setTitle("Tx Freq"); TxFreq->setAfcDisplayMode(Narrow); TxFreq->setAfcMode(Narrow); // TxFunctions = new CTxFunctions( "Rx / Tx", this ); TxFunctions =new CLedButton(this); connect(TxFunctions,SIGNAL(startRx()),this,SIGNAL(startRx())); connect(TxFunctions,SIGNAL(startTx()),this,SIGNAL(startTx())); TxFunctions->setGeometry( QRect( 100, 20, 51, 71 ) ); languageChange(); } /* * Destroys the object and frees any allocated resources */ CTxDisplay::~CTxDisplay() { // no need to delete child widgets, Qt does it all for us } /* * Sets the strings of the subwidgets using the current * language. */ void CTxDisplay::languageChange() { } void CTxDisplay::calculateSizeofComponents() { /** in percent of whole widget **/ /** TX Function part **/ #define TXFUNCTIONWIDTH 10 /** TxFrequency (Width) **/ #define TXFREQWIDTH 18 #define TXFREQHEIGHT 70 /** Left and Right Margin **/ #define LEFTANDRIGHTMARGIN 1 /** Top and Bottom Margin **/ #define TOPANDBOTTOMMARGIN 2 /** Inner distance **/ #define distance 1 int xpos,ypos,width,height,innerheight,innerwidth; width=this->width(); height=this->height(); xpos=width*LEFTANDRIGHTMARGIN/100; /** Frequency select Box **/ innerheight=height*TXFREQHEIGHT/100; ypos=(height-innerheight)/2; innerwidth=width*TXFREQWIDTH/100; TxFreq->setGeometry(xpos,ypos,innerwidth,innerheight); /** TX- Functions **/ //ypos=height*TOPANDBOTTOMMARGIN/100; //innerheight=height-2*ypos; innerheight=height*TXFREQHEIGHT/100; xpos=xpos+innerwidth+width*distance/100; innerwidth=width*TXFUNCTIONWIDTH/100; TxFunctions->setGeometry(xpos,ypos,innerwidth,innerheight); /** TX- Window **/ xpos=xpos+innerwidth+width*distance/100; innerwidth=width-xpos-width*LEFTANDRIGHTMARGIN/100; TxWindow->setGeometry(xpos,ypos,innerwidth,innerheight); } void CTxDisplay::resizeEvent( QResizeEvent * ) { calculateSizeofComponents(); } void CTxDisplay::abbruch() { TxFunctions->setStatus(UNDEF); } linpsk/src/cdemodulator.h0000644000175000017500000000510711337745306015710 0ustar schroerschroer/*************************************************************************** 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 #include #include #include #include "constants.h" /**Base class for all possible types of demodulators *@author Volker Schroer */ class CDemodulator : public QObject { Q_OBJECT public: CDemodulator(); virtual ~CDemodulator(); /** processes the input */ virtual void ProcessInput(double *input, double *spectrum) = 0; /** gets the selected frequency */ virtual double getRxFrequency(void); virtual double get2RxFrequency(void); /** Initialises something */ virtual bool Init(double,int) = 0; virtual std::complex *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/src/crecording.h0000644000175000017500000000261311337745306015344 0ustar schroerschroer/*************************************************************************** |FILENAME| - description ------------------- begin : |DATE| copyright : (C) |YEAR| by |AUTHOR| email : |EMAIL| ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * The PSK part is based on WinPSK 1.0 by Moe Wheatley, AE4JY * ***************************************************************************/ #ifndef CRECORDING_H #define CRECORDING_H #include class QRadioButton; class CRecording : public QGroupBox { Q_OBJECT public: CRecording( QWidget* parent = 0); ~CRecording(); QRadioButton* Record; public slots: protected: void resizeEvent( QResizeEvent * ); protected slots: virtual void languageChange(); private: void calculateSizeofComponents(); }; #endif // CRECORDING_H linpsk/src/src.pro0000644000175000017500000000410411337745306014362 0ustar schroerschroerSOURCES += linpsk.cpp \ main.cpp \ macros.cpp \ macrowindow.cpp \ bpskdemodulator.cpp \ bpskmodulator.cpp \ cdemodulator.cpp \ cledbutton.cpp \ cmodulator.cpp \ controlpanel.cpp \ cpskdemodulator.cpp \ crecording.cpp \ crxchannel.cpp \ crxdisplay.cpp \ crxwindow.cpp \ csound.cpp \ csquelch.cpp \ ctrigger.cpp \ ctxbuffer.cpp \ ctxdisplay.cpp \ ctxwindow.cpp \ deinterleaver.cpp \ feccoder.cpp \ firfilter.cpp \ frequencyselect.cpp \ fskmodulator.cpp \ input.cpp \ interleaver.cpp \ mfskdemodulator.cpp \ mfskmodulator.cpp \ mfskvaricode.cpp \ parameter.cpp \ pskmodulator.cpp \ qpskdemodulator.cpp \ qpskmodulator.cpp \ rttydemodulator.cpp \ rttymodulator.cpp \ textinput.cpp \ viterbi.cpp \ waveinput.cpp \ spectrumdisplay.cpp \ readonlystringlistmodel.cpp \ processlogdata.cpp HEADERS += linpsk.h \ bpskdemodulator.h \ bpskmodulator.h \ cdemodulator.h \ cledbutton.h \ cmodulator.h \ color.h \ constants.h \ controlpanel.h \ cpskdemodulator.h \ crecording.h \ crxchannel.h \ crxdisplay.h \ crxwindow.h \ csound.h \ csquelch.h \ ctrigger.h \ ctxbuffer.h \ ctxdisplay.h \ ctxwindow.h \ deinterleaver.h \ feccoder.h \ fircoeffs.h \ firfilter.h \ frequencyselect.h \ input.h \ interleaver.h \ macros.h \ macrowindow.h \ mfskdemodulator.h \ mfskmodulator.h \ mfskvaricode.h \ parameter.h \ pskmodulator.h \ psktable.h \ qpskdemodulator.h \ qpskmodulator.h \ rttydemodulator.h \ rttymodulator.h \ textinput.h \ viterbi.h \ waveinput.h \ spectrumdisplay.h \ readonlystringlistmodel.h \ fskmodulator.h \ processlogdata.h TEMPLATE = app CONFIG += warn_on \ thread \ qt \ debug TARGET = ../bin/linpsk RESOURCES = application.qrc DESTDIR = . QMAKE_CXXFLAGS_DEBUG += -g3 \ -O0 QMAKE_CXXFLAGS_RELEASE += -O2 QT += network INCLUDEPATH += ../gui LIBS += ../gui/libgui.a \ -L/usr/lib64 \ -L/usr/lib \ -lasound \ -lfftw3 TARGETDEPS += ../gui/libgui.a DISTFILES += ../README ../COPYING \ ../ChangeLog \ ../asoundrc \ ../images/linpsk.png INSTALLS += target target.path = /usr/local/bin CONFIG -= debug linpsk/src/processlogdata.cpp0000644000175000017500000001156011337745306016573 0ustar schroerschroer/*************************************************************************** * 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; } ProcessLogData::~ProcessLogData() { } void ProcessLogData::saveQsoData ( QString s ) { qDebug ( "Request save" ); requestType = Save; actionString = s; doAction(); } void ProcessLogData::requestCallSign ( QLabel **r, QString s ) { qDebug ( "Request Callsign" ); requestType = Request; actionString.clear(); actionString.append ( "@@@@" ); actionString.append ( s ); actionString.append ( "\r\n" ); for ( int i = 0; i < 6;i++ ) results[i] = r[i]; doAction(); } void ProcessLogData::run() { connectionEstablished = false; connectionError = false; qRegisterMetaType ( "QAbstractSocket::SocketError" ); tcpSocket = new QTcpSocket(); connect ( tcpSocket, SIGNAL ( disconnected() ), this, SLOT ( connectionClosedbyHost() ) ); connect ( tcpSocket, SIGNAL ( readyRead() ), this, SLOT ( readAnswer() ) ); connect ( tcpSocket, SIGNAL ( connected() ), this, SLOT ( setConnected() ) ); connect ( tcpSocket, SIGNAL ( error ( QAbstractSocket::SocketError ) ), this, SLOT ( setError ( QAbstractSocket::SocketError ) ) ); tcpSocket->connectToHost ( QHostAddress::LocalHost, 8080, QIODevice::ReadWrite ); exec(); } void ProcessLogData::doAction() { if ( !connectionEstablished ) usleep ( 6000 ); if ( !connectionEstablished && tcpSocket->state() != 3) { qDebug ( "Waiting for Socket timed out: %d",tcpSocket->state() ); QMessageBox::StandardButton reply; reply = QMessageBox::question ( 0, "LinPSK", tr ( "Cannot connect to LinLogBook\nTry again later ?" ), QMessageBox::Yes | QMessageBox::No ); if ( reply == QMessageBox::No ) emit unabletoConnect(); if ( tcpSocket != 0 ) delete tcpSocket; tcpSocket = 0; exit(); return; } // if ( tcpSocket->state() != QAbstractSocket::ConnectedState ) // usleep ( 500 ); qDebug ( "SocketError %d", tcpSocket->state() ); if ( tcpSocket->state() == QAbstractSocket::UnconnectedState ) { QMessageBox::information ( 0, "LinPSK", tr ( "Cannot connect to LinLogBook" ) ); return; } int n = tcpSocket->write ( actionString.toLatin1(), actionString.length() ); qDebug ( "Written %d, to be written %d", n, actionString.length() ); if ( n < 0 ) // Retry { usleep ( 100 ); n = tcpSocket->write ( actionString.toLatin1(), actionString.length() ); qDebug ( "Written %d, to be written %d", n, actionString.length() ); } tcpSocket->flush(); } void ProcessLogData::connectionClosedbyHost() { connectionEstablished = false; if ( tcpSocket != 0 ) delete tcpSocket; tcpSocket = 0; quit(); } void ProcessLogData::readAnswer() { qDebug ( "Read Answer" ); //Has to be improved, to get safer QString s; int i; for ( i = 0; i < 6; i++ ) { while ( ! tcpSocket->canReadLine() ) usleep ( 100 ); s = QLatin1String ( tcpSocket->readLine() ); s.remove ( QLatin1Char ( '\n' ) ); results[i]->setText ( s ); results[i]->show(); } qDebug ( "%d Zeilen gelesen", i ); emit answerAvailable(); } void ProcessLogData::setConnected() { connectionEstablished = true; } void ProcessLogData::setError ( QAbstractSocket::SocketError ) { connectionEstablished = false; connectionError = true; if ( tcpSocket != 0 ) qDebug ( "SocketError %d", tcpSocket->state() ); } linpsk/src/viterbi.h0000644000175000017500000000300211337745306014662 0ustar schroerschroer/*************************************************************************** viterbi.h - description ------------------- begin : Sam Mr 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 encode(int); void decode(double *); int getbit(unsigned int i); int getbitinvers(unsigned int i); private: unsigned *StateTable; long long int *PathMem; double *Metric; double * distance; long long int * bitestimate; int NumberofStates; int MinimumPath; unsigned int CoderState; const double (*dist)(double *,int); }; #endif linpsk/src/bpskdemodulator.cpp0000644000175000017500000000603711337745306016763 0ustar schroerschroer/*************************************************************************** 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" BPskDemodulator::BPskDemodulator():CPskDemodulator() { ave1=1.0; ave2=1.0; } BPskDemodulator::~BPskDemodulator(){ } void BPskDemodulator::DecodeSymbol(double angle) { bool bit; char ch =0; CalcQuality(angle); bit = GetBPSKSymb(); if( (bit==0) && m_LastBitZero ) //if character delimiter { if(m_BitAcc != 0 ) { m_BitAcc >>= 2; //get rid of last zero and one m_BitAcc &= 0x07FF; ch = m_VaricodeDecTbl[m_BitAcc]; m_BitAcc = 0; if( (ch!=0) && ( !Squelch || (Squelch && (fastSquelch || ( ( unsigned int ) m_DevAve > Threshold ))))) // Squelch Part { emit newSymbol(ch); if (fastSquelch && (( unsigned int ) m_DevAve < Threshold) ) fastSquelch = false; } } } else { m_BitAcc <<= 1; m_BitAcc |= bit; if(bit==0) m_LastBitZero = true; else m_LastBitZero = false; } if (bit) { m_OffCount=0; if (m_OnCount++ >20) fastSquelch=true; } else { m_OnCount=0; if (m_OffCount++ > 20) fastSquelch=false; } } bool BPskDemodulator::GetBPSKSymb() { return (Phase_Vector.real()> 0.0); } ////////////////////////////////////////////////////////////////////// // Calculate signal quality based on the statistics of the phase // difference angle. The more dispersion of the "0" and "180" degree // phase shifts, the worse the signal quality. This information is used // to activate the squelch control. If 20 consecutive "180" degree shifts // occur, the squelch is forced on, and if 20 consecutive "0" degree // shifts occur, the squelch is forced off quickly. ////////////////////////////////////////////////////////////////////// void BPskDemodulator::CalcQuality( double angle ) { double temp; if ( fabs(angle) < M_PI_2) temp= angle; else { if ( angle > 0.0) temp=angle-M_PI; else temp = M_PI+ angle; } m_QFreqError = -temp; temp = fabs(temp); m_DevAve =0.5 * ave1 + 0.45 * ave2 + 0.05 *temp; ave2=ave1; ave1=m_DevAve; // And now norm m_DevAve for use in Squelch m_DevAve = 100. -m_DevAve *63.67; } linpsk/src/crxwindow.cpp0000644000175000017500000001727211337745306015613 0ustar schroerschroer/*************************************************************************** crxwindow.cpp - description ------------------- begin : Mon Mar 6 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. * ***************************************************************************/ #include "crxwindow.h" #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(); DisplayBox = new QWidget ( this ); DisplayBox->setFixedSize ( 642, RXWINDOWBUFFER*rowHeight ); DisplayBox->setContextMenuPolicy ( Qt::CustomContextMenu ); connect ( DisplayBox, SIGNAL ( customContextMenuRequested ( QPoint ) ), this, SLOT ( contextMenu ( QPoint ) ) ); setWidget ( DisplayBox ); setHorizontalScrollBarPolicy ( Qt::ScrollBarAlwaysOff ); setVerticalScrollBarPolicy ( Qt::ScrollBarAlwaysOn ); trigger = false; TriggerText = ""; TexttoTrigger = ""; save = false; stream = 0; Row = 0; Column = 0; AutoScroll = true; DisplayLineHeight = rowHeight - 2; for ( int i = 0;i < RXWINDOWBUFFER;i++ ) { ScrollBuffer[i] = new QLineEdit ( DisplayBox ); ScrollBuffer[i]->move ( 1, 1 + DisplayLineHeight*i ); ScrollBuffer[i]->setFrame ( false ); ScrollBuffer[i]->setReadOnly ( true ); ScrollBuffer[i]->setFixedHeight ( rowHeight ); ScrollBuffer[i]->setContextMenuPolicy ( Qt::NoContextMenu ); ScrollBuffer[i]->show(); } setBackgroundRole ( ScrollBuffer[0]->backgroundRole() ); menu = new QMenu ( tr ( "Log value" ), DisplayBox ); QAction *A = menu->addAction ( tr ( "Callsign" ) ); connect ( A, SIGNAL ( triggered() ), this, SLOT ( copyCallSign() ) ); A = menu->addAction ( "QTH" ); connect ( A, SIGNAL ( triggered() ), this, SLOT ( copyQTH() ) ); A = menu->addAction ( "Name" ); connect ( A, SIGNAL ( triggered() ), this, SLOT ( copyName() ) ); A = menu->addAction ( tr ( "Locator" ) ); connect ( A, SIGNAL ( triggered() ), this, SLOT ( copyLocator() ) ); A = menu->addAction ( "Raport" ); connect ( A, SIGNAL ( triggered() ), this, SLOT ( copyRST() ) ); selectedString.clear(); } /* * Destroys the object and frees any allocated resources */ CRxWindow::~CRxWindow() { for ( int i = 0;i < RXWINDOWBUFFER;i++ ) { if ( ScrollBuffer[i] ) delete ScrollBuffer[i]; ScrollBuffer[i] = 0; } // no need to delete child widgets, Qt does it all for us } void CRxWindow::updateRx ( char c ) { switch ( c ) { case '\n': case '\r': NeueZeile(); break; case '\b': if ( Column > 0 ) { Column--; QString s = ScrollBuffer[Row]->text(); s.truncate ( Column ); ScrollBuffer[Row]->setText ( s ); if ( trigger && ( settings.Status == OFF ) ) { if ( TriggerText.length() > 0 ) TriggerText.remove ( TriggerText.length(), 1 ); } } break; case '0': if ( settings.slashed0 ) c = 0xF8; default: if ( trigger && ( settings.Status == OFF ) ) { TriggerText.append ( c ); if ( TriggerText.length() > TexttoTrigger.length() ) { TriggerText.remove ( 0, 1 ); if ( TriggerText.toLower() == TexttoTrigger.toLower() ) { trigger = false; // Stop emit Triggered(); } } } QString s = ScrollBuffer[Row]->text() + QString ( QChar ( c ) ); ScrollBuffer[Row]->setText ( s ); Column++; if ( Column >= 80 ) NeueZeile(); } } void CRxWindow::clearRxWindow() { Column = 0; Row = 0; for ( int i = 0;i < RXWINDOWBUFFER;i++ ) ScrollBuffer[i]->setText ( "" ); ensureVisible ( 0, Row*rowHeight, 20, 15 ); } void CRxWindow::removeLines ( int number2Remove ) { int i; for ( i = number2Remove; i < RXWINDOWBUFFER; i++ ) ScrollBuffer[i-number2Remove]->setText ( ScrollBuffer[i]->text() ); for ( i = RXWINDOWBUFFER - number2Remove;i < RXWINDOWBUFFER;i++ ) ScrollBuffer[i]->setText ( "" ); } void CRxWindow::NeueZeile() { Column = 0; Row++; if ( Row >= RXWINDOWBUFFER ) { if ( save && stream != 0 ) for ( int i = 0;i < 10; i++ ) *stream << ScrollBuffer[i]->text() << "\n"; removeLines ( 10 ); Row -= 10; } if ( ! AutoScroll ) return; // ensureVisible ( 0, Row*rowHeight, 20, 15 ); ensureWidgetVisible ( ( QWidget* ) ScrollBuffer[Row] ); } void CRxWindow::setColor ( QColor color ) { for ( int i = 0;i < RXWINDOWBUFFER;i++ ) ScrollBuffer[i]->setStyleSheet ( "QLineEdit{color: " + color.name() + "; }" ); } void CRxWindow::fontChange ( const QFont & ) { QFontMetrics fm ( font() ); for ( int i = 0;i < RXWINDOWBUFFER;i++ ) ScrollBuffer[i]->setFixedHeight ( fm.height() ); } void CRxWindow::activateTrigger ( QString s ) { trigger = true; TexttoTrigger = s; TriggerText = ""; } void CRxWindow::deactivateTrigger() { trigger = false; } bool CRxWindow::getTriggerStatus() { return trigger; } QString CRxWindow::getTriggerText() { return TexttoTrigger; } void CRxWindow::stopRecording() { /** Save all ScrollBuffer in Buffer **/ if ( save ) { for ( int i = 0; i <= Row; i++ ) *stream << ScrollBuffer[i]->text() << "\n"; File.close(); save = false; delete stream; } } void CRxWindow::startRecording ( QString Datei ) { if ( !save ) { File.setFileName ( Datei ); File.open ( QIODevice::WriteOnly ); save = true; stream = new QTextStream ( &File ); } } bool CRxWindow::getRecordingState() { return save; } void CRxWindow::resizeEvent ( QResizeEvent * ) { int width = this->width(); DisplayBox->setFixedWidth ( width );; for ( int i = 0;i < RXWINDOWBUFFER;i++ ) ScrollBuffer[i]->setFixedWidth ( width ); } void CRxWindow::contextMenu ( QPoint p ) { int selectedLine, selectedColumn; char c = 0xF8; QPoint p1 = QCursor::pos(); selectedLine = p.y() / DisplayLineHeight; selectedColumn = ScrollBuffer[selectedLine]->cursorPositionAt ( QPoint ( p.x(), 2 ) ); ScrollBuffer[selectedLine]->setCursorPosition ( selectedColumn ); ScrollBuffer[selectedLine]->cursorWordForward ( true ); selectedString = ScrollBuffer[selectedLine]->selectedText(); selectedString = selectedString.replace ( QChar ( c ), QLatin1String ( "0" ) ); // Replace Slashed zero by zero if ( selectedString == QString ( " " ) ) { ScrollBuffer[selectedLine]->setCursorPosition ( selectedColumn + 1 ); ScrollBuffer[selectedLine]->cursorWordForward ( true ); selectedString = ScrollBuffer[selectedLine]->selectedText(); } qDebug ( "Copy %s", qPrintable ( selectedString ) ); menu->exec ( p1 ); } void CRxWindow::copyCallSign() { emit copyCallSign ( selectedString ); } void CRxWindow::copyQTH() { emit copyQTH ( selectedString ); } void CRxWindow::copyName() { emit copyName ( selectedString ); } void CRxWindow::copyLocator() { emit copyLocator ( selectedString ); } void CRxWindow::copyRST() { emit copyRST ( selectedString ); } linpsk/src/rttydemodulator.h0000644000175000017500000000724711337745306016477 0ustar schroerschroer/*************************************************************************** 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(); bool Init(double,int); virtual double get2RxFrequency(); virtual void setParameter(RxTxParameterType,void * ); virtual void *getParameter(RxTxParameterType); virtual void *getBuffer(); AfcMode AfcProperties(); void setFilter(double freq, double bandwidth); void execFilter(); void downmix(complex *,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/src/crxdisplay.h0000644000175000017500000000606711337745306015416 0ustar schroerschroer/*************************************************************************** |FILENAME| - description ------------------- begin : |DATE| copyright : (C) |YEAR| by |AUTHOR| email : |EMAIL| ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * The PSK part is based on WinPSK 1.0 by Moe Wheatley, AE4JY * ***************************************************************************/ #ifndef CRXDISPLAY_H #define CRXDISPLAY_H #include "constants.h" #include #include #include #include "constants.h" class QTabBar; class CRecording; class CRxChannel; class CSquelch; class CTrigger; class FrequencySelect; class CRxWindow; class Input; class QTimer; class QPushButton; class CRxDisplay : public QFrame { Q_OBJECT public: CRxDisplay ( QWidget* parent = 0 ); ~CRxDisplay(); /** Returns the pointer to the values for Calculating the Spectrum **/ double * FFTValues(); bool start_process_loop(); void stop_process_loop(); void newColor(); FrequencySelect* RxFreq; CRecording* Recording; CTrigger* Trigger; CSquelch* Squelch; void setColorList ( QList * ); QTabBar* RxHeader; public slots: /** Starting receiving/transmitting */ void addRxWindow ( int Frequency, Mode Modulation, QString Heading ); void setRxFrequency ( double ); protected: virtual void resizeEvent ( QResizeEvent * ); protected slots: virtual void languageChange(); void process_rxdata(); void changeActiveRxWindow ( int ); void trigger(); void clearRxWindow(); private: void calculateSizeofComponents(); QList *Farbe; /** Sound is a pointer to the Input Source, may be a File with Demo Samples (text or wav), or the soundcard ( /dev/audio ) **/ Input *Sound; QPushButton *Clear; /** Pointer to input Buffer **/ // double *inbuf; double inbuf[BUF_SIZE]; CRxChannel *RxChannel; /** Decimation Filter to reduce samplerate */ void ProcDec2Fir ( double *pIn, double *pOut, int BlockSize ); double *dec2fir; // queue for decimation by 2 filter // double *outbuf; // outputbuffer double outbuf[BUF_SIZE]; double *m_pDec2InPtr; /** Timer ** for polling the soundcard **/ //QTimer *RxTimer; //fftw_real* output; double output[BUF_SIZE/2]; fftw_plan plan; signals: void startPlotting ( double *, bool ); void newActiveChannel(); void new_IMD ( float ); void copyCallSign(QString); void copyQTH(QString); void copyName(QString); void copyLocator(QString); void copyRST(QString); }; #endif // CRXDISPLAY_H linpsk/src/qpskmodulator.h0000644000175000017500000000251511337745306016133 0ustar schroerschroer/*************************************************************************** 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 GetNextSymbol(void); private: unsigned short int m_TxCodeWord; }; #endif linpsk/src/controlpanel.cpp0000644000175000017500000000343611337745306016264 0ustar schroerschroer #include "controlpanel.h" #include #include #include #include #include #include #include "spectrumdisplay.h" #include "qsodata.h" #include "macrowindow.h" /* * Constructs a ControlPanel which is a child of 'parent', with the * name 'name'.' */ ControlPanel::ControlPanel(Macros *Macro, QWidget* parent) : QFrame( parent ) { setFrameShape( QFrame::StyledPanel ); setFrameShadow( QFrame::Sunken ); Display = new SpectrumDisplay( this ); QSO = new QSOData(this); MacroBox = new MacroWindow(Macro,this); } /* * Destroys the object and frees any allocated resources */ ControlPanel::~ControlPanel() { if(QSO) delete QSO; QSO=0; // no need to delete child widgets, Qt does it all for us } /* * Sets the strings of the subwidgets using the current * language. */ void ControlPanel::calculateSizeofComponents() { #define TOPMARGIN 2 #define LEFTMARGIN 1 #define SPECTRUMWIDTH 35 #define SPECTRUMHEIGHT 85 #define QSODATAWIDTH 45 #define MACROBOXWIDTH 17 int xpos,ypos,width,height,innerheight,innerwidth,innerwidthqso,innerwidthmacros; width=this->width(); height=this->height(); xpos=width*LEFTMARGIN/100; ypos=height*TOPMARGIN/100; innerwidth=(width-xpos)*SPECTRUMWIDTH/100; innerwidthqso=(width-xpos)*QSODATAWIDTH/100; innerwidthmacros=(width-xpos)*MACROBOXWIDTH/100; innerheight=((height-2*ypos)*SPECTRUMHEIGHT)/100; Display->setGeometry(xpos,ypos,innerwidth,innerheight); xpos=xpos+innerwidth+10; innerheight=(height*(100-2*TOPMARGIN))/100; QSO->setGeometry(xpos,ypos,innerwidthqso,innerheight); xpos = xpos+innerwidthqso+10; MacroBox->setGeometry(xpos,ypos,innerwidthmacros,innerheight); MacroBox->show(); } void ControlPanel::resizeEvent( QResizeEvent * ) { calculateSizeofComponents(); } linpsk/src/cdemodulator.cpp0000644000175000017500000000424011337745306016240 0ustar schroerschroer/*************************************************************************** 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; } CDemodulator::~CDemodulator() { } void CDemodulator::setAfcMode(AfcMode afc) { UseAfc=afc; } void CDemodulator::setRxFrequency(double freq) { if ( (freq > 200 ) && (freq < 3000 ) ) RxFrequency = freq; else { printf("Invalid Frequency %f\n",freq); return; } } double CDemodulator::getRxFrequency(void) { return RxFrequency; } void CDemodulator::setThreshold(int value) { Threshold= value; } void CDemodulator::setSquelch(bool OnOff) { Squelch=OnOff; } AfcMode CDemodulator::getAfcMode() { return UseAfc; } bool CDemodulator::getSquelchState() { return Squelch; } std::complex * CDemodulator::getPhasePointer() { return 0; } int CDemodulator::getThreshold() { return Threshold; } double CDemodulator::get2RxFrequency(void) { return 0.0; } float CDemodulator::getIMD() { return 0.0; } void CDemodulator::setParameter(RxTxParameterType,void *) { /** * At the moment only RTTY uses some extra Parameters * So there is mostly nothing to do * but that may change in the future **/ return; } void *CDemodulator::getParameter(RxTxParameterType) { return 0; } void *CDemodulator::getBuffer() { return 0; } linpsk/src/spectrumdisplay.h0000644000175000017500000000471011337745306016455 0ustar schroerschroer/*************************************************************************** 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 #include using namespace std; class QRadioButton; class QSpinBox; class QPixmap; class QWidget; /** *@author Volker Schroer */ class SpectrumDisplay : public QFrame { Q_OBJECT public: SpectrumDisplay( QWidget* parent = 0); ~SpectrumDisplay(); void setColorList(QList *c); void mousePressEvent(QMouseEvent *); public slots: void startPlot(double *,bool); void setPhasePointer(std::complex *); protected: void resizeEvent( QResizeEvent * ); void paintEvent(QPaintEvent *); protected slots: virtual void languageChange(); void setnewFrequency(int); private: void calculateSizeofComponents(); QSpinBox* MaxFreq; QSpinBox* MinFreq; QRadioButton *Smooth; void plotspectrum(bool); /** Pointer to the Input for the FFT **/ double *inputdata; complex *Phase; void translate(void); void paintLineal(QPainter* ,int,int); void plotVector(QPainter *p); /** Results of FFT */ void calcFFT(); int fftdata[1024]; // Not all elements are used, it differs int xtranslate[1024]; // depending on the display width float smoothedfft[1024]; // Pointer to the different Colors QList *Farbe; QPixmap pdisplay; // Pixmap for Display for double buffering QPixmap pwaterfall; // Pixmap for Waterfall Display //QPixmap *pellipse; // Pixmap for crossed ellipse in RTTY(2) Mode signals: void FrequencyChanged(double); void frequencyChanged(int); }; #endif linpsk/src/cpskdemodulator.h0000644000175000017500000000577111337745306016435 0ustar schroerschroer/*************************************************************************** cpskdemodulator.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 CPSKDEMODULATOR_H #define CPSKDEMODULATOR_H using namespace std; #include "constants.h" #include #include #include #include "cdemodulator.h" class CPskDemodulator : public CDemodulator { Q_OBJECT public: CPskDemodulator(); virtual ~CPskDemodulator(); bool Init(double Fs ,int BlockSize); int getSquelchValue(); void ProcessInput( double *pIn, double *Spectrum); complex * getPhasePointer(); virtual float getIMD(); AfcMode AfcProperties(); protected: // Methods /** Decodes the symbol depending on the PskModes */ virtual void DecodeSymbol( double) = 0; /** Calculates the Cuality of the signal -- depends on the mode */ virtual void CalcQuality( double angle ) = 0; // Variables complex Prev_Sample; complex Phase_Vector; int m_BitAcc; bool m_LastBitZero; unsigned char* m_VaricodeDecTbl; int m_OnCount; int m_OffCount; double m_FreqError; double m_QFreqError; double m_DevAve; bool fastSquelch; private: int m_ClkErrTimer; int m_ClkErrCounter; int m_ClkError; //methods bool SymbSync(complex ); void CalcBitFilter( complex); double CalcAGC( complex ); double CalcFreqError(complex); void calcIMD(double *Spectrum); //variables double m_QPSKprob[4]; int m_LastPkPos; int m_SampCnt; bool m_DispTrig; float m_BitPhaseInc; float m_BitPhasePos; // float m_SyncAve[21]; complex DelayLine[40]; float m_SignalLevel; complex* m_pQue1; complex* m_pQue2; complex* m_pQue3; complex* m_pInPtr1; complex* m_pInPtr2; complex* m_pInPtr3; complex m_FreqSignal; complex m_BitSignal; // Phase Values complex * Phase; // Local variables for various functions that need to be saved between calls double m_AGCave; double m_LastFreq; int m_PkPos; int m_BitPos; float IMD; /** Some Variable for CalcQuality */ double fe0,fe1,fe2; double x_loop_1,y_loop_1; public slots: signals: // Signals }; #endif linpsk/src/input.cpp0000644000175000017500000000230211337745306014712 0ustar schroerschroer/*************************************************************************** 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/src/interleaver.h0000644000175000017500000000243411337745306015546 0ustar schroerschroer/*************************************************************************** interleaver.h - description ------------------- begin : Sam Mr 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/src/rttydemodulator.cpp0000644000175000017500000004631711337745306017033 0ustar schroerschroer/*************************************************************************** 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; } bool RTTYDemodulator::Init ( double FS, int ) { SampleRate = FS; Baudrate = 45.45; NumberOfBits = 5; SymbolLength = int ( FS / Baudrate + 0.5 ); Status = WaitingForMark; FrequencyChanged = false; ave1 = 0.5; ave2 = 0.0; setRxFrequency ( 1000. ); F0inc = 0.; F1inc = 0.; F0max = 0.; F1max = 0.; return true; } void RTTYDemodulator::ProcessInput ( double *input, double * ) { char c1; int i, j, count; int StartBitCount, StartBitLength, StartBit2Lead; int StopBit2Count; int actSample; // int Filtered[RESULTLENGTH]; // complex 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/src/cmodulator.cpp0000644000175000017500000000242111337745306015726 0ustar schroerschroer/*************************************************************************** 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; Buffer=TxBuffer; } CModulator::~CModulator() { } void CModulator::setParameter(RxTxParameterType,void *) { /** * At the moment only RTTY uses some extra Parameters * So there is mostly nothing to do * but that may change in the future **/ return; } linpsk/src/feccoder.h0000644000175000017500000000237111337745306015000 0ustar schroerschroer/*************************************************************************** feccoder.h - description ------------------- begin : Sam Mr 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 FECCODER_H #define FECCODER_H /** *@author Volker Schroer */ class FECCoder { public: FECCoder(); ~FECCoder(); void FECEncode(int,unsigned char *); private: static const unsigned char Partab[256]; unsigned int coded; }; #endif linpsk/src/parameter.h0000644000175000017500000000464311337745306015212 0ustar schroerschroer/*************************************************************************** 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; /**Contains parameters for transmitting and receiving some of them are set by settup *@author Volker Schroer */ class Parameter { public: Parameter(); ~Parameter(); void setupDevices(); // Variables /** MinimumWindowWidth */ int MinimumWindowWidth; /** MinimumWindowHeight */ int MinimumWindowHeight; QString callsign; // Callsign QString myLocator; QString inputFilename; //Name of Demofile QString DemoModeFileType[2]; // File Type of DemoFile int DemoTypeNumber; // Index of selected FileType int serial; // Filedescriptor for serial Device for PTT QString SerialDevice; //Filename for PTT Device //Logging QString QSOFileName; // Name of the file,where qsodata will be stored QString Directory; bool fileLog; bool LinLog; QString Host; int Port; bool DemoMode; // DemoMode ? int timeoffset; // offset to UTC /** DeviceSection */ bool slashed0; // True if to print 0 slashed bool autoCrLf; // True if sending cr lf on enter unsigned int RxChannels; CRxChannel * ChannelChain; CRxChannel * ActChannel; QsoInfo *QslData; BUTTONSTATUS Status; QFont *ApplicationFont; QString dateFormat; }; #endif linpsk/src/macrowindow.h0000644000175000017500000000315211337745306015555 0ustar schroerschroer/*************************************************************************** macros.h - description ------------------- begin : Sam Mai 3 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 MACROWINDOW_H #define MACROWINDOW_H #include class Macros; class QGroupBox; class QButtonGroup; /**This class implements simple text and file macros. The macros are startet by a pushbutton and the pushbuttons are arranged in a scrollview. *@author Volker Schroer */ class MacroWindow : public QScrollArea { Q_OBJECT public: MacroWindow(Macros *M,QWidget *parent=0); ~MacroWindow(); void setMacroWindow ( Macros *M); private: QButtonGroup* DisplayBox; QGroupBox* Area; int NumberOfMacros; protected: void fontChange(const QFont &); public slots: virtual void resizeEvent( QResizeEvent * ); void updateMacroWindow(Macros *); signals: void callMacro(int); }; #endif linpsk/src/interleaver.cpp0000644000175000017500000000411111337745306016073 0ustar schroerschroer/*************************************************************************** interleaver.cpp - description ------------------- begin : Sam Mr 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/src/cledbutton.h0000644000175000017500000000310111337745306015361 0ustar schroerschroer/*************************************************************************** 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 /**Constucts a pushbutton with a led in it *@author Volker Schroer */ enum BUTTONSTATUS { UNDEF, // undefined ON, // TX OFF // RX }; class CLedButton : public QPushButton { Q_OBJECT public: CLedButton(QWidget *parent=0); ~CLedButton(); /** paint the button and the led in it */ void paintEvent(QPaintEvent *e); /** sets the buttonstatus */ void setStatus(BUTTONSTATUS state); BUTTONSTATUS getstatus(); private: BUTTONSTATUS status; private slots: // Private slots /** No descriptions */ void rxtx(); signals: void startRx(); void startTx(); }; #endif linpsk/src/crxwindow.h0000644000175000017500000000461611337745306015256 0ustar schroerschroer/*************************************************************************** crxwindow.h - description ------------------- begin : Mon Mar 6 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 CRXWINDOW_H #define CRXWINDOW_H #include #include "constants.h" #include #include class QLineEdit; class QWidget; class QString; class QMenu; class CRxWindow : public QScrollArea { Q_OBJECT public: CRxWindow ( QWidget* parent = 0 ); ~CRxWindow(); bool getTriggerStatus(); QString getTriggerText(); void stopRecording(); void startRecording ( QString ); bool getRecordingState(); public slots: void updateRx ( char ); void clearRxWindow(); void setColor ( QColor ); void activateTrigger ( QString ); void deactivateTrigger(); void contextMenu ( QPoint ); protected: virtual void fontChange ( const QFont & ); virtual void resizeEvent ( QResizeEvent * e ); protected slots: void copyCallSign(); void copyQTH(); void copyName(); void copyLocator(); void copyRST(); private: QLineEdit* ScrollBuffer[RXWINDOWBUFFER]; int Row, Column, rowHeight; void removeLines(int); void NeueZeile(); QWidget* DisplayBox; bool AutoScroll; bool trigger; QString TriggerText; QString TexttoTrigger; bool save; QFile File; QTextStream *stream; QMenu *menu; QString selectedString; int DisplayLineHeight; signals: void Triggered(); void copyCallSign ( QString ); void copyQTH ( QString ); void copyName ( QString ); void copyLocator ( QString ); void copyRST ( QString ); }; #endif // CRXWINDOW_H linpsk/src/crxchannel.cpp0000644000175000017500000001646611337745306015720 0ustar schroerschroer/*************************************************************************** crxchannel.cpp - 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. * ***************************************************************************/ #include #include #include "crxchannel.h" #include "cdemodulator.h" #include "crxwindow.h" #include "qpskdemodulator.h" #include "bpskdemodulator.h" #include "rttydemodulator.h" #include "mfskdemodulator.h" #include "parameter.h" extern Parameter settings; CRxChannel::CRxChannel ( int ID, QWidget *parent, Mode DemodulatorType, unsigned int Freq ) { nextChannel = 0; prevChannel = 0; RxMode = DemodulatorType; WindowsID = ID; double SampleRate = 5512.5; int BufferLength; BufferLength = BUF_SIZE / 2; switch ( DemodulatorType ) { case QPSK: Demodulator = new QPskDemodulator(); break; case RTTY: Demodulator = new RTTYDemodulator(); SampleRate = 11025; BufferLength = BUF_SIZE; break; case MFSK16: Demodulator = new MFSKDemodulator(); SampleRate = 11025; BufferLength = BUF_SIZE; break; default: Demodulator = new BPskDemodulator(); break; } Demodulator->Init ( SampleRate, BufferLength ); // Should changed later to // adjusted Samplerate Demodulator->setRxFrequency ( double ( Freq ) ); Demodulator->setAfcMode ( Demodulator->AfcProperties() ); RxWindow = new CRxWindow ( parent ); connect ( Demodulator, SIGNAL ( newSymbol ( char ) ), RxWindow, SLOT ( updateRx ( char ) ) ); connect ( RxWindow, SIGNAL ( Triggered() ), this, SLOT ( triggered() ) ); QDateTime t1; QDateTime t; t = QDateTime::currentDateTime(); t1 = t.addSecs ( settings.timeoffset * 3600 ); QsoData.QsoDate= t.date() ; QsoData.QsoTime= t1.time(); } CRxChannel::~CRxChannel() { if ( Demodulator != 0 ) delete Demodulator; if ( RxWindow != 0 ) delete RxWindow; if ( prevChannel != 0 ) prevChannel->changeChain ( nextChannel ); } void CRxChannel::insertChannel ( CRxChannel *nChannel ) { CRxChannel *p; // Find last Channel in Chain p = this; while ( p->getNextChannel() != 0 ) p = p->getNextChannel(); if ( p == this ) { nextChannel = nChannel; nChannel->setPrevChannel ( p ); } else p->insertChannel ( nChannel ); } void CRxChannel::changeChain ( CRxChannel *nChannel ) { nextChannel = nChannel; } void CRxChannel::setGeometry ( int x, int y, int width, int height ) { if ( RxWindow != 0 ) RxWindow->setGeometry ( x, y, width, height ); } void CRxChannel::processInput ( double *Input, double *Spectrum ) { Demodulator->ProcessInput ( Input, Spectrum ); } CRxChannel * CRxChannel::getNextChannel() { return nextChannel; } void CRxChannel::setRxFrequency ( double Freq ) { Demodulator->setRxFrequency ( Freq ); } Mode CRxChannel::getModulationType() { return RxMode; } void CRxChannel::hide() { RxWindow->hide(); } void CRxChannel::show() { RxWindow->show(); } CRxChannel* CRxChannel::getChannel ( int ID ) { CRxChannel *p; if ( ID > WindowsID ) for ( p = this; p != 0; p = p->getNextChannel() ) { if ( p->getID() == ID ) return p; } if ( ID < WindowsID ) for ( p = this; p != 0; p = p->prevChannel ) { if ( p->getID() == ID ) return p; } return this; } void CRxChannel::setPrevChannel ( CRxChannel *p ) { prevChannel = p; } complex* CRxChannel::getPhasePointer() { if ( ( RxMode == BPSK ) || ( RxMode == QPSK ) ) return Demodulator->getPhasePointer(); else return 0; } int CRxChannel::getID() { return WindowsID; } void CRxChannel::setAfcMode ( AfcMode mode ) { Demodulator->setAfcMode ( mode ); } AfcMode CRxChannel::getAfcMode() { return Demodulator->getAfcMode(); } int CRxChannel::getSquelchValue() { return Demodulator->getSquelchValue(); } void CRxChannel::setThreshold ( int value ) { Demodulator->setThreshold ( value ); } void CRxChannel::setSquelch ( bool OnOff ) { Demodulator->setSquelch ( OnOff ); } bool CRxChannel::getSquelchState() { return Demodulator->getSquelchState(); } double CRxChannel::getRxFrequency() { if ( Demodulator != 0 ) return Demodulator->getRxFrequency(); else return 0; } int CRxChannel::getThreshold() { return Demodulator->getThreshold(); } void CRxChannel::updateRx ( char c ) { RxWindow->updateRx ( c ); } void CRxChannel::setWindowColor ( QColor c ) { RxWindow->setColor ( c ); } void CRxChannel::clearRxWindow() { RxWindow->clearRxWindow(); } void CRxChannel::setMode ( Mode DemodulatorType ) { if ( RxMode != DemodulatorType ) { Demodulator->disconnect(); double SampleRate = 5512.5; double Freq = Demodulator->getRxFrequency(); bool Squelch = Demodulator->getSquelchState(); int Threshold = Demodulator->getThreshold(); delete Demodulator; int BufferLength = BUF_SIZE / 2; switch ( DemodulatorType ) { case QPSK: Demodulator = new QPskDemodulator(); break; case RTTY: Demodulator = new RTTYDemodulator(); SampleRate = 11025; BufferLength = BUF_SIZE; break; case MFSK16: Demodulator = new MFSKDemodulator(); SampleRate = 11025; BufferLength = BUF_SIZE; break; default: Demodulator = new BPskDemodulator(); break; } RxMode = DemodulatorType; Demodulator->Init ( SampleRate, BufferLength ); // Should changed later to // adjusted Samplerate Demodulator->setRxFrequency ( Freq ); Demodulator->setThreshold ( Threshold ); Demodulator->setSquelch ( Squelch ); connect ( Demodulator, SIGNAL ( newSymbol ( char ) ), RxWindow, SLOT ( updateRx ( char ) ) ); } } void CRxChannel::setQsoData ( QsoInfo *Data ) { if ( Data ) QsoData = *Data; } QsoInfo *CRxChannel::getQsoData() { return &QsoData; } void CRxChannel::triggered() { int i = WindowsID; emit Triggered ( i ); QApplication::beep(); } void CRxChannel::record ( bool recording ) { if ( recording ) { QString s; s.setNum ( WindowsID ); RxWindow->startRecording ( QString ( "Window_" ) + s + QString ( ".txt" ) ); } else RxWindow->stopRecording(); } int CRxChannel::get2RxFrequency() { return ( int ) Demodulator->get2RxFrequency(); } float CRxChannel::getIMD() { return Demodulator->getIMD(); } void CRxChannel::setParameter ( RxTxParameterType Type, void *Value ) { Demodulator->setParameter ( Type, Value ); } void *CRxChannel::getParameter ( RxTxParameterType Type ) { return Demodulator->getParameter ( Type ); } void * CRxChannel::getBuffer() { return Demodulator->getBuffer(); } AfcMode CRxChannel::AfcProperties() { return Demodulator->AfcProperties(); } linpsk/src/csound.cpp0000644000175000017500000003301711337745306015055 0ustar schroerschroer/*************************************************************************** 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 using namespace std; extern Parameter settings; CSound::CSound ( int ptt = -1 ) : Input ( ptt ) { started = false; output = false; freePointer = 0; available = 0; readPointer = 0; free = 2 * BUF_SIZE; } CSound::~CSound() { } int CSound::getSamples ( double *sample, int anzahl ) { if ( !started ) return 0; if ( anzahl > available ) return 0; memcpy ( sample, &buffer[readPointer], anzahl*sizeof ( double ) ) ; LockPointers.lock(); available -= anzahl; free += anzahl; WakeUp.wakeAll(); LockPointers.unlock(); readPointer += anzahl; readPointer %= ( 2 * BUF_SIZE ); return anzahl; } bool CSound::open_Device_read ( QString *errorstring ) { int err; snd_pcm_hw_params_t *hwparams; snd_pcm_sw_params_t *swparams; snd_pcm_uframes_t period_size = 512; unsigned int SampleRate = 11025; output = false; freePointer = 0; available = 0; readPointer = 0; free = 2 * BUF_SIZE; err = snd_pcm_open ( &handle, "LinPSK_Record", SND_PCM_STREAM_CAPTURE, SND_PCM_ASYNC ); if ( err < 0 ) { *errorstring = QString ( "Unable to open Device LinPSK_Record: " ) + QString ( snd_strerror ( err ) ) + QString ( "\nPlease read the README for configuration hints\n" ); return false; } snd_pcm_hw_params_malloc ( &hwparams ); snd_pcm_sw_params_malloc ( &swparams ); /* Choose all parameters */ err = snd_pcm_hw_params_any ( handle, hwparams ); if ( err < 0 ) { *errorstring = QString ( "Broken configuration : no configurations available: " ) + QString ( snd_strerror ( err ) ); return false; } /* Set the interleaved read/write format */ err = snd_pcm_hw_params_set_access ( handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED ); if ( err < 0 ) { *errorstring = QString ( "Access type not available : " ) + QString ( snd_strerror ( err ) ); return false; } /* Set the sample format */ err = snd_pcm_hw_params_set_format ( handle, hwparams, SND_PCM_FORMAT_FLOAT_LE ); if ( err < 0 ) { *errorstring = QString ( "Sample format Float not available : " ) + QString ( snd_strerror ( err ) ); return false; } /* Set the count of channels, most soundcards only support stereo */ err = snd_pcm_hw_params_set_channels ( handle, hwparams, 2 ); if ( err < 0 ) { *errorstring = QString ( "Channels count 2 not available, please modify your plugin: " ) + QString ( snd_strerror ( err ) ); return false; } err = snd_pcm_hw_params_set_rate ( handle, hwparams, SampleRate, 0 ); if ( err < 0 ) { *errorstring = QString ( "Samplerate %1 not available for capture: " ).arg ( SampleRate ) + QString ( snd_strerror ( err ) ); return false; } int kkk = 0; err = snd_pcm_hw_params_set_period_size_near ( handle, hwparams, &period_size, &kkk ); if ( err < 0 ) { *errorstring = QString ( "Unable to set period size %d for play: " ).arg ( period_size ) + QString ( snd_strerror ( err ) ); return false; } snd_pcm_uframes_t buffer_size = 2048; err = snd_pcm_hw_params_set_buffer_size_near ( handle, hwparams, &buffer_size ); if ( err < 0 ) { *errorstring = QString ( "Unable to set buffer size %i for capture: " ).arg ( buffer_size ) + QString ( snd_strerror ( err ) ); return false; } err = snd_pcm_hw_params ( handle, hwparams ); if ( err < 0 ) { *errorstring = QString ( "Unable to set hw params for input: " ) + QString ( snd_strerror ( err ) ); return false; } snd_pcm_hw_params_free ( hwparams ); /* Get the current swparams */ err = snd_pcm_sw_params_current ( handle, swparams ); if ( err < 0 ) { *errorstring = QString ( "Unable to determine current swparams for capture: " ) + QString ( snd_strerror ( err ) ); return false; } err = snd_pcm_sw_params_set_start_threshold ( handle, swparams, 1 ); if ( err < 0 ) { *errorstring = QString ( "Unable to set start threshold for capture: " ) + QString ( snd_strerror ( err ) ); return false; } /* Write the parameters to the record device */ err = snd_pcm_sw_params ( handle, swparams ); if ( err < 0 ) { *errorstring = QString ( "Unable to set sw params for input: " ) + QString ( snd_strerror ( err ) ); return false; } snd_pcm_sw_params_free ( swparams ); output = false; err = snd_pcm_start ( handle ); if ( err <= 0 ) started = true; else { *errorstring = QString ( "Unable to start soundcard for receiving: " ) + QString ( snd_strerror ( err ) ); started = false; return false; } return true; } bool CSound::open_Device_write ( QString *errorstring ) { int err; snd_pcm_hw_params_t *hwparams; snd_pcm_sw_params_t *swparams; snd_pcm_uframes_t period_size = 1024; unsigned int SampleRate = 11025; output = true; qDebug ( "Open Device write" ); err = snd_pcm_open ( &handle, "LinPSK_Play", SND_PCM_STREAM_PLAYBACK, 0 ); if ( err < 0 ) { *errorstring = QString ( "Unable to open Device LinPSK_Play: " ) + QString ( snd_strerror ( err ) ); return false; } // Set blocking mode err = snd_pcm_nonblock ( handle, 0 ); snd_pcm_hw_params_malloc ( &hwparams ); snd_pcm_sw_params_malloc ( &swparams ); /* Choose all parameters */ err = snd_pcm_hw_params_any ( handle, hwparams ); if ( err < 0 ) { *errorstring = QString ( "Broken configuration : no configurations available: " ) + QString ( snd_strerror ( err ) ); return false; } /* Set the interleaved read/write format */ err = snd_pcm_hw_params_set_access ( handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED ); if ( err < 0 ) { *errorstring = QString ( "Access type not available : " ) + QString ( snd_strerror ( err ) ); return false; } /* Set the sample format */ err = snd_pcm_hw_params_set_format ( handle, hwparams, SND_PCM_FORMAT_FLOAT_LE ); if ( err < 0 ) { *errorstring = QString ( "Sample format Float not available : " ) + QString ( snd_strerror ( err ) ); return false; } /* Set the count of channels */ err = snd_pcm_hw_params_set_channels ( handle, hwparams, 2 ); if ( err < 0 ) { *errorstring = QString ( "Channels count 2 not available, please modify your plugin: " ) + QString ( snd_strerror ( err ) ); return false; } err = snd_pcm_hw_params_set_rate ( handle, hwparams, SampleRate, 0 ); if ( err < 0 ) { *errorstring = QString ( "Samplerate %1 not available for playing: " ).arg ( SampleRate ) + QString ( snd_strerror ( err ) ); return false; } int kkk = 0; err = snd_pcm_hw_params_set_period_size_near ( handle, hwparams, &period_size, &kkk ); if ( err < 0 ) { *errorstring = QString ( "Unable to set period size %d for play: " ).arg ( period_size ) + QString ( snd_strerror ( err ) ); return false; } snd_pcm_uframes_t buffer_size = 9192; err = snd_pcm_hw_params_set_buffer_size_near ( handle, hwparams, &buffer_size ); if ( err < 0 ) { *errorstring = QString ( "Unable to set buffer size %i for play: " ).arg ( buffer_size ) + QString ( snd_strerror ( err ) ); return false; } else qDebug("Buffersize set to %i",buffer_size); err = snd_pcm_hw_params ( handle, hwparams ); if ( err < 0 ) { *errorstring = QString ( "Unable to set hw params for input: " ) + QString ( snd_strerror ( err ) ); return false; } snd_pcm_hw_params_free ( hwparams ); /* Get the current swparams */ err = snd_pcm_sw_params_current ( handle, swparams ); if ( err < 0 ) { *errorstring = QString ( "Unable to determine current swparams for play: " ) + QString ( snd_strerror ( err ) ); return false; } snd_pcm_uframes_t threshold=buffer_size/2; if ( threshold > 2048) threshold=2048; err = snd_pcm_sw_params_set_start_threshold ( handle, swparams, threshold ); if ( err < 0 ) { *errorstring = QString ( "Unable to set start threshold mode : " ) + QString ( snd_strerror ( err ) ); return false; } else qDebug("Setting start threshold to %i", threshold); /* Write the parameters to the record/playback device */ err = snd_pcm_sw_params ( handle, swparams ); if ( err < 0 ) { *errorstring = QString ( "Unable to set sw params for output: " ) + QString ( snd_strerror ( err ) ); return false; } output = true; return true; } int CSound::putSamples ( double *sample, int anzahl ) { if ( anzahl <= free ) { memcpy ( &buffer[freePointer], sample, anzahl*sizeof ( double ) ); LockPointers.lock(); toBePlayed += anzahl; free -= anzahl; if ( toBePlayed > 2*BUF_SIZE ) qDebug ( "putSamples: Bufferoverrun" ); WakeUp.wakeAll(); LockPointers.unlock(); freePointer += anzahl; freePointer %= ( 2 * BUF_SIZE ); } else { anzahl=0; qDebug ( "++++++free too low %d", free ); } return anzahl; } void CSound::PTT ( bool mode ) { int flags; int ii; flags = TIOCM_RTS | TIOCM_DTR; if ( serial < 0 ) // No serial Device selected { // No PTT, only start stream if ( mode ) { if ( !started ) { started = true; } } else { if ( started ) { started = false; } } return; } if ( mode ) // PTT on { ii = ioctl ( serial, TIOCMBIS, &flags ); if ( !started ) { started = true; } } else { if ( started ) { started = false; } ii = ioctl ( serial, TIOCMBIC, &flags ); } return; } bool CSound::close_Device() { wait(); if ( handle != 0 ) snd_pcm_close ( handle ); handle = 0; started = false; output = false; return true; } void CSound::run() { started = true; if ( !output ) record(); else play(); } void CSound::record() { int toBeRead, err; float SampleBuffer[256]; qDebug ( "Start recording" ); while ( started ) { LockPointers.lock(); while ( free < 128 && started ) WakeUp.wait ( &LockPointers ); LockPointers.unlock(); if ( !started ) break; toBeRead = min ( free, 128 ); if ( toBeRead > BUF_SIZE ) { qDebug ( "Error toBeRead zu gross" ); return; } if ( ( freePointer + toBeRead ) > 2*BUF_SIZE ) qDebug ( "Out of Bounds \n" ); err = snd_pcm_readi ( handle, SampleBuffer, toBeRead ); if ( err == toBeRead ) { for ( int i = 0; i < toBeRead;i++ ) buffer[freePointer+i] = SampleBuffer[2*i]; LockPointers.lock(); available += toBeRead; free -= toBeRead; LockPointers.unlock(); freePointer = ( freePointer + toBeRead ) % ( 2 * BUF_SIZE ); if ( available >= BUF_SIZE ) emit samplesAvailable(); } else { if ( err == -EPIPE ) { // Overrun snd_pcm_prepare ( handle ); snd_pcm_start ( handle ); qDebug ( "Record: Overrun" ); } else { qDebug ( "Record: unhandled error %d\n %s\n", err, snd_strerror ( err ) ); return ; } } } snd_pcm_drop ( handle ); qDebug ( "record thread terminated" ); } void CSound::play() { float SampleBuffer[256], x; bool signaled; int err, laenge; laenge = 128; signaled = false; freePointer = 0; readPointer = 0; free = 2 * BUF_SIZE; toBePlayed = 0; qDebug ( "Play thread started" ); while ( started ) { LockPointers.lock(); if ( toBePlayed <= BUF_SIZE && ( !signaled ) ) { emit samplesAvailable(); signaled = true; } if ( free > ( 2* BUF_SIZE ) ) qDebug ( "Out of bounds" ); while ( toBePlayed < laenge && started ) WakeUp.wait ( &LockPointers ); LockPointers.unlock(); if ( !started ) { qDebug ( "Stop received" ); break; } if ( toBePlayed >= BUF_SIZE ) signaled = false; for ( int i = 0;i < laenge;i++ ) { x = buffer[readPointer+i]; SampleBuffer[2*i] = x; SampleBuffer[2*i+1] = x; } err = snd_pcm_writei ( handle, SampleBuffer , laenge ); if ( err == laenge ) { LockPointers.lock(); toBePlayed -= err; free += err; readPointer = ( readPointer + err ) % ( 2 * BUF_SIZE ); LockPointers.unlock(); } else { if ( err == -EPIPE ) { /* under-run */ qDebug ( "Underun in Play position 2 laenge %d Pointer %d available %d\n", laenge, readPointer, toBePlayed ); err = snd_pcm_prepare ( handle ); if ( err < 0 ) { qDebug ( "Can't recover from underrun, prepare failed: %s\nStopping Play Thread", snd_strerror ( err ) ); break; } } else if ( err == -EAGAIN ) qDebug ( "Play ???? \n" ); else { qDebug("Errorcode %i",err); qDebug ( " %s\nStopping Play Thread", snd_strerror ( err ) ); break; } } } qDebug ( "Now dropping" ); snd_pcm_drop ( handle ); qDebug ( "Play Thread terminated" ); } linpsk/src/rttymodulator.cpp0000644000175000017500000002464011337745306016515 0ustar schroerschroer/*************************************************************************** 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; } /// actChar = getChar(); bit = 1; /// if ( actChar == TXOFF_CODE ) /// status = TX_END_STATE; /// else /// TX_Status = Startbit; TX_Status = WaitingforChar; break; } break; // case TX_POSTAMBLE_STATE: // break; case TX_TUNE_STATE: actChar = getChar(); bit =0; if ( actChar == TXOFF_CODE) status = TX_END_STATE; break; case TX_END_STATE: bit=1; break; } return bit; } double RTTYModulator::calcNextSample(unsigned int bit) { double temp; temp = xr *dr[bit] - xi*di[bit]; xi = xr *di[bit] + xi*dr[bit]; xr = temp; temp = 2.0 -(xr*xr+xi*xi); xr *=temp; xi *=temp; return xr; } int RTTYModulator::Char2Baudot(int character) { int value; static const char symbols[128]= { 0x00, // NULL 0 0x00, // SOH undefined 1 0x00, // STX " 2 0x00, // ETX " 3 0x00, // EOT " 4 0x09, // ENQ 5 0x00, // ACK undefined 6 0x0A, // BEL 7 0x08, // BS ? 8 0x00, // HT undefined 9 0x02, // LF 10 0x00, // VT undefined 11 0x00, // FF " 12 0x08, // CR 13 0x00, // SO undefined 14 0x00, // SI " 15 0x00, // DLE undefined 16 0x00, // DC1 " 17 0x00, // DC2 " 18 0x00, // DC3 " 19 0x00, // DC4 " 20 0x00, // NAK " 21 0x00, // SYN " 22 0x00, // ETB " 23 0x00, // CAN " 24 0x00, // EM " 25 0x00, // SUB " 26 0x00, // ESC " 27 0x00, // FS " 28 0x00, // GS " 29 0x00, // RS " 30 0x00, // US " 31 0x04, // SPACE 32 0x00, // ! undefined 33 0x11, // " 34 0x14, // # 35 0x09, // $ 36 0x00, // % undefinded 37 0x00, // & " 38 0x05, // ' " 39 0x0f, // ( 40 0x12, // ) 41 0x00, // * undefined 42 0x11, // + 43 0x0c, // , 44 0x03, // - 45 0x1A, // . 46 0x1d, // / 47 0x16, // 0 48 0x17, // 1 49 0x13, // 2 50 0x01, // 3 51 0x0A, // 4 52 0x10, // 5 53 0x15, // 6 54 0x07, // 7 55 0x06, // 8 56 0x18, // 9 57 0x0E, // : 58 0x1e, // ; 59 0x00, // < undefined 60 0x1e, // = ? 61 0x00, // > undefined 62 0x19, // ? 63 0x00, // @ undefined 64 0x03, // A 65 0x19, // B 66 0x0E, // C 67 0x09, // D 68 0x01, // E 69 0x0D, // F 70 0x1A, // G 71 0x14, // H 72 0x06, // I 73 0x0b, // J 74 0x0F, // K 75 0x12, // L 76 0x1C, // M 77 0x0C, // N 78 0x18, // O 79 0x16, // P 80 0x17, // Q 81 0x0A, // R 82 0x05, // S 83 0x10, // T 84 0x07, // U 85 0x1E, // V 86 0x13, // W 87 0x1D, // X 88 0x15, // Y 89 0x11, // Z 90 0x00, // [ undefined 91 0x00, // \ " 92 0x00, // ] " 93 0x00, // ^ " 94 0x00, // _ " 95 0x00, // ' " 96 0x03, // A 97 0x19, // B 98 0x0E, // C 99 0x09, // D 100 0x01, // E 101 0x0D, // F 102 0x1A, // G 103 0x14, // H 104 0x06, // I 105 0x0b, // J 106 0x0F, // K 107 0x12, // L 108 0x1C, // M 109 0x0C, // N 110 0x18, // O 111 0x16, // P 112 0x17, // Q 113 0x0A, // R 114 0x05, // S 115 0x10, // T 116 0x07, // U 117 0x1E, // V 118 0x13, // W 119 0x1D, // X 120 0x15, // Y 121 0x11, // Z 122 0x00, // { undefined 123 0x00, // \ " 124 0x00, // } " 125 0x00, // ~ " 126 0x00 // DEL " 127 }; static const CharacterStatus shift[128] = { IGNORE,IGNORE,IGNORE,IGNORE, // 4* IGNORE FIGS, IGNORE, FIGS, IGNORE,IGNORE,IGNORE,IGNORE, // 26 * IGNORE IGNORE,IGNORE,IGNORE,IGNORE, IGNORE,IGNORE,IGNORE,IGNORE, IGNORE,IGNORE,IGNORE,IGNORE, IGNORE,IGNORE,IGNORE,IGNORE, IGNORE,IGNORE,IGNORE,IGNORE, IGNORE,IGNORE, FIGS,FIGS,FIGS, // 3 * FIGS IGNORE, FIGS,FIGS,FIGS,FIGS, // 4 * FIGS IGNORE, FIGS,FIGS,FIGS,FIGS,FIGS, // 17 * FIGS FIGS,FIGS,FIGS,FIGS,FIGS, FIGS,FIGS,FIGS,FIGS,FIGS, FIGS,FIGS, IGNORE, FIGS, IGNORE, FIGS, IGNORE, LTRS,LTRS,LTRS,LTRS, //26 * LTRS LTRS,LTRS,LTRS,LTRS, LTRS,LTRS,LTRS,LTRS, LTRS,LTRS,LTRS,LTRS, LTRS,LTRS,LTRS,LTRS, LTRS,LTRS,LTRS,LTRS, LTRS,LTRS, IGNORE,IGNORE,IGNORE,IGNORE, // 6* IGNORE IGNORE,IGNORE, LTRS,LTRS,LTRS,LTRS, // 26 * LTRS LTRS,LTRS,LTRS,LTRS, LTRS,LTRS,LTRS,LTRS, LTRS,LTRS,LTRS,LTRS, LTRS,LTRS,LTRS,LTRS, LTRS,LTRS,LTRS,LTRS, LTRS,LTRS, IGNORE,IGNORE,IGNORE,IGNORE, // 5 * IGNORE IGNORE }; switch (shift[character]) { case IGNORE: value = symbols[character]; break; case LTRS: if ( actCharacterStatus != LTRS) { value = 0x1f; secondchar = symbols[character]; actCharacterStatus = LTRS; } else value = symbols[character]; break; case FIGS: if ( actCharacterStatus != FIGS) { value = 0x1b; secondchar = symbols[character]; actCharacterStatus = FIGS; } else value = symbols[character]; break; } return value; } int RTTYModulator::getChar() { int value; char ch; ch = 0; if (secondchar != 0) { value = secondchar; secondchar = 0; } else do { value = Buffer->getTxChar(); if ( value > 0 ) { ch = value; if ( value > 127 ) value = value -128; value = Char2Baudot(value); } } while ( value == 0 ); if (ch > 0) emit charSend(ch); return value; } void RTTYModulator::setParameter(RxTxParameterType Type,void *Value) { switch (Type) { case Reverse: extraParameter.reverse = * (bool *) Value; break; case Offset: extraParameter.offset = * (int *) Value; break; case Parity: extraParameter.parity = * (Paritaet *) Value; break; case Extra: extraParameter = * (ExtraParameter *) Value; break; default: break; } init(); } void RTTYModulator::init() { f1=f0+extraParameter.offset; if (!extraParameter.reverse) { float x; //Change Mark and Space Frequency x=f0; f0=f1; f1=x; } xr=1.0; xi=0.0; dr[0]=cos(f0*2.0*M_PI/SampleRate); di[0]=sin(f0*2.0*M_PI/SampleRate); dr[1]=cos(f1*2.0*M_PI/SampleRate); di[1]=sin(f1*2.0*M_PI/SampleRate); } linpsk/src/csquelch.cpp0000644000175000017500000001141311337745306015365 0ustar schroerschroer/*************************************************************************** |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 scale; p.begin ( this ); // Get Parameters of the Slider initStyleOption ( &option ); option.type = QStyleOption::SO_Slider; option.subControls = QStyle::SC_SliderGroove; const QColor c0 = option.palette.color ( QPalette::Window ); QRect groove = option.rect; if ( SquelchLevel > 0 ) { // Draw the two parts of the slider groove, if we have a signal int height = option.rect.height(); scale = ( height * ( 100 - SquelchLevel ) ) / 100; // Set Color depending on signal strength if ( SquelchLevel < option.sliderValue ) // Too low option.palette.setColor ( QPalette::Window, Yellow ); else option.palette.setColor ( QPalette::Window, Cyan ); p.drawComplexControl ( QStyle::CC_Slider, option ); option.rect.setHeight ( scale ); } option.palette.setColor ( QPalette::Window, c0 ); p.drawComplexControl ( QStyle::CC_Slider, option ); option.rect = groove; option.subControls = QStyle::SC_SliderHandle; p.drawComplexControl ( QStyle::CC_Slider, option ); } void mySlider::setSquelchLevel ( int level ) { SquelchLevel = level; repaint(); } int mySlider::getThreshold() { return value(); } /* * Constructs a CSquelch which is a child of 'parent', with the * name 'name'.' */ CSquelch::CSquelch ( const QString name, QWidget* parent ) : QGroupBox ( name, parent ) { setAlignment ( int ( Qt::AlignHCenter ) ); Activate = new QRadioButton ( tr ( "On/Off" ), this ); Activate->setGeometry ( QRect ( 120, 340, 60, 41 ) ); Squelch = new mySlider ( this ); //connect(Squelch,SIGNAL(sliderMoved(int)),this,SLOT(setThreshold(int))); languageChange(); } /* * Destroys the object and frees any allocated resources */ CSquelch::~CSquelch() { // no need to delete child widgets, Qt does it all for us } /* * Sets the strings of the subwidgets using the current * language. */ void CSquelch::languageChange() { setTitle ( tr ( "Squelch" ) ); } void CSquelch::resizeEvent ( QResizeEvent * ) { calculateSizeofComponents(); } void CSquelch::calculateSizeofComponents() { /** Margins **/ #define TOPMARGIN 10 /** WIDTH and Height in % **/ #define SQUELCHWIDTH 25 #define SQUELCHHEIGHT 70 #define BUTTONWIDTH 75 #define BUTTONHEIGHT 10 int xpos, ypos, width, height, innerwidth, innerheight; width = this->width(); height = this->height(); innerwidth = width * SQUELCHWIDTH / 100; xpos = ( width - innerwidth ) / 2; ypos = height * TOPMARGIN / 100; innerheight = height * SQUELCHHEIGHT / 100; Squelch->setGeometry ( xpos, ypos, innerwidth, innerheight ); ypos = ypos + innerheight + TOPMARGIN; innerwidth = width * BUTTONWIDTH / 100; xpos = ( width - innerwidth ) / 2; innerheight = height * BUTTONHEIGHT / 100; Activate->setGeometry ( xpos, ypos, innerwidth, innerheight ); resize ( width, height ); } void CSquelch::setSquelchLevel ( int level ) { Squelch->setSquelchLevel ( level ); //repaint(); } int CSquelch::getThreshold() { return Squelch->getThreshold(); } bool CSquelch::getSquelchState() { return Activate->isChecked(); } void CSquelch::setSquelchState ( bool state ) { Activate->setChecked ( state ); } void CSquelch::setThreshold ( int Threshold ) { Squelch->setValue ( Threshold ); } linpsk/src/macrowindow.cpp0000644000175000017500000000722211337745306016112 0ustar schroerschroer/*************************************************************************** macros.cpp - description ------------------- begin : Sam Mai 3 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 "macrowindow.h" #include #include #include #include #include "parameter.h" #include "macros.h" extern Parameter settings; MacroWindow::MacroWindow ( Macros *Macro, QWidget *parent ) : QScrollArea ( parent ) { QPushButton *pb; Area = new QGroupBox ( this ); Area->setAlignment ( Qt::AlignHCenter ); DisplayBox = new QButtonGroup ( Area ); setWidget ( Area ); setHorizontalScrollBarPolicy ( Qt::ScrollBarAlwaysOff ); setVerticalScrollBarPolicy ( Qt::ScrollBarAlwaysOn ); NumberOfMacros = Macro->count(); if ( NumberOfMacros > 0 ) for ( int i = 0; i < NumberOfMacros;i++ ) { pb = new QPushButton ( Macro->getMacroName ( i ), Area ); DisplayBox->addButton ( pb, i ); } else Area->hide(); connect ( DisplayBox, SIGNAL ( buttonClicked ( int ) ), this, SIGNAL ( callMacro ( int ) ) ); } MacroWindow::~MacroWindow() {} void MacroWindow::resizeEvent ( QResizeEvent * ) { if ( NumberOfMacros == 0 ) return; // Nothing to do int width, height, y; width = this->width(); width = width - verticalScrollBar()->width(); y = 5; if ( settings.ApplicationFont != 0 ) height = QFontMetrics ( *settings.ApplicationFont ).height(); else height = QFontMetrics ( this->font() ).height(); if(NumberOfMacros > 0) for ( int i = 0; i < NumberOfMacros; i++ ) { QPushButton *pb; pb = static_cast ( DisplayBox->button ( i ) ); // if (settings.ApplicationFont != 0) // pb->setFont(*settings.ApplicationFont); pb->setFixedSize ( width - 20, height ); pb->move ( 8, y ); y = y + height + 5; } Area->setFixedSize ( width-5, y ); Area->show(); } void MacroWindow::updateMacroWindow ( Macros *Macro ) { QPushButton *pb; NumberOfMacros = Macro->count(); pb = new QPushButton ( Macro->getMacroName ( NumberOfMacros - 1 ), Area ); DisplayBox->addButton ( pb, NumberOfMacros - 1 ); pb->show(); resizeEvent ( 0 ); } void MacroWindow::fontChange ( const QFont & ) { /** if (settings.ApplicationFont != 0) { DisplayBox->setFont(*settings.ApplicationFont); int anzahl = DisplayBox->count(); for(int i=0; i < anzahl; i++) { QButton *pb; pb=DisplayBox->find(i); pb->setFont(*settings.ApplicationFont); } } **/ } void MacroWindow::setMacroWindow ( Macros *M ) { int i, anzahl; QPushButton *pb; anzahl = DisplayBox->buttons().size(); if ( anzahl > 0) for ( i = 0; i < anzahl; i++ ) { pb= static_cast ( DisplayBox->button ( i ) ); DisplayBox->removeButton (pb ); delete pb; } NumberOfMacros = M->count(); if ( NumberOfMacros > 0 ) for ( i = 0; i < NumberOfMacros;i++ ) { pb = new QPushButton ( M->getMacroName ( i ), Area ); DisplayBox->addButton ( pb, i ); pb->show(); } else Area->hide(); resizeEvent ( 0 ); } linpsk/src/readonlystringlistmodel.cpp0000644000175000017500000000336611337745306020547 0ustar schroerschroer/*************************************************************************** * 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/src/cmodulator.h0000644000175000017500000000336511337745306015403 0ustar schroerschroer/*************************************************************************** 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 *Buffer; public slots: signals: void charSend(char); }; #endif linpsk/src/crxchannel.h0000644000175000017500000000507611337745306015360 0ustar schroerschroer/*************************************************************************** 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 "constants.h" #include #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= BPSK,unsigned int Freq=1000); virtual ~CRxChannel(); void insertChannel(CRxChannel * ); void setPrevChannel(CRxChannel *); void changeChain(CRxChannel *); void setGeometry(int,int,int,int); void processInput(double *, double *); AfcMode getAfcMode(); AfcMode AfcProperties(); CRxChannel *getNextChannel(); double getRxFrequency(); int get2RxFrequency(); Mode getModulationType(); int getID(); bool getSquelchState(); int getSquelchValue(); void setThreshold(int); int getThreshold(); QColor getWindowColor(); void setWindowColor(QColor); void setParameter(RxTxParameterType,void *); void *getParameter(RxTxParameterType); CRxWindow *RxWindow; float getIMD(); virtual void *getBuffer(); public slots: void setRxFrequency(double); void hide(); void show(); class CRxChannel *getChannel(int); void setAfcMode(AfcMode); std::complex* getPhasePointer(); void setSquelch(bool); void updateRx(char); void clearRxWindow(); void setMode(Mode); void setQsoData(QsoInfo *); QsoInfo *getQsoData(); void record(bool); protected: CDemodulator *Demodulator; private: CRxChannel *nextChannel; CRxChannel *prevChannel; Mode RxMode; int WindowsID; QsoInfo QsoData; private slots: void triggered(); signals: void Triggered(int); }; #endif linpsk/src/ctxbuffer.cpp0000644000175000017500000000433011337745306015546 0ustar schroerschroer/*************************************************************************** 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; filled=0; } else { inpos--; if (inpos < 0) inpos +=TXBUFFER_LENGTH; } } } void CTxBuffer::clear() { filled=0; inpos=0; outpos=0; } void CTxBuffer::insert(QString Text,int length) { for (int i=0;i Filled()) // Wait until Buffer is not filled qApp->processEvents(QEventLoop::AllEvents,100); filled++; txbuffer[inpos++]=Text.at(i).toAscii(); inpos = inpos % TXBUFFER_LENGTH; } } } linpsk/src/ctxwindow.cpp0000644000175000017500000001607111337745306015611 0ustar schroerschroer/*************************************************************************** |FILENAME| - description ------------------- begin : |DATE| copyright : (C) |YEAR| by |AUTHOR| email : |EMAIL| ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * The PSK part is based on WinPSK 1.0 by Moe Wheatly, AE4JY * ***************************************************************************/ #include "ctxbuffer.h" #include "ctxwindow.h" #include #include #include #include #include "parameter.h" extern Parameter settings; /* * Constructs a CTxWindow which is a child of 'parent', with the * name 'name'.' */ CTxWindow::CTxWindow ( QWidget* parent ) : QFrame ( parent ) { setFrameShape ( QFrame::Panel ); setFrameShadow ( QFrame::Sunken ); // setLineWidth( 2 ); // setMargin( 2 ); // setMidLineWidth( 1 ); Clear = new QPushButton ( "TXClear", this ); Zeile1 = new QLineEdit ( this ); Zeile1->setFrame ( false ); Zeile2 = new QLineEdit ( this ); Zeile2->setFrame ( false ); // Zeile2->setFrameShadow( QLineEdit::Plain ); // Zeile2->setLineWidth( 0 ); Zeile3 = new QLineEdit ( this ); Zeile3->setFrame ( false ); languageChange(); Zeile = 0; Spalte = 0; Zeile1->setFocusProxy ( this ); Zeile2->setFocusProxy ( this ); Zeile3->setFocusProxy ( this ); setFocusPolicy(Qt::ClickFocus); // signals and slots connections connect ( Clear , SIGNAL ( clicked() ), this, SLOT ( clear() ) ); connect ( Zeile1, SIGNAL ( returnPressed() ), this, SLOT ( gotoNextLine() ) ); connect ( Zeile2, SIGNAL ( returnPressed() ), this, SLOT ( gotoNextLine() ) ); connect ( Zeile3, SIGNAL ( returnPressed() ), this, SLOT ( gotoNextLine() ) ); /** connect( Zeile1, SIGNAL( textChanged(const QString &)) , this, SLOT(transmitText(const QString &))); connect( Zeile2, SIGNAL( textChanged(const QString &)) , this, SLOT(transmitText(const QString &))); connect( Zeile3, SIGNAL( textChanged(const QString &)) , this, SLOT(transmitText(const QString &))); **/ setEnabled ( true ); } void CTxWindow::clear() { Zeile1->clear(); Zeile2->clear(); Zeile3->clear(); Zeile = 0; Spalte = 0; Zeile1->setCursorPosition ( Spalte ); Buffer->clear(); } void CTxWindow::resizeEvent ( QResizeEvent * ) { calculateSizeofComponents(); } void CTxWindow::gotoNextLine() { if ( Zeile == 2 ) // Reached last Line { Zeile1->setText ( Zeile2->text() ); Zeile2->setText ( Zeile3->text() ); Zeile3->clear(); Spalte = 0; Zeile3->setCursorPosition ( Spalte ); } else { Zeile++; Spalte = 0; if ( Zeile == 1 ) Zeile2->setCursorPosition ( Spalte ); else Zeile3->setCursorPosition ( Spalte ); } } void CTxWindow::calculateSizeofComponents() { #define MARGINS 3 #define DISTANCE 2 #define BUTTOMWIDTH 20 int xpos, ypos, width, height, innerheight, innerwidth; width = this->width(); height = this->height(); xpos = DISTANCE; ypos = height * MARGINS / 100; innerheight = ( height - 2 * ypos - height * DISTANCE / 100 ) / 4; Zeile1->setGeometry ( xpos, ypos, width - 2*xpos, innerheight ); ypos = ypos + innerheight - 2; Zeile2->setGeometry ( xpos, ypos, width - 2*xpos, innerheight ); ypos = ypos + innerheight - 2; Zeile3->setGeometry ( xpos, ypos, width - 2*xpos, innerheight ); ypos = ypos + innerheight + height * DISTANCE / 100; innerwidth = 100; xpos = width - innerwidth - 2 * xpos; Clear->setGeometry ( xpos, ypos, innerwidth, innerheight ); } void CTxWindow::mousePressEvent ( QMouseEvent * ) { if ( Zeile == 0 ) Zeile1->setCursorPosition ( Spalte ); if ( Zeile == 1 ) Zeile2->setCursorPosition ( Spalte ); if ( Zeile == 2 ) Zeile3->setCursorPosition ( Spalte ); } /* * Destroys the object and frees any allocated resources */ CTxWindow::~CTxWindow() { // no need to delete child widgets, Qt does it all for us } /* * Sets the strings of the subwidgets using the current * language. */ void CTxWindow::languageChange() { Clear->setText ( tr ( "Clear" ) ); } void CTxWindow::keyPressEvent ( QKeyEvent *e ) // Bearbeiten der Eingaben im // TX Window { unsigned char c; static bool CapsLock = false; if ( Buffer->Filled() ) { QApplication::beep(); e->ignore(); return; } /** if ( e->state() & ControlButton ) { if ( e->key() == Key_V ) pasteText( QApplication::clipboard()->text( QClipboard::Clipboard ) ); } else **/ switch ( e->key() ) { case Qt::Key_Enter: case Qt::Key_Return: gotoNextLine(); if(settings.autoCrLf) Buffer->insert('\r'); Buffer->insert ( '\n' ); e->accept(); break; case Qt::Key_Home: Buffer->insert('\r'); e->accept(); break; case Qt::Key_CapsLock: CapsLock = !CapsLock; e->accept(); break; case Qt::Key_Backspace: c = '\b'; backspace(); e->accept(); Buffer->insert ( c ); break; default: // ButtonState cc=e->state(); // if ( (cc == ShiftButton) ) if ( ( e->modifiers() == Qt::ShiftModifier ) || CapsLock ) { if ( !e->text().isEmpty() ) c = e->text().toUpper().at ( 0 ).toAscii(); else c = 0; } else { if ( !e->text().isEmpty() ) c = e->text().toLower().at ( 0 ).toAscii(); else c = 0; } if ( c != 0 ) { Spalte++; if ( Spalte > 80 ) { Buffer->insert ( '\n' ); //This newline Char will be Transmitted gotoNextLine(); } Buffer->insert ( c ); insert ( c ); e->accept(); } } // End Case } // keyPressEvent void CTxWindow::backspace() { QLineEdit * line; if ( Zeile == 0 ) line = Zeile1; if ( Zeile == 1 ) line = Zeile2; if ( Zeile == 2 ) line = Zeile3; line->backspace(); } void CTxWindow::insert ( unsigned char c ) { QLineEdit *line; if ( Zeile == 0 ) line = Zeile1; if ( Zeile == 1 ) line = Zeile2; if ( Zeile == 2 ) line = Zeile3; QString s = line->text() + QString ( QChar ( c ) ); line->setText ( s ); } void CTxWindow::setTxBuffer ( CTxBuffer *p ) { Buffer = p; } void CTxWindow::pasteText ( const QString &Text ) { int length; length = Text.length(); for ( int i = 0; i < length; i++ ) { Spalte++; if ( Spalte > 80 ) { Buffer->insert ( '\n' ); //This newline Char will be Transmitted gotoNextLine(); } char c = Text.at ( i ).toAscii(); Buffer->insert ( c ); insert ( c ); } } linpsk/src/mfskdemodulator.h0000644000175000017500000000501211337745306016421 0ustar schroerschroer/*************************************************************************** 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(); bool Init(double,int); virtual double get2RxFrequency(); private: AfcMode AfcProperties(); void mixdown(double *); void calcSoftBits(int pos, double *softBits); unsigned int datashreg; MFSKVaricode *Decoder; Deinterleaver * leave; complex *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/src/deinterleaver.cpp0000644000175000017500000000411111337745306016404 0ustar schroerschroer/*************************************************************************** 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 #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.toAscii(), s.length() ); c = '\n'; write ( fd, &c, 1 ); } return anzahl; } /** Dummy */ void TextInput::PTT ( bool ) { } /** Dummy */ bool TextInput::open_Device_read ( QString *errorstring ) { *errorstring = QString ( "" ); if ( settings.inputFilename == "" ) { *errorstring = QString ( QObject::tr ( "Error, no Demofile selected" ) ); return false; } fd = open ( settings.inputFilename.toAscii(), O_RDONLY ); if ( fd > 0 ) return true; else { *errorstring = QString ( QObject::tr ( "Error, Could not open Demofile " ) ); return false; } } bool TextInput::close_Device() { if ( fd >= 0 ) close ( fd ); fd = -1; return true; } linpsk/src/waveinput.cpp0000644000175000017500000001512311337745306015602 0ustar schroerschroer/*************************************************************************** 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[3]; char c; QString s; int i; *errorstring=QString(""); if (settings.inputFilename == "" ) { *errorstring= QString(QObject::tr("Error, no Demofile selected")); return false; } fd = open(settings.inputFilename.toAscii(),O_RDONLY); if ( fd < 0) { *errorstring= QString(QObject::tr("Error, Could not open Demofile ")); return false; } // Check for RIFF i =read(fd,&header[0],4*sizeof(header[0])); if ( i != 4) { close(fd); *errorstring= QString(QObject::tr("Header mismatch")); return false; } header[4]=0; s=QString(header); if ( s != "RIFF") { close(fd); *errorstring = settings.inputFilename + QString(QObject::tr( " is not a RIFF File\n")); return false; } //Check for Wave lseek(fd,8,SEEK_SET); i =read(fd,&header[0],4*sizeof(header[0])); header[4]=0; if ( i != 4) { close(fd); *errorstring= QString(QObject::tr("SubType mismatch\n")); return false; } s=QString(header); if ( s != "WAVE") { close(fd); *errorstring =settings.inputFilename + QString(QObject::tr(" is not a WAVE File\n")); return false; } //Check for fmt i =read(fd,&header[0],4*sizeof(header[0])); header[4]=0; if ( i != 4) { close(fd); *errorstring= QString(QObject::tr("File is too short\n")); return false; } s=QString(header); if ( s != "fmt ") { close(fd); *errorstring =settings.inputFilename + QString(QObject::tr(" does not have a fmt chunk\n")); return false; } // Read length of fmt chunk i=read(fd,&header[0],4*sizeof(header[0])); if ( i != 4) { close(fd); *errorstring= QString(QObject::tr("File is too short, while reading fmt chunk\n")); return false; } Length=header[0] | (header[1] << 8) |(header[2] << 16) | (header[3] << 24 ); // To distinguish between the two versions of wav ( canonical and new) if ((Length -16) >0) offset = Length-16; else offset = 0; //Check for format lseek(fd,20,SEEK_SET); i=read(fd,&header[0],2*sizeof(header[0])); if ( i != 2) { close(fd); *errorstring= QString(QObject::tr("File is too short, while reading format info in fmt chunk\n")); return false; } Length=header[0] | ( header[1] << 8 ); if (Length != 1 ) { close(fd); *errorstring= QString(QObject::tr("File is too short, while reading format info in fmt chunk\n")); return false; } //check for mono lseek(fd,22,SEEK_SET); i=read(fd,&header[0],2*sizeof(header[0])); if ( i != 2) { close(fd); *errorstring= QString(QObject::tr("File is too short, while reading channel info in fmt chunk\n")); return false; } Length=header[0] | ( header[1] << 8 ); if ( Length != 1) { close(fd); *errorstring= QString(QObject::tr("Only mono is supported at the moment\n")); return false; } // Check for sample rate lseek(fd,24,SEEK_SET); i=read(fd,&header[0],4*sizeof(header[0])); if ( i != 4) { close(fd); *errorstring= QString(QObject::tr("File is too short, while reading sample rate in fmt chunk\n")); return false; } Length=header[0] | ( header[1] << 8 ) | (header[2] << 16) | (header[3] << 24 ); if ( Length != 11025) { close(fd); *errorstring= QString(QObject::tr("Only a sample rate of 11025Hz is supported at the moment\n")); return false; } //let's check for 8 / 16 bit samples lseek(fd,34,SEEK_SET); i=read(fd,&c,1); if (c == 8) EightBits=true; else EightBits=false; offset +=36; // Now find data lseek(fd,offset,SEEK_SET); i=read(fd,&header[0],4*sizeof(header[0])); header[5]=0; s=QString(header); // Checking for fact chunk if ( s == "fact") { lseek(fd,8,SEEK_CUR); i=read(fd,&header[0],4*sizeof(header[0])); header[5]=0; s=QString(header); } if ( (i != 4) || s != "data" ) { close(fd); *errorstring= QString(QObject::tr("No data found\n")); return false; } // got it // Read 4 byte Length info i=read(fd,&header1[0],4*sizeof(header1[0])); if ( i != 4) { close(fd); *errorstring= QString(QObject::tr("File is too short, while reading length of data chunk\n")); return false; } Length=0; Length=header1[0] | (header1[1] << 8) |(header1[2] << 16) | (header1[3] << 24 ); Bytesread=0; offset = lseek(fd,0,SEEK_CUR); i=lseek(fd,offset,SEEK_SET); return true; } int WaveInput::getSamples(double *sample,int anzahl) { unsigned char c[2]; int i,j; j=0; double x; while (j= 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/src/feccoder.cpp0000644000175000017500000000432011337745306015327 0ustar schroerschroer/*************************************************************************** feccoder.cpp - description ------------------- begin : Sam Mr 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 "feccoder.h" /* The two generator polynomials for the NASA Standard K=7 rate 1/2 code. */ #define POLYA 0x6d #define POLYB 0x4f /* * 8-bit parity lookup table, generated */ const unsigned char FECCoder::Partab[256] = { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, }; FECCoder::FECCoder() { } FECCoder::~FECCoder() { } void FECCoder::FECEncode(int data, unsigned char *bits) { coded = (coded << 1) | !!data; // return (Partab[coded & POLYA] << 1) | Partab[coded & POLYB]; bits[0]=Partab[coded & POLYA]; // High bits[1]=Partab[coded & POLYB]; // Low } linpsk/src/mfskvaricode.h0000644000175000017500000000244011337745306015700 0ustar schroerschroer/*************************************************************************** mfskvaricode.h - description ------------------- begin : Sam Mr 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/src/fircoeffs.h0000644000175000017500000002170211337745306015173 0ustar schroerschroer////////////////////////////////////////////////////////////////////// // Copyright 1999. Moe Wheatley AE4JY // //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/src/qpskdemodulator.h0000644000175000017500000000272311337745306016445 0ustar schroerschroer/*************************************************************************** qpskdemodulator.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 QPSKDEMODULATOR_H #define QPSKDEMODULATOR_H #include "cpskdemodulator.h" /**Implementation of the QPsk demodulator *@author Volker Schroer */ class Viterbi; class QPskDemodulator : public CPskDemodulator { public: QPskDemodulator(); ~QPskDemodulator(); protected: /** Decodes a QPSK Symbol */ //void DecodeSymbol( complex newsamp); void DecodeSymbol( double); void CalcQuality(double); private: double ave1,ave2; Viterbi *v; }; #endif linpsk/src/firfilter.h0000644000175000017500000000314511337745306015214 0ustar schroerschroer/*************************************************************************** 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 *Filtercoeffs,int Filterlength,FilterMode); ~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/src/csquelch.h0000644000175000017500000000361311337745306015035 0ustar schroerschroer/*************************************************************************** |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(const QString, QWidget* parent = 0); ~CSquelch(); void setSquelchLevel(int); int getThreshold(); bool getSquelchState(); void setSquelchState(bool); public slots: void setThreshold(int); protected: void resizeEvent( QResizeEvent * ); protected slots: virtual void languageChange(); private: void calculateSizeofComponents(); mySlider* Squelch; QRadioButton* Activate; }; #endif // CSQUELCH_H linpsk/src/readonlystringlistmodel.h0000644000175000017500000000364211337745306020211 0ustar schroerschroer/*************************************************************************** * 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/src/linpsk.cpp0000644000175000017500000007033611337745306015067 0ustar schroerschroer/*************************************************************************** |FILENAME| - description ------------------- begin : |DATE| copyright : (C) |YEAR| by |AUTHOR| email : |EMAIL| ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * The PSK part is based on WinPSK 1.0 by Moe Wheatly, AE4JY * ***************************************************************************/ #include "linpsk.h" #include "controlpanel.h" #include "crxdisplay.h" #include "ctxdisplay.h" #include "parameter.h" #include "addrxwindow.h" #include "spectrumdisplay.h" #include "frequencyselect.h" #include "cledbutton.h" #include "rttymodulator.h" #include "pskmodulator.h" #include "bpskmodulator.h" #include "qpskmodulator.h" #include "mfskmodulator.h" #include "ctxbuffer.h" #include "crxchannel.h" #include "input.h" #include "textinput.h" #include "waveinput.h" #include "csound.h" #include "generalsettings.h" #include "modemenu.h" #include "macrowindow.h" #include "addmacro.h" #include "deletemacro.h" #include "macros.h" #include "qsodata.h" #include "editmacro.h" #include "deletemacro.h" #include "renamemacro.h" #include "color.h" #include "crecording.h" #include #include #ifdef HAVE_CONFIG #include "config.h" #else #define VERSION "1.1" #endif #define ProgramName "LinPSK " extern Parameter settings; /* * Constructs a LinPSK as a child of 'parent', with the * name 'name' and widget flags set to 'f'. * */ LinPSK::LinPSK ( QWidget* parent, Qt::WFlags fl ) : QMainWindow ( parent, fl ) { RxDisplay = 0; TxDisplay = 0; Control = 0; Sound = 0; SaveParameters = new Parameter(); Macro = new Macros(); // Macros will be used in read_config read_config(); if ( settings.ApplicationFont == 0 ) { settings.ApplicationFont = new QFont ( qApp->font().family() ); settings.ApplicationFont->setPixelSize ( 10 ); qApp->setFont ( *settings.ApplicationFont ); } else qApp->setFont ( *settings.ApplicationFont ); // Save Settings to be able to make local modifications *SaveParameters = settings; if ( WindowColors.size() == 0 ) WindowColors << color[0] ; Modulator = 0; setCentralWidget ( new QWidget ( this ) ); centralWidget()->setMinimumSize ( settings.MinimumWindowWidth, settings.MinimumWindowHeight ); setWindowTitle ( QString ( ProgramName ) + QString ( VERSION ) ); setWindowIcon ( QIcon ( ":/images/linpsk.png" ) ); // Create Statusbar QStatusBar *StatusBar = this->statusBar(); StatusBar->setSizeGripEnabled ( true ); //Messages msg = new QLabel ( StatusBar ); StatusBar->addPermanentWidget ( msg, 2 ); msg->setText ( tr ( "Ready" ) ); // IMD IMD = new QLabel ( StatusBar ); StatusBar -> addPermanentWidget ( IMD, 1 ); // Time zeit = new QLabel ( StatusBar ); StatusBar->addPermanentWidget ( zeit, 1 ); // date datum = new QLabel ( StatusBar ); StatusBar ->addPermanentWidget ( datum, 1 ); setclock(); // Let the time pass QTimer *clock = new QTimer ( this ); connect ( clock, SIGNAL ( timeout() ), SLOT ( setclock() ) ); clock->start ( 60000 ); RxDisplay = new CRxDisplay ( centralWidget() ); TxDisplay = new CTxDisplay ( centralWidget() ); Control = new ControlPanel ( Macro, centralWidget() ); RxDisplay->RxFreq->setAfcDisplayMode ( settings.ActChannel->AfcProperties() ); RxDisplay->RxFreq->setAfcMode ( settings.ActChannel->getAfcMode() ); RxDisplay->setColorList ( &WindowColors ); connect ( RxDisplay, SIGNAL ( copyCallSign ( QString ) ), Control->QSO, SLOT ( copyCallSign ( QString ) ) ); connect ( RxDisplay, SIGNAL ( copyQTH ( QString ) ), Control->QSO, SLOT ( copyQTH ( QString ) ) ); connect ( RxDisplay, SIGNAL ( copyName ( QString ) ), Control->QSO, SLOT ( copyName ( QString ) ) ); connect ( RxDisplay, SIGNAL ( copyLocator ( QString ) ), Control->QSO, SLOT ( copyLocator ( QString ) ) ); connect ( RxDisplay, SIGNAL ( copyRST ( QString ) ), Control->QSO, SLOT ( copyRST ( QString ) ) ); settings.QslData = settings.ActChannel->getQsoData(); Control->Display->setPhasePointer ( settings.ActChannel->getPhasePointer() ); Control->Display->setColorList ( &WindowColors ); //Control->MacroBox->updateMacroWindow ( Macro ); // menubar menubar = menuBar(); // File Menu fileMenu = menubar->addMenu ( tr ( "File" ) ); // Settings Menu editMenu = menubar->addMenu ( tr ( "Settings" ) ); menubar->addSeparator(); //======= changeRxParams = menubar->addMenu ( tr ( "RxParams" ) ); helpMenu = menubar->addMenu ( tr ( "Help" ) ); QAction *A; // File Menu // ================= File Actions ======== A = fileMenu->addAction ( tr ( "Open Demo File" ) ); connect ( A, SIGNAL ( activated() ), this, SLOT ( fileOpen() ) ); A = fileMenu->addAction ( tr ( "add RxWindow" ) ); connect ( A, SIGNAL ( activated() ), this, SLOT ( addRxWindow() ) ); fileMenu->addSeparator(); fileMenu->addSeparator(); A = fileMenu->addAction ( tr ( "Exit" ) ); connect ( A, SIGNAL ( activated() ), this, SLOT ( Exit() ) ); // Settings Menu // ================= Settings Actions================= A = editMenu->addAction ( tr ( "General_Settings" ) ); connect ( A, SIGNAL ( activated() ), this, SLOT ( generalSettings() ) ); editMenu->addSeparator(); A = editMenu->addAction ( tr ( "Add Macros" ) ); connect ( A, SIGNAL ( activated() ), this, SLOT ( addMacro() ) ); A = editMenu->addAction ( tr ( "Edit Macros" ) ); connect ( A , SIGNAL ( activated() ), this, SLOT ( editMacro() ) ); A = editMenu->addAction ( tr ( "Delete Macros" ) ); connect ( A , SIGNAL ( activated() ), this, SLOT ( deleteMacro() ) ); A = editMenu->addAction ( tr ( "Rename Macros" ) ); connect ( A , SIGNAL ( activated() ), this, SLOT ( renameMacro() ) ); //=============================================================================== A = editMenu->addSeparator(); A = editMenu->addAction ( tr ( "Font Settings" ) ); connect ( A , SIGNAL ( activated() ), this, SLOT ( FontSetup() ) ); A = editMenu->addAction ( tr ( "ColorSettings" ) ); connect ( A , SIGNAL ( activated() ), this, SLOT ( chooseColor() ) ); editMenu->addSeparator(); A = editMenu->addAction ( tr ( "Save Settings" ) ); connect ( A , SIGNAL ( activated() ), this, SLOT ( saveSettings() ) ); // Menu Rx Settings //================Actions for RX Window =========== A = changeRxParams->addAction ( tr ( "Change Rx Mode" ) ); connect ( A , SIGNAL ( activated() ), this, SLOT ( setRxMode() ) ); // A= changeRxParams->addAction(tr( " ???") ); // connect ( A , SIGNAL ( activated() ), settings.ActChannel, SLOT ( clearRxWindow() ) ); //Help Menu // ================= Help Actions ========= A = helpMenu->addAction ( tr ( "helpContentsAction" ) ); connect ( A, SIGNAL ( activated() ), this, SLOT ( helpIndex() ) ); A = helpMenu->addAction ( tr ( "helpIndexAction" ) ); connect ( A, SIGNAL ( activated() ), this, SLOT ( helpContents() ) ); A = helpMenu->addAction ( tr ( "helpAboutAction" ) ); connect ( A, SIGNAL ( activated() ), this, SLOT ( helpAbout() ) ); languageChange(); // signals and slots connections //================================= Rx Parames =================== //================================================================ connect ( TxDisplay, SIGNAL ( startRx() ), this, SLOT ( startRx() ) ); connect ( TxDisplay, SIGNAL ( startTx() ), this, SLOT ( startTx() ) ); connect ( Macro, SIGNAL ( StartRx() ), this, SLOT ( startRx() ) ); connect ( Macro, SIGNAL ( StartTx() ), this, SLOT ( startTx() ) ); connect ( RxDisplay, SIGNAL ( startPlotting ( double *, bool ) ), Control->Display, SLOT ( startPlot ( double *, bool ) ) ); connect ( Control->Display, SIGNAL ( FrequencyChanged ( double ) ), RxDisplay->RxFreq, SLOT ( setFrequency ( double ) ) ); connect ( RxDisplay, SIGNAL ( new_IMD ( float ) ), this, SLOT ( setIMD ( float ) ) ); connect ( Control->MacroBox, SIGNAL ( callMacro ( int ) ), this, SLOT ( executeMacro ( int ) ) ); connect ( RxDisplay, SIGNAL ( newActiveChannel() ), this, SLOT ( setChannelParams() ) ); connect ( RxDisplay->Recording->Record, SIGNAL ( toggled ( bool ) ), this, SLOT ( recording ( bool ) ) ); //=================================================================== TxBuffer = new CTxBuffer(); TxDisplay->TxWindow->setTxBuffer ( TxBuffer ); apply_settings(); } /* * Destroys the object and frees any allocated resources */ LinPSK::~LinPSK() { // no need to delete child widgets, Qt does it all for us } /* * Sets the strings of the subwidgets using the current * language. */ void LinPSK::languageChange() { /** // File Open_Demo_File->setText( tr( "Open Demo File" ) ); Open_Demo_File->setMenuText( tr( "&Open Demo File" ) ); Open_Demo_File->setAccel( tr( "Ctrl+O" ) ); fileExitAction->setText( tr( "Exit" ) ); fileExitAction->setMenuText( tr( "E&xit" ) ); fileExitAction->setAccel( QString::null ); // Help helpContentsAction->setText( tr( "Contents" ) ); helpContentsAction->setMenuText( tr( "&Contents..." ) ); helpContentsAction->setAccel( QString::null ); helpIndexAction->setText( tr( "Index" ) ); helpIndexAction->setMenuText( tr( "&Index..." ) ); helpIndexAction->setAccel( QString::null ); helpAboutAction->setText( tr( "About" ) ); helpAboutAction->setMenuText( tr( "&About" ) ); helpAboutAction->setAccel( QString::null ); add_Rx_Window->setText( tr( "add Rx Window" ) ); add_Rx_Window->setMenuText( tr( "&Add another RxWindow" ) ); // Settings General_Settings->setText( tr( "General Settings" ) ); AddMacros->setText( tr( "Add Macro" ) ); FontSettings->setText( tr( "Font Settings" ) ); ColorSettings->setText( tr( "Color Settings" ) ); EditMacros->setText( tr( "Edit Macro" ) ); DeleteMacros->setText( tr("Delete Macro") ); RenameMacros->setText( tr("Rename Macro") ); // EditFiles->setText( tr( "Edit Files" ) ); SaveSettings->setText( tr( "Save Settings" ) ); // Rx Params Clear_RxWindow->setMenuText( tr ("Clear active RX Channel") ); ChangeRxMode->setMenuText( tr ("Change Mode of active Rx Channel") ); menubar->findItem( 0 )->setText( tr( "&File" ) ); menubar->findItem( 1 )->setText( tr( "&Settings" ) ); menubar->findItem( 2 )->setText( tr( "&RxParams" ) ); menubar->findItem( 4 )->setText( tr( "&Help" ) ); **/ } void LinPSK::fileOpen() { QString fileName; fileName = QFileDialog::getOpenFileName ( 0, tr ( "Open Demofile" ), "", settings.DemoModeFileType[settings.DemoTypeNumber] ); if ( !fileName.isEmpty() ) settings.inputFilename = fileName; } void LinPSK::Exit() { if ( settings.Status == ON ) // We arejust transmitting { QMessageBox::information ( 0, ProgramName, "You should stop transmitting before closing this window!" ); return; } else { if ( RxDisplay != 0 ) RxDisplay->stop_process_loop(); settings = *SaveParameters; save_config(); qApp->quit(); return; } } void LinPSK::helpIndex() {} void LinPSK::helpContents() {} void LinPSK::helpAbout() {} void LinPSK::addRxWindow() { AddRxWindow *Channel = new AddRxWindow(); if ( Channel->exec() != 0 ) { AfcMode modus; modus = RxDisplay->RxFreq->getAfcMode(); settings.ActChannel->setAfcMode ( modus ); Mode rxmode = ( Mode ) Channel->selectedMode(); if ( WindowColors.size() <= settings.RxChannels ) WindowColors << color[ ( settings.RxChannels*51 ) % 256]; RxDisplay->addRxWindow ( Channel->frequency(), rxmode, Channel->titleText() ); settings.ActChannel->setWindowColor ( WindowColors.at ( settings.RxChannels ) ); settings.RxChannels++; RxDisplay->RxFreq->setAfcDisplayMode ( settings.ActChannel->AfcProperties() ); } } void LinPSK::calculateSizeofComponents() { /** Anteile in percent of mainwindow **/ /** RXDisplay **/ #define RXPART 36 /** TXDisplay **/ #define TXPART 20 /** Controlpanel **/ #ifndef LINPSK_FOR_MAC #define CONTROLPART 37 #else #define CONTROLPART 40 #endif int width, height; int xpos, ypos; int windowsheight; width = this->width(); height = this->height(); xpos = 0; ypos = 0;; windowsheight = height * RXPART / 100; if ( RxDisplay != 0 ) RxDisplay->setGeometry ( xpos, ypos, width, windowsheight ); ypos = ypos + windowsheight; windowsheight = height * TXPART / 100; if ( TxDisplay != 0 ) TxDisplay->setGeometry ( xpos, ypos, width, windowsheight ); ypos = ypos + windowsheight; windowsheight = height * CONTROLPART / 100; if ( Control != 0 ) Control->setGeometry ( xpos, ypos, width, windowsheight ); } void LinPSK::resizeEvent ( QResizeEvent * ) { calculateSizeofComponents(); } void LinPSK::setclock() { QString s; QDateTime t; t = QDateTime::currentDateTime(); t = t.addSecs ( settings.timeoffset * 3600 ); s.sprintf ( " %2d:%2d UTC", t.time().hour(), t.time().minute() ); s.replace ( QRegExp ( ": " ), ":0" ); zeit->setText ( s ); zeit->update(); s = t.toString ( "dd.MM.yyyy" ); datum->setText ( s ); } void LinPSK::setIMD ( float IMDvalue ) { QString s; if ( IMDvalue != 0.0 ) s.sprintf ( " IMD = %6.2f dB", IMDvalue ); else s.sprintf ( " IMD " ); IMD->setText ( s ); } void LinPSK::startRx() { if ( Modulator != 0 ) { TxBuffer->insert ( TXOFF_CODE ); if ( Sound > 0 ) // Switch Trx to rx while ( Sound->isRunning() ) // Wait for buffer to be cleared qApp->processEvents ( QEventLoop::AllEvents, 100 ); } if ( RxDisplay->start_process_loop() ) { QString Info; TxDisplay->TxFunctions->setStatus ( OFF ); if ( settings.ActChannel != 0 ) switch ( settings.ActChannel->getModulationType() ) { case QPSK: Info = "QPSK"; break; case BPSK: Info = "BPSK"; break; case RTTY: Info = "RTTY"; break; case MFSK16: Info = "MFSK16"; break; default: Info = "undefined"; } msg->setText ( tr ( "Receiving " ) + Info ); } else TxDisplay->TxFunctions->setStatus ( UNDEF ); Control->Display->show(); settings.Status = TxDisplay->TxFunctions->getstatus(); TxDisplay->TxWindow->setFocus(); } void LinPSK::startTx() { Mode ModulationType; QString errorstring; QString Info; double Frequency; RxDisplay->stop_process_loop(); if ( settings.ActChannel == 0 ) { QMessageBox::critical ( 0, " Programm Error! LinPsk", "No active Channel available" ); TxDisplay->TxFunctions->setStatus ( UNDEF ); return; } ModulationType = settings.ActChannel->getModulationType(); if ( TxDisplay->TxFreq->getAfcMode() != Off ) // net ? TxDisplay->TxFreq->setFrequency ( settings.ActChannel->getRxFrequency() ); Frequency = TxDisplay->TxFreq->getFrequency(); switch ( ModulationType ) { case QPSK: Modulator = new QPskModulator ( 11025, Frequency, TxBuffer ); Info = "QPSK"; break; case BPSK: Modulator = new BPSKModulator ( 11025, Frequency, TxBuffer ); Info = "BPSK"; break; case RTTY: Modulator = new RTTYModulator ( 11025, Frequency, TxBuffer ); if ( settings.ActChannel->getParameter ( Extra ) != 0 ) Modulator->setParameter ( Extra, settings.ActChannel->getParameter ( Extra ) ); Info = "RTTY"; break; case MFSK16: Modulator = new MFSKModulator ( 11025, Frequency, TxBuffer ); Info = "MFSK16"; break; default: Modulator = new BPSKModulator ( 11025, Frequency, TxBuffer ); Info = "BPSK"; break; } if ( Sound <= 0 ) // Only create Sound Device once for output { if ( settings.DemoMode ) { if ( settings.DemoTypeNumber == 0 ) Sound = new WaveInput ( -1 ); else Sound = new TextInput ( -1 ); msg->setText ( tr ( "Transmitting (Demo)" ) ); } else Sound = new CSound ( settings.serial ); connect ( Sound, SIGNAL ( samplesAvailable() ), this, SLOT ( process_txdata() ) ); } if ( Sound <= 0 ) { QMessageBox::critical ( 0, " Programm Error! LinPsk", "Could not create Sound Device for Output" ); TxDisplay->TxFunctions->setStatus ( ON ); return; } if ( Sound->open_Device_write ( &errorstring ) < 0 ) { QMessageBox::information ( 0, ProgramName, errorstring ); stopTx(); return; } connect ( Modulator, SIGNAL ( charSend ( char ) ), settings.ActChannel, SLOT ( updateRx ( char ) ) ); TxDisplay->TxFunctions->setStatus ( ON ); msg->setText ( tr ( "Transmitting " ) + Info ); TxDisplay->TxWindow->setFocus(); settings.Status = TxDisplay->TxFunctions->getstatus(); Control->Display->hide(); Txcount = BUF_SIZE; // process_txdata(); // Generate first Sample Sound->PTT ( true ); Sound->start(); } void LinPSK::process_txdata() { int length; // To avoid pending calls to process_txdata() after stopping tx // when Modulator is alredy deleted if (Modulator == 0) return; if ( Txcount > 0 ) { length = Modulator->CalcSignal ( Output, BUF_SIZE ); if ( length <= 0 ) { length = -length; while ( length < BUF_SIZE ) Output[length++] = 0.0; length = BUF_SIZE; Txcount = Sound->putSamples ( Output, length ); stopTx(); return; } } else length = BUF_SIZE; Txcount = Sound->putSamples ( Output, length ); // If Txcount >= 0 and length < BUF_SIZE // we've reached end of Transmiision } void LinPSK::generalSettings() { GeneralSettings *LocalSettings = new GeneralSettings ( this ); if ( LocalSettings->exec() != 0 ) settings = LocalSettings->getSettings(); apply_settings(); } void LinPSK::chooseColor() { int ID = settings.ActChannel->getID(); QColor color = QColorDialog::getColor ( WindowColors[ID], this ); if ( color.isValid() ) { settings.ActChannel->setWindowColor ( color ); WindowColors[ID] = color; RxDisplay->repaint(); RxDisplay->newColor(); } } void LinPSK::FontSetup() { bool ok; QFont f = QFontDialog::getFont ( &ok, font(), this ); if ( ok ) { settings.ApplicationFont->setFamily ( f.family() ); int ii = f.pixelSize(); if ( ii <= 0 ) { ii = f.pointSize(); settings.ApplicationFont->setPointSize ( ii ); } else settings.ApplicationFont->setPixelSize ( ii ); qApp->setFont ( f ); } } void LinPSK::stopTx() { Modulator->disconnect(); if ( Sound != 0 ) { Sound->PTT ( false ); Sound->close_Device(); } delete Modulator; Modulator = 0; } void LinPSK::apply_settings() { selectPTTDevice(); } void LinPSK::setChannelParams() { Control->Display->setPhasePointer ( settings.ActChannel->getPhasePointer() ); Control->QSO->newChannel(); if ( settings.ActChannel != 0 ) { QString Info; switch ( settings.ActChannel->getModulationType() ) { case QPSK: Info = "QPSK"; break; case BPSK: Info = "BPSK"; break; case RTTY: Info = "RTTY"; break; case MFSK16: Info = "MFSK16"; break; default: Info = "undefined"; } RxDisplay->RxFreq->setAfcDisplayMode ( settings.ActChannel->AfcProperties() ); msg->setText ( tr ( "Receiving " ) + Info ); } } void LinPSK::setRxMode() { QString Info; ModeMenu Menu ; ExtraParameter *Param; Param = ( ExtraParameter * ) settings.ActChannel->getParameter ( Extra ); if ( Param != 0 ) Menu.setParameter ( *Param ); if ( Menu.exec() != 0 ) { Mode rxmode = ( Mode ) Menu.selectedMode(); settings.ActChannel->setMode ( rxmode ); RxDisplay->RxFreq->setAfcDisplayMode ( settings.ActChannel->AfcProperties() ); RxDisplay->RxFreq->setAfcMode ( settings.ActChannel->getAfcMode() ); Control->Display->setPhasePointer ( settings.ActChannel->getPhasePointer() ); settings.ActChannel->setParameter ( Extra, &Menu.getParameter() ); } if ( settings.ActChannel != 0 ) switch ( settings.ActChannel->getModulationType() ) { case QPSK: Info = "QPSK"; break; case BPSK: Info = "BPSK"; break; case RTTY: Info = "RTTY"; break; case MFSK16: Info = "MFSK16"; break; default: Info = "undefined"; } msg->setText ( tr ( "Receiving " ) + Info ); } void LinPSK::save_config() { int i; QSettings config ( "DL1KSV", "LinPSK" ); /** Windows Parameter **/ config.beginGroup ( "WindowsParameter" ); // config.setValue ( "MinimumWindowWidth", settings.MinimumWindowWidth ); config.setValue ( "WindowWidth", width() ); // config.setValue ( "MinimumWindowHeight", settings.MinimumWindowHeight ); config.setValue ( "Xpos", this->x() ); config.setValue ( "Ypos", this->y() ); config.setValue ( "WindowHeight", height() ); config.setValue ( "FontName", qApp->font().family() ); config.setValue ( "FontSize", qApp->font().pointSize() ); config.endGroup(); /** DemoMode **/ config.setValue ( "DemoMode", settings.DemoMode ); config.setValue ( "DemoTypeNumber", settings.DemoTypeNumber ); //Operating config.setValue ( "Callsign", settings.callsign ); config.setValue ( "MyLocator", settings.myLocator ); config.setValue ( "PTTDevice", settings.SerialDevice ); //Logging config.setValue ( "Directory", settings.Directory ); config.setValue ( "QSoFileName", settings.QSOFileName ); config.setValue ( "FileLog", settings.fileLog ); config.setValue ( "LinLog", settings.LinLog ); if ( settings.LinLog ) { config.setValue ( "Host", settings.Host ); config.setValue ( "Port", settings.Port ); } config.setValue ( "TimeOffset", settings.timeoffset ); config.setValue ( "dateFormat", settings.dateFormat ); config.setValue ( "Slashed0", settings.slashed0 ); config.setValue ("autoCrLf",settings.autoCrLf); /** Colors **/ if ( WindowColors.size() > 0 ) { config.beginWriteArray ( "Colors" ); for ( i = 0; i < WindowColors.size();i++ ) { config.setArrayIndex ( i ); config.setValue ( "r", WindowColors[i].red() ); config.setValue ( "g", WindowColors[i].green() ); config.setValue ( "b", WindowColors[i].blue() ); } config.endArray(); } // Macros if ( ( Macro->count() > 0 ) ) { config.beginWriteArray ( "Macros" ); for ( i = 0; i < Macro->count();i++ ) { config.setArrayIndex ( i ); config.setValue ( "Name", Macro->getMacroName ( i ) ); QString s = Macro->getDefinition ( i ); config.setValue ( "Definition", s ); config.setValue ( "Accelerator", Macro->getAccelerator ( i ) ); } config.endArray(); } } void LinPSK::executeMacro ( int MacroNumber ) { Macro->executeMacro ( MacroNumber, TxBuffer ); } void LinPSK::addMacro() { AddMacro *NewMacro = new AddMacro ( Macro ); // NewMacro->setKeywords ( Macro ); if ( NewMacro->exec() != 0 ) { Macro->insert ( NewMacro->macroName(), NewMacro->macroDefinition(), NewMacro->accelerator(), NewMacro->position() ); Control->MacroBox->updateMacroWindow ( Macro ); } } void LinPSK::editMacro() { if ( Macro->count() > 0 ) { EditMacro *Edit = new EditMacro ( Macro ); if ( Edit->exec() != 0 ) // Control->MacroBox->updateMacroWindow ( Macro ); Control->MacroBox->setMacroWindow ( Macro ); } } void LinPSK::deleteMacro() { if ( Macro->count() > 0 ) { DeleteMacro *Del = new DeleteMacro ( Macro ); if ( Del->exec() != 0 ) Control->MacroBox->setMacroWindow ( Macro ); } } void LinPSK::renameMacro() { if ( Macro->count() > 0 ) { RenameMacro *Ren = new RenameMacro ( Macro ); if ( Ren->exec() != 0 ) Control->MacroBox->setMacroWindow ( Macro ); } } void LinPSK::read_config() { QSettings config ( "DL1KSV", "LinPSK" ); int HeighttoSet = 0; int WidthtoSet = 0; int X = -1; int Y = -1; int i, size; // Try to read settings from Configfile /** Windows Parameter **/ config.beginGroup ( "WindowsParameter" ); // settings.MinimumWindowWidth = config.value ( "MinimumWindowWidth" , 600 ).toInt(); WidthtoSet = config.value ( "WindowWidth" ).toInt(); // settings.MinimumWindowHeight = config.value ( "MinimumWindowHeight", 400 ).toInt(); X = config.value ( "Xpos" ).toInt(); Y = config.value ( "Ypos" ).toInt(); HeighttoSet = config.value ( "WindowHeight" ).toInt(); if ( config.contains ( "FontName" ) ) { settings.ApplicationFont = new QFont ( config.value ( "FontName" ).toString() ); size = config.value ( "FontSize" ).toInt(); if ( size < 10 ) size = 10; settings.ApplicationFont->setPointSize ( size ); } config.endGroup(); /** DemoMode **/ settings.DemoMode = config.value ( "DemoMode" ).toBool(); settings.DemoTypeNumber = config.value ( "DemoTypeNumber" ).toInt(); //Operating settings.callsign = config.value ( "Callsign" ).toString(); settings.myLocator = config.value ( "MyLocator" ).toString(); settings.SerialDevice = config.value ( "PTTDevice" ).toString(); //Logging settings.Directory = config.value ( "Directory", QDir::homePath() ).toString(); settings.QSOFileName = config.value ( "QSoFileName" ).toString(); settings.fileLog = config.value ( "FileLog", true ).toBool(); settings.LinLog = config.value ( "LinLog", false ).toBool(); if ( settings.LinLog ) { settings.Host = config.value ( "Host", "localhost" ).toString(); settings.Port = config.value ( "Port", 8080 ).toInt(); } settings.timeoffset = config.value ( "TimeOffset" ).toInt(); settings.dateFormat = config.value ( "dateFormat", "dd.MM.yyyy" ).toString(); settings.slashed0 = config.value ( "Slashed0" ).toBool(); settings.autoCrLf = config.value("autoCrLf").toBool(); /** Colors **/ if ( config.contains ( "Colors" ) ) { size = config.beginReadArray ( "Colors" ); for ( i = 0; i < size;i++ ) { config.setArrayIndex ( i ); int r = config.value ( "r" ).toInt(); int g = config.value ( "g" ).toInt(); int b = config.value ( "b" ).toInt(); WindowColors.push_back ( QColor ( r, g, b ) ); } config.endArray(); } // Macros size = config.beginReadArray ( "Macros" ); if ( size > 0 ) { QString name, def, acc; for ( i = 0; i < size;i++ ) { config.setArrayIndex ( i ); name = config.value ( "Name" ).toString(); def = config.value ( "Definition" ).toString(); acc = config.value ( "Accelerator" ).toString(); Macro->insert ( name, def, acc, i + 1 ); } config.endArray(); } if ( ( HeighttoSet > 0 ) && ( WidthtoSet > 0 ) ) resize ( WidthtoSet, HeighttoSet ); if ( ( X >= 0 ) && ( Y >= 0 ) ) move ( X, Y ); } void LinPSK::selectPTTDevice() { //if (settings.serial >0 ) // close(settings.serial); settings.serial = -1; if ( settings.SerialDevice != "None" ) //{ // QMessageBox::information(0,"LinPsk","Trying to open Device " + settings.SerialDevice); settings.serial = open ( settings.SerialDevice.toAscii().data(), O_EXCL | O_WRONLY ); // if (settings.serial > 0 ) // QMessageBox::information(0,"LinPsk","Opening successfull"); // else // QMessageBox::information(0,"LinPsk","Opening unsuccessfull"); //} int flags = TIOCM_RTS | TIOCM_DTR; if ( settings.serial > 0 ) ioctl ( settings.serial, TIOCMBIC, &flags ); else settings.SerialDevice = "None"; //Their seems to be a wrong Value in the ConfigFile } void LinPSK::recording ( bool on ) { settings.ActChannel->record ( on ); } void LinPSK::HelpAbout() { QMessageBox::about ( this, tr ( "About..." ), ProgramName + QString ( VERSION ) + "\n written by Volker Schroer, DL1KSV\n" ); // setActiveWindow(); } void LinPSK::saveSettings() { *SaveParameters = settings; save_config(); } void LinPSK::closeEvent ( QCloseEvent *e ) { if ( settings.Status != ON ) // We are not just transmitting { if ( RxDisplay != 0 ) RxDisplay->stop_process_loop(); e->accept(); save_config(); } else { QMessageBox::information ( 0, ProgramName, "You should stop transmitting before closing this window!" ); e->ignore(); } return; } linpsk/src/mfskmodulator.cpp0000644000175000017500000000601611337745306016450 0ustar schroerschroer/*************************************************************************** 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 ( int i = 0; i < NumberofTones;i++ ) { ToneFrequencyr[i] = cos ( PI2 * ( freq + i * Baudrate ) / SampleRate ); ToneFrequencyi[i] = sin ( PI2 * ( freq + i * Baudrate ) / SampleRate ); } NxSamples = SamplesperSymbol; } MFSKModulator::~MFSKModulator() { if ( Encoder != 0 ) delete Encoder; if ( leave != 0 ) delete leave; if ( Fec != 0 ) delete Fec; } int MFSKModulator::getToneNumber() { int ch; if ( postamblePtr == 1 ) return TXOFF_CODE; for ( ;; ) { if ( Allbitsgone ) { if ( postamblePtr > 1 ) { postamblePtr--; ch = 0; } else if ( preamblePtr > 0 ) { preamblePtr--; ch = 0; } else { ch = Buffer->getTxChar(); if ( ch < 0 ) { if ( ch == TXOFF_CODE ) // { postamblePtr = 10; // ch=0; // } // else ch = 0; // } 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/src/crxdisplay.cpp0000644000175000017500000003160111337745306015741 0ustar schroerschroer/*************************************************************************** |FILENAME| - description ------------------- begin : |DATE| copyright : (C) |YEAR| by |AUTHOR| email : |EMAIL| ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #include "crxdisplay.h" #include #include #include #include #include "crecording.h" #include "crxchannel.h" #include "crxwindow.h" #include "csquelch.h" #include "ctrigger.h" #include "frequencyselect.h" #include "input.h" #include "textinput.h" #include "waveinput.h" #include "csound.h" #include "fircoeffs.h" #include "parameter.h" extern Parameter settings; /* * Constructs a CRxDisplay which is a child of 'parent', with the * name 'name'.' */ CRxDisplay::CRxDisplay ( QWidget* parent ) : QFrame ( parent ) { setFrameShape ( QFrame::WinPanel ); setFrameShadow ( QFrame::Sunken ); RxFreq = new FrequencySelect ( this, Wide ); RxFreq->setTitle ( "Rx Freq / AFC" ); RxFreq->setFunctionText ( "Narrow" ); Recording = new CRecording ( this ); Trigger = new CTrigger ( "Trigger", this ); Squelch = new CSquelch ( "Squelch", this ); RxHeader = new QTabBar ( this ); RxHeader->setShape ( QTabBar::RoundedNorth ); Clear = new QPushButton ( this ); Clear->setText ( "Clear" ); // QTab *Tab = new QTab("Rx 1"); RxHeader->insertTab ( 0, "Rx 1" ); Sound = 0; dec2fir = new double[DEC2_LPFIR_LENGTH]; RxChannel = new CRxChannel ( 0, this ); connect ( RxChannel->RxWindow, SIGNAL ( copyCallSign ( QString ) ), this, SIGNAL ( copyCallSign ( QString ) ) ); connect ( RxChannel->RxWindow, SIGNAL ( copyQTH ( QString ) ), this, SIGNAL ( copyQTH ( QString ) ) ); connect ( RxChannel->RxWindow, SIGNAL ( copyName ( QString ) ), this, SIGNAL ( copyName ( QString ) ) ); connect ( RxChannel->RxWindow, SIGNAL ( copyLocator ( QString ) ), this, SIGNAL ( copyLocator ( QString ) ) ); connect ( RxChannel->RxWindow, SIGNAL ( copyRST ( QString ) ), this, SIGNAL ( copyRST ( QString ) ) ); settings.ChannelChain = RxChannel; settings.ActChannel = RxChannel; Squelch->setSquelchState ( RxChannel->getSquelchState() ); languageChange(); // Connect Signals and Slots // RxTimer = new QTimer ( this ); // connect ( RxTimer, SIGNAL ( timeout() ), this, SLOT ( process_rxdata() ) ); connect ( RxFreq, SIGNAL ( FrequencyChanged ( double ) ), this, SLOT ( setRxFrequency ( double ) ) ); connect ( RxHeader, SIGNAL ( currentChanged ( int ) ), this, SLOT ( changeActiveRxWindow ( int ) ) ); // connect(RxFreq,SIGNAL(toggleAFC(bool)),this,SLOT(setAFC(bool))); connect ( Trigger->Activate, SIGNAL ( clicked() ), this, SLOT ( trigger() ) ); connect ( Trigger->TriggerText, SIGNAL ( returnPressed() ), this, SLOT ( trigger() ) ); connect ( RxChannel, SIGNAL ( Triggered ( int ) ), RxHeader, SLOT ( setCurrentTab ( int ) ) ); connect ( Clear, SIGNAL ( clicked() ), this, SLOT ( clearRxWindow() ) ); trigger(); // We should ensure that the triggertext is stored; // Creating Variables for the fft // plan=rfftw_create_plan(BUF_SIZE/2,FFTW_REAL_TO_COMPLEX,FFTW_ESTIMATE); plan = fftw_plan_r2r_1d ( BUF_SIZE / 2, outbuf, output, FFTW_R2HC , FFTW_PATIENT ); } /* * Destroys the object and frees any allocated resources */ CRxDisplay::~CRxDisplay() { // no need to delete child widgets, Qt does it all for us } /* * Sets the strings of the subwidgets using the current * language. */ void CRxDisplay::languageChange() { // setCaption( tr( "RxDisplay" ) ); } void CRxDisplay::calculateSizeofComponents() { /** in percent of whole widget **/ /** RX Part **/ #define RXPARTWIDTH 64 /** Squelch **/ #define SQUELCHWIDTH 10 /** General Width **/ #define GENERALWIDTH 18 /** Recording **/ #define RECORDHEIGHT 25 /** Trigger **/ #define TRIGGERHEIGHT 33 /** RxFrequency (Height) **/ #define RXFREQHEIGHT 70 /** Left and Right Margin **/ #define LEFTANDRIGHTMARGIN 1 /** Top and Bottom Margin **/ #define TOPANDBOTTOMMARGIN 5 /** Inner distance **/ #define DISTANCE 1 /** Tab height **/ #define TABHEIGHT 10 #define TABWIDTH 30 int xpos, ypos, width, height, innerheight, innerwidth; width = this->width(); height = this->height(); xpos = width * LEFTANDRIGHTMARGIN / 100; /**Recording **/ ypos = height * TOPANDBOTTOMMARGIN / 100; innerwidth = width * GENERALWIDTH / 100; innerheight = height * RECORDHEIGHT / 100; Recording->setGeometry ( xpos, ypos, innerwidth, innerheight ); ypos = ypos + innerheight + height * DISTANCE / 100; /** Trigger **/ innerheight = height * TRIGGERHEIGHT / 100; Trigger->setGeometry ( xpos, ypos, innerwidth, innerheight ); /** RXFrequency **/ ypos = ypos + innerheight + height * DISTANCE / 100; RxFreq->setGeometry ( xpos, ypos, innerwidth, innerheight ); /**SQuelch **/ xpos = xpos + innerwidth + width * DISTANCE / 100; ypos = height * TOPANDBOTTOMMARGIN / 100;; innerheight = height - 2 * ypos; innerwidth = width * SQUELCHWIDTH / 100; Squelch->setGeometry ( xpos, ypos, innerwidth, innerheight ); /** RxWindowTabBar **/ xpos = xpos + innerwidth + width * DISTANCE / 100; innerwidth = ( width - xpos - width * LEFTANDRIGHTMARGIN / 100 ) * TABWIDTH / 100;; innerheight = height * TABHEIGHT / 100; RxHeader->setGeometry ( xpos, ypos, innerwidth, innerheight ); Clear->setGeometry ( width - width*LEFTANDRIGHTMARGIN / 100 - 100, ypos, 100, innerheight ); ypos = ypos + innerheight; innerheight = height - innerheight - height * TOPANDBOTTOMMARGIN / 100; innerwidth = width - xpos - width * LEFTANDRIGHTMARGIN / 100; settings.ActChannel->setGeometry ( xpos, ypos, innerwidth, innerheight ); } void CRxDisplay::resizeEvent ( QResizeEvent * ) { calculateSizeofComponents(); } bool CRxDisplay::start_process_loop() { QString errorstring; if ( Sound == 0 ) { if ( settings.DemoMode ) { if ( settings.DemoTypeNumber == 0 ) Sound = new WaveInput ( -1 ); else Sound = new TextInput ( -1 ); } else Sound = new CSound ( settings.serial ); if ( Sound <= 0 ) return false; connect ( Sound, SIGNAL ( samplesAvailable() ), this, SLOT ( process_rxdata() ) ); } m_pDec2InPtr = dec2fir; for ( int i = 0; i < DEC2_LPFIR_LENGTH;i++ ) dec2fir[i] = 0.0; // fill delay buffer with zero if ( ! Sound->open_Device_read ( &errorstring ) ) //Something went wrong in Opening Input File { if ( settings.DemoMode ) QMessageBox::information ( 0, "LinPsk", errorstring ); else QMessageBox::critical ( 0, "LinPsk", errorstring ); if ( Sound != 0 ) delete Sound; Sound = 0; return false; } Sound->start(); return true; } void CRxDisplay::ProcDec2Fir ( double *pIn, double *pOut, int BlockSize ) { /** Decimate by 2 FIR filter on 'BlockSize' samples. pIn == pointer to input array of double's (can be same buffer as pOut ) pOut == pointer to output array of double's Blocksize == number of samples to process This Procdeure is taken from WinPSK by Moe Wheatley **/ int i, j; double acc; const double* Kptr; double* Firptr; double* Qptr; double* Inptr; Inptr = m_pDec2InPtr; //use automatic copies of member variables Qptr = dec2fir; // for better speed. j = 0; for ( i = 0; i < BlockSize; i++ ) // put new samples into Queue { if ( --Inptr < Qptr ) //deal with wraparound Inptr = Qptr + DEC2_LPFIR_LENGTH - 1; *Inptr = pIn[i]; if ( i&1 ) //calculate MAC's every other time for decimation by 2 { acc = 0.0; Firptr = Inptr; Kptr = Dec2LPCoef; while ( Kptr < ( Dec2LPCoef + DEC2_LPFIR_LENGTH ) ) //do the MAC's { acc += ( ( *Firptr++ ) * ( *Kptr++ ) ); if ( Firptr >= Qptr + DEC2_LPFIR_LENGTH ) //deal with wraparound Firptr = Qptr; } pOut[j++] = acc; //save output sample } } m_pDec2InPtr = Inptr; // save position in circular delay line } void CRxDisplay::process_rxdata() { bool overload; if ( Sound->getSamples ( inbuf, BUF_SIZE ) == 0 ) return; // No sample available, try later overload = false; ProcDec2Fir ( inbuf, outbuf , BUF_SIZE ); // 2uS per sample RxFreq->setFrequency ( settings.ActChannel->getRxFrequency() ); Squelch->setSquelchLevel ( settings.ActChannel->getSquelchValue() ); settings.ActChannel->setThreshold ( Squelch->getThreshold() ); settings.ActChannel->setSquelch ( Squelch->getSquelchState() ); settings.ActChannel->setAfcMode ( RxFreq->getAfcMode() ); for ( CRxChannel * p = RxChannel;p != 0;p = p->getNextChannel() ) if ( ( p->getModulationType() != RTTY ) && ( p->getModulationType() != MFSK16 ) ) { p->processInput ( outbuf, output ); } else p->processInput ( inbuf, output ); /** Update RxFreq for the active Channel **/ emit new_IMD ( settings.ActChannel->getIMD() ); // Calculate FFT and start Ploting // First look for overload int N = BUF_SIZE / 2; for ( int i = 0; i < N;i++ ) { if ( outbuf[i] > 0.77 ) overload = true; // Apply Hamming to Data outbuf[i] *= ( 0.54 - 0.46 * cos ( ( i * PI2 ) / N ) ); } fftw_execute ( plan ); //Calculate power spectrum for ( int i = 1;i < BUF_SIZE / 4;i++ ) output[i] = output[i] * output[i] + output[BUF_SIZE/2-i] * output[BUF_SIZE/2-i]; emit startPlotting ( output, overload ); } void CRxDisplay::addRxWindow ( int Frequency, Mode Modulation, QString Heading ) { CRxChannel *p; int ID = RxHeader->count(); RxHeader->insertTab ( ID, Heading ); p = new CRxChannel ( ID, this, Modulation, Frequency ); connect ( p, SIGNAL ( Triggered ( int ) ), this, SLOT ( changeActiveRxWindow ( int ) ) ); connect ( p->RxWindow, SIGNAL ( copyCallSign ( QString ) ), this, SIGNAL ( copyCallSign ( QString ) ) ); connect ( p->RxWindow, SIGNAL ( copyQTH ( QString ) ), this, SIGNAL ( copyQTH ( QString ) ) ); connect ( p->RxWindow, SIGNAL ( copyName ( QString ) ), this, SIGNAL ( copyName ( QString ) ) ); connect ( p->RxWindow, SIGNAL ( copyLocator ( QString ) ), this, SIGNAL ( copyLocator ( QString ) ) ); connect ( p->RxWindow, SIGNAL ( copyRST ( QString ) ), this, SIGNAL ( copyRST ( QString ) ) ); RxChannel->insertChannel ( p ); RxHeader->setCurrentIndex ( ID ); //RxHeader->repaint(); trigger(); // We should ensure that the triggertext is stored; RxHeader->setTabTextColor ( ID, Farbe->at ( ID ) ); } void CRxDisplay::setRxFrequency ( double freq ) { settings.ActChannel->setRxFrequency ( freq ); } void CRxDisplay::changeActiveRxWindow ( int ID ) { setFocus(); if ( settings.ActChannel != 0 ) { settings.ActChannel->hide(); settings.ActChannel->setQsoData ( settings.QslData ); // Save actual Data to Channel settings.ActChannel->setAfcMode ( RxFreq->getAfcMode() ); if ( settings.ActChannel->getChannel ( ID ) != 0 ) settings.ActChannel = settings.ActChannel->getChannel ( ID ); settings.QslData = settings.ActChannel->getQsoData(); RxFreq->setAfcDisplayMode ( settings.ActChannel->AfcProperties() ); RxFreq->setAfcMode ( settings.ActChannel->getAfcMode() ); RxFreq->setFrequency ( ( unsigned int ) settings.ActChannel->getRxFrequency() ); Squelch->setSquelchState ( settings.ActChannel->getSquelchState() ); Squelch->setThreshold ( settings.ActChannel->getThreshold() ); Trigger->Activate->setChecked ( settings.ActChannel->RxWindow->getTriggerStatus() ); Trigger->TriggerText->setText ( settings.ActChannel->RxWindow->getTriggerText() ); Recording->Record->setChecked ( settings.ActChannel->RxWindow->getRecordingState() ); calculateSizeofComponents(); settings.ActChannel->show(); emit newActiveChannel(); RxHeader->setCurrentIndex ( ID ); } } void CRxDisplay::stop_process_loop() { if ( Sound != 0 ) { Sound->stop(); Sound->wait(); Sound->close_Device(); delete Sound; } Sound = 0 ; } void CRxDisplay::trigger() { settings.ActChannel->RxWindow->activateTrigger ( Trigger->TriggerText->text() ); if ( !Trigger->Activate->isChecked() ) settings.ActChannel->RxWindow->deactivateTrigger(); } void CRxDisplay::setColorList ( QList *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 ) ); } linpsk/src/mfskmodulator.h0000644000175000017500000000345711337745306016123 0ustar schroerschroer/*************************************************************************** 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/src/textinput.h0000644000175000017500000000355311337745306015275 0ustar schroerschroer/*************************************************************************** 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/src/cpskdemodulator.cpp0000644000175000017500000005172611337745306016771 0ustar schroerschroer/*************************************************************************** cpskdemodulator.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 "cpskdemodulator.h" #include "fircoeffs.h" #include "parameter.h" extern Parameter settings; static const unsigned short int VARICODE_TABLE[] = { 0xAAC0, // ASCII = 0 1010101011 0xB6C0, // ASCII = 1 1011011011 0xBB40, // ASCII = 2 1011101101 0xDDC0, // ASCII = 3 1101110111 0xBAC0, // ASCII = 4 1011101011 0xD7C0, // ASCII = 5 1101011111 0xBBC0, // ASCII = 6 1011101111 0xBF40, // ASCII = 7 1011111101 0xBFC0, // ASCII = 8 1011111111 0xEF00, // ASCII = 9 11101111 0xE800, // ASCII = 10 11101 0xDBC0, // ASCII = 11 1101101111 0xB740, // ASCII = 12 1011011101 0xF800, // ASCII = 13 11111 0xDD40, // ASCII = 14 1101110101 0xEAC0, // ASCII = 15 1110101011 0xBDC0, // ASCII = 16 1011110111 0xBD40, // ASCII = 17 1011110101 0xEB40, // ASCII = 18 1110101101 0xEBC0, // ASCII = 19 1110101111 0xD6C0, // ASCII = 20 1101011011 0xDAC0, // ASCII = 21 1101101011 0xDB40, // ASCII = 22 1101101101 0xD5C0, // ASCII = 23 1101010111 0xDEC0, // ASCII = 24 1101111011 0xDF40, // ASCII = 25 1101111101 0xEDC0, // ASCII = 26 1110110111 0xD540, // ASCII = 27 1101010101 0xD740, // ASCII = 28 1101011101 0xEEC0, // ASCII = 29 1110111011 0xBEC0, // ASCII = 30 1011111011 0xDFC0, // ASCII = 31 1101111111 0x8000, // ASCII = ' ' 1 0xFF80, // ASCII = '!' 111111111 0xAF80, // ASCII = '"' 101011111 0xFA80, // ASCII = '#' 111110101 0xED80, // ASCII = '$' 111011011 0xB540, // ASCII = '%' 1011010101 0xAEC0, // ASCII = '&' 1010111011 0xBF80, // ASCII = ''' 101111111 0xFB00, // ASCII = '(' 11111011 0xF700, // ASCII = ')' 11110111 0xB780, // ASCII = '*' 101101111 0xEF80, // ASCII = '+' 111011111 0xEA00, // ASCII = ',' 1110101 0xD400, // ASCII = '-' 110101 0xAE00, // ASCII = '.' 1010111 0xD780, // ASCII = '/' 110101111 0xB700, // ASCII = '0' 10110111 0xBD00, // ASCII = '1' 10111101 0xED00, // ASCII = '2' 11101101 0xFF00, // ASCII = '3' 11111111 0xBB80, // ASCII = '4' 101110111 0xAD80, // ASCII = '5' 101011011 0xB580, // ASCII = '6' 101101011 0xD680, // ASCII = '7' 110101101 0xD580, // ASCII = '8' 110101011 0xDB80, // ASCII = '9' 110110111 0xF500, // ASCII = ':' 11110101 0xDE80, // ASCII = ';' 110111101 0xF680, // ASCII = '<' 111101101 0xAA00, // ASCII = '=' 1010101 0xEB80, // ASCII = '>' 111010111 0xABC0, // ASCII = '?' 1010101111 0xAF40, // ASCII = '@' 1010111101 0xFA00, // ASCII = 'A' 1111101 0xEB00, // ASCII = 'B' 11101011 0xAD00, // ASCII = 'C' 10101101 0xB500, // ASCII = 'D' 10110101 0xEE00, // ASCII = 'E' 1110111 0xDB00, // ASCII = 'F' 11011011 0xFD00, // ASCII = 'G' 11111101 0xAA80, // ASCII = 'H' 101010101 0xFE00, // ASCII = 'I' 1111111 0xFE80, // ASCII = 'J' 111111101 0xBE80, // ASCII = 'K' 101111101 0xD700, // ASCII = 'L' 11010111 0xBB00, // ASCII = 'M' 10111011 0xDD00, // ASCII = 'N' 11011101 0xAB00, // ASCII = 'O' 10101011 0xD500, // ASCII = 'P' 11010101 0xEE80, // ASCII = 'Q' 111011101 0xAF00, // ASCII = 'R' 10101111 0xDE00, // ASCII = 'S' 1101111 0xDA00, // ASCII = 'T' 1101101 0xAB80, // ASCII = 'U' 101010111 0xDA80, // ASCII = 'V' 110110101 0xAE80, // ASCII = 'W' 101011101 0xBA80, // ASCII = 'X' 101110101 0xBD80, // ASCII = 'Y' 101111011 0xAB40, // ASCII = 'Z' 1010101101 0xFB80, // ASCII = '[' 111110111 0xF780, // ASCII = '\' 111101111 0xFD80, // ASCII = ']' 111111011 0xAFC0, // ASCII = '^' 1010111111 0xB680, // ASCII = '_' 101101101 0xB7C0, // ASCII = '`' 1011011111 0xB000, // ASCII = 'a' 1011 0xBE00, // ASCII = 'b' 1011111 0xBC00, // ASCII = 'c' 101111 0xB400, // ASCII = 'd' 101101 0xC000, // ASCII = 'e' 11 0xF400, // ASCII = 'f' 111101 0xB600, // ASCII = 'g' 1011011 0xAC00, // ASCII = 'h' 101011 0xD000, // ASCII = 'i' 1101 0xF580, // ASCII = 'j' 111101011 0xBF00, // ASCII = 'k' 10111111 0xD800, // ASCII = 'l' 11011 0xEC00, // ASCII = 'm' 111011 0xF000, // ASCII = 'n' 1111 0xE000, // ASCII = 'o' 111 0xFC00, // ASCII = 'p' 111111 0xDF80, // ASCII = 'q' 110111111 0xA800, // ASCII = 'r' 10101 0xB800, // ASCII = 's' 10111 0xA000, // ASCII = 't' 101 0xDC00, // ASCII = 'u' 110111 0xF600, // ASCII = 'v' 1111011 0xD600, // ASCII = 'w' 1101011 0xDF00, // ASCII = 'x' 11011111 0xBA00, // ASCII = 'y' 1011101 0xEA80, // ASCII = 'z' 111010101 0xADC0, // ASCII = '{' 1010110111 0xDD80, // ASCII = '|' 110111011 0xAD40, // ASCII = '}' 1010110101 0xB5C0, // ASCII = '~' 1011010111 0xED40, // ASCII = 127 1110110101 0xEF40, // ASCII = 128 1110111101 0xEFC0, // ASCII = 129 1110111111 0xF540, // ASCII = 130 1111010101 0xF5C0, // ASCII = 131 1111010111 0xF6C0, // ASCII = 132 1111011011 0xF740, // ASCII = 133 1111011101 0xF7C0, // ASCII = 134 1111011111 0xFAC0, // ASCII = 135 1111101011 0xFB40, // ASCII = 136 1111101101 0xFBC0, // ASCII = 137 1111101111 0xFD40, // ASCII = 138 1111110101 0xFDC0, // ASCII = 139 1111110111 0xFEC0, // ASCII = 140 1111111011 0xFF40, // ASCII = 141 1111111101 0xFFC0, // ASCII = 142 1111111111 0xAAA0, // ASCII = 143 10101010101 0xAAE0, // ASCII = 144 10101010111 0xAB60, // ASCII = 145 10101011011 0xABA0, // ASCII = 146 10101011101 0xABE0, // ASCII = 147 10101011111 0xAD60, // ASCII = 148 10101101011 0xADA0, // ASCII = 149 10101101101 0xADE0, // ASCII = 150 10101101111 0xAEA0, // ASCII = 151 10101110101 0xAEE0, // ASCII = 152 10101110111 0xAF60, // ASCII = 153 10101111011 0xAFA0, // ASCII = 154 10101111101 0xAFE0, // ASCII = 155 10101111111 0xB560, // ASCII = 156 10110101011 0xB5A0, // ASCII = 157 10110101101 0xB5E0, // ASCII = 158 10110101111 0xB6A0, // ASCII = 159 10110110101 0xB6E0, // ASCII = 160 10110110111 0xB760, // ASCII = 161 10110111011 0xB7A0, // ASCII = 162 10110111101 0xB7E0, // ASCII = 163 10110111111 0xBAA0, // ASCII = 164 10111010101 0xBAE0, // ASCII = 165 10111010111 0xBB60, // ASCII = 166 10111011011 0xBBA0, // ASCII = 167 10111011101 0xBBE0, // ASCII = 168 10111011111 0xBD60, // ASCII = 169 10111101011 0xBDA0, // ASCII = 170 10111101101 0xBDE0, // ASCII = 171 10111101111 0xBEA0, // ASCII = 172 10111110101 0xBEE0, // ASCII = 173 10111110111 0xBF60, // ASCII = 174 10111111011 0xBFA0, // ASCII = 175 10111111101 0xBFE0, // ASCII = 176 10111111111 0xD560, // ASCII = 177 11010101011 0xD5A0, // ASCII = 178 11010101101 0xD5E0, // ASCII = 179 11010101111 0xD6A0, // ASCII = 180 11010110101 0xD6E0, // ASCII = 181 11010110111 0xD760, // ASCII = 182 11010111011 0xD7A0, // ASCII = 183 11010111101 0xD7E0, // ASCII = 184 11010111111 0xDAA0, // ASCII = 185 11011010101 0xDAE0, // ASCII = 186 11011010111 0xDB60, // ASCII = 187 11011011011 0xDBA0, // ASCII = 188 11011011101 0xDBE0, // ASCII = 189 11011011111 0xDD60, // ASCII = 190 11011101011 0xDDA0, // ASCII = 191 11011101101 0xDDE0, // ASCII = 192 11011101111 0xDEA0, // ASCII = 193 11011110101 0xDEE0, // ASCII = 194 11011110111 0xDF60, // ASCII = 195 11011111011 0xDFA0, // ASCII = 196 11011111101 0xDFE0, // ASCII = 197 11011111111 0xEAA0, // ASCII = 198 11101010101 0xEAE0, // ASCII = 199 11101010111 0xEB60, // ASCII = 200 11101011011 0xEBA0, // ASCII = 201 11101011101 0xEBE0, // ASCII = 202 11101011111 0xED60, // ASCII = 203 11101101011 0xEDA0, // ASCII = 204 11101101101 0xEDE0, // ASCII = 205 11101101111 0xEEA0, // ASCII = 206 11101110101 0xEEE0, // ASCII = 207 11101110111 0xEF60, // ASCII = 208 11101111011 0xEFA0, // ASCII = 209 11101111101 0xEFE0, // ASCII = 210 11101111111 0xF560, // ASCII = 211 11110101011 0xF5A0, // ASCII = 212 11110101101 0xF5E0, // ASCII = 213 11110101111 0xF6A0, // ASCII = 214 11110110101 0xF6E0, // ASCII = 215 11110110111 0xF760, // ASCII = 216 11110111011 0xF7A0, // ASCII = 217 11110111101 0xF7E0, // ASCII = 218 11110111111 0xFAA0, // ASCII = 219 11111010101 0xFAE0, // ASCII = 220 11111010111 0xFB60, // ASCII = 221 11111011011 0xFBA0, // ASCII = 222 11111011101 0xFBE0, // ASCII = 223 11111011111 0xFD60, // ASCII = 224 11111101011 0xFDA0, // ASCII = 225 11111101101 0xFDE0, // ASCII = 226 11111101111 0xFEA0, // ASCII = 227 11111110101 0xFEE0, // ASCII = 228 11111110111 0xFF60, // ASCII = 229 11111111011 0xFFA0, // ASCII = 230 11111111101 0xFFE0, // ASCII = 231 11111111111 0xAAB0, // ASCII = 232 101010101011 0xAAD0, // ASCII = 233 101010101101 0xAAF0, // ASCII = 234 101010101111 0xAB50, // ASCII = 235 101010110101 0xAB70, // ASCII = 236 101010110111 0xABB0, // ASCII = 237 101010111011 0xABD0, // ASCII = 238 101010111101 0xABF0, // ASCII = 239 101010111111 0xAD50, // ASCII = 240 101011010101 0xAD70, // ASCII = 241 101011010111 0xADB0, // ASCII = 242 101011011011 0xADD0, // ASCII = 243 101011011101 0xADF0, // ASCII = 244 101011011111 0xAEB0, // ASCII = 245 101011101011 0xAED0, // ASCII = 246 101011101101 0xAEF0, // ASCII = 247 101011101111 0xAF50, // ASCII = 248 101011110101 0xAF70, // ASCII = 249 101011110111 0xAFB0, // ASCII = 250 101011111011 0xAFD0, // ASCII = 251 101011111101 0xAFF0, // ASCII = 252 101011111111 0xB550, // ASCII = 253 101101010101 0xB570, // ASCII = 254 101101010111 0xB5B0 // ASCII = 255 101101011011 }; ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CPskDemodulator::CPskDemodulator(): CDemodulator() { m_pQue1 = NULL; m_pQue2 = NULL; m_pQue3 = NULL; m_VaricodeDecTbl = NULL; Phase= NULL; } CPskDemodulator::~CPskDemodulator() { if(m_pQue1) delete m_pQue1; if(m_pQue2) delete m_pQue2; if(m_pQue3) delete m_pQue3; if(m_VaricodeDecTbl) delete m_VaricodeDecTbl; if(Phase ) delete Phase; } ///////////////////////////////////////////////////////////////// // Initialize PskDet buffers and pointers ///////////////////////////////////////////////////////////////// bool CPskDemodulator::Init( double Fs, int BlockSize ) { unsigned short int wTemp; int i; //circular delay lines.(data stays put and the pointers move) if( (m_pQue1 = new complex[DEC3_LPFIR_LENGTH] ) == NULL) return false; if( (m_pQue2 = new complex[DEC3_LPFIR_LENGTH] ) == NULL) return false; if( (m_pQue3 = new complex[BITFIR_LENGTH] ) == NULL) return false; if( ( m_VaricodeDecTbl = new unsigned char[2048] )== NULL) return false; if ( ( Phase = new complex[228] ) == NULL ) return false; for(int i=0; i(0.0,0.0); } for(i=0; i(0.0,0.0); } for( i=0; i(0.0,0.0); } for( int j=0; j<2048; j++) //init inverse varicode lookup decoder table { m_VaricodeDecTbl[j] = 0; for(int i=0; i<256;i++) { wTemp = VARICODE_TABLE[i]; wTemp >>= 4; while( !(wTemp&1) ) wTemp >>= 1; wTemp >>= 1; if( wTemp == j) m_VaricodeDecTbl[j] = (unsigned char)i; } } m_pInPtr1 = m_pQue1; //initialize que ptrs m_pInPtr2 = m_pQue2; m_pInPtr3 = m_pQue3; SampleRate = Fs; //sample rate NxSamples = BlockSize; //size data input buffer OszFreqinc = 1000.0*PI2/SampleRate; m_BitPhaseInc = 9.0/SampleRate; //bit oversampling period m_SignalLevel = 1.0; m_BitPhasePos = 0.0; m_BitAcc = 0; m_LastBitZero = false; m_SampCnt = 0; m_OnCount = 0; m_OffCount = 0; for (i=0;i< 228; i++) Phase[i]=0.0; for( i=0; i<40; i++) DelayLine[i] = 0.0; // initialize the array // Init a bunch of "static" variables used in various member fuctions m_AGCave = 0.0; m_FreqError = 0.0; OszFrequency = 0.0; m_LastFreq = 1000.0; m_PkPos = 0; m_BitPos = 0; Prev_Sample=complex(0.0,0.0) ; Phase_Vector = Prev_Sample; m_DevAve = 0.78; m_QFreqError = 0.0; m_LastPkPos = 0; m_ClkErrCounter = 0; m_ClkErrTimer = 0; m_ClkError = 0; // Initializing Variables for AFC fe0=0.0; fe1=0.0; fe2=0.0; // FastSquelch fastSquelch=false; // IMD IMD=0.0; // Means Unkonown x_loop_1=0; y_loop_1=0; return true; } ////////////////////////////////////////////////////////////////////// // Main routine called to process the next block of data 'pIn'. // The center frequency is specified by 'Freq'. // 'UseAFC' specifies whether to automatically lock to the frequency. // 30mSec for BPSK, 38mSec for QPSK( 133MHz Pentium ) ////////////////////////////////////////////////////////////////////// void CPskDemodulator::ProcessInput( double* pIn, double *Spectrum) { double vcophz = OszFrequency; int i,j; complex acc; const double* Kptr; complex* Firptr; complex* Inptr1; //decimation FIR #1 variables complex* Qptr1; complex* Inptr2; //decimation FIR #2 variables complex* Qptr2; if ( UseAfc == Wide ) { // Check if we are near the center frequency in Spectrum int index; index=(int) (RxFrequency/2.69165); double smooth[15],xx; // First we smooth the spectrum for(int i=0; i<15; i++) { smooth[i]=0.0; for (int k=0; k <15; k++) smooth[i] +=Spectrum[index-14+k+i]/7; } int maxspect=0; xx=0.0; for(int i=0;i <15; i++) { if (smooth[i] >xx ) { xx=smooth[i]; maxspect=i; } } if ( maxspect < 5 ) // We are far above the Frequency RxFrequency -=1.5; else if (maxspect > 9 ) RxFrequency += 1.5; } m_DispTrig = false; j=0; if( RxFrequency != m_LastFreq ) //caller is changing center frequency { OszFreqinc = (PI2/SampleRate)*RxFrequency; //new center freq inc m_LastFreq = RxFrequency; } Inptr1 = m_pInPtr1; //use local copies of member variables Qptr1 = m_pQue1; // for better speed. Inptr2 = m_pInPtr2; Qptr2 = m_pQue2; for( i = 0; i PI2) //handle 2 Pi wrap around vcophz -= PI2; *Inptr1=pIn[i]*complex(cos(vcophz),sin(vcophz)); //decimate by 3 filter if( ( (++m_SampCnt)%3 ) == 0 ) //calc first decimation filter every 3 samples { acc=complex(0.0,0.0); Firptr = Inptr1; Kptr = Dec3LPCoef; while( Kptr < (Dec3LPCoef + DEC3_LPFIR_LENGTH) ) //do the MAC's { acc +=(*Firptr)*(*Kptr++); if( (++Firptr) >= Qptr1+DEC3_LPFIR_LENGTH ) //deal with wraparound Firptr = Qptr1; } if( --Inptr2 < Qptr2 ) //deal with FIR pointer wrap around Inptr2 = Qptr2+DEC3_LPFIR_LENGTH-1; *Inptr2=acc; //decimate by 3 filter if( (m_SampCnt%9) == 0 ) //calc second decimation filter every 9 samples { acc=complex(0.0,0.0); Firptr = Inptr2; Kptr = Dec3LPCoef; while( Kptr < (Dec3LPCoef + DEC3_LPFIR_LENGTH) ) //do the MAC's { acc +=(*Firptr)*(*Kptr); Kptr++; if( (++Firptr) >= Qptr2+DEC3_LPFIR_LENGTH ) //deal with wraparound Firptr = Qptr2; } // here at Fs/9 = 612.5 Hz rate with latest sample in acc. // Matched Filter the I and Q data and also a frequency error filter // filter puts filtered signals in m_FreqSignal and m_BitSignal. CalcBitFilter( acc ); if( SymbSync(m_BitSignal) ) { Phase_Vector=m_BitSignal*conj(Prev_Sample); Prev_Sample = m_BitSignal; Phase[j++]=Phase_Vector; double angle = atan2(Phase_Vector.imag(),Phase_Vector.real()); DecodeSymbol( angle); if ( (unsigned int) m_DevAve > Threshold) { if (m_OffCount > 10) calcIMD(Spectrum); // We got enough Idles to calc the IMD } else IMD =0.0; if( UseAfc != Off ) OszFreqinc +=CalcFreqError(Phase_Vector); } } } } m_SampCnt = m_SampCnt%9; m_pInPtr1 = Inptr1; // save position in circular delay line m_pInPtr2 = Inptr2; // save position in circular delay line OszFrequency = vcophz; if (UseAfc != Off) // Change RxFrequency, but slowly { RxFrequency=OszFreqinc*SampleRate/PI2; m_LastFreq=RxFrequency; } } ////////////////////////////////////////////////////////////////////// // Called at Fs/9 rate to calculate the symbol sync position // Returns true if at center of symbol. // Sums up the energy at each sample time, averages it, and picks the // sample time with the highest energy content. ////////////////////////////////////////////////////////////////////// bool CPskDemodulator::SymbSync(complex sample) { bool Trigger; int BitPos = m_BitPos; Trigger=false; DelayLine[BitPos]=sample; m_BitPhasePos += m_BitPhaseInc; if( m_BitPhasePos >= Ts ) { // here every symbol time m_BitPhasePos -= Ts; float x,y,maxsample; int kk; x=0; maxsample=-1; for(int i=0; i <10;i++) { kk= BitPos-i-10; if (kk < 0) kk += 40; y= abs(DelayLine[kk]); maxsample=max(maxsample,y); x += y; kk = BitPos-i; if (kk < 0) kk += 40; y = abs(DelayLine[kk]); maxsample=max(maxsample,y); x -= y; } maxsample = 3.* maxsample; if ( x < -maxsample ) m_BitPhasePos += m_BitPhaseInc; else if ( x > maxsample) m_BitPhasePos -= m_BitPhaseInc; Trigger=true; } BitPos++; if ( BitPos >= 40 ) BitPos=0; m_BitPos=BitPos; return Trigger; } ////////////////////////////////////////////////////////////////////// // Frequency error calculator ////////////////////////////////////////////////////////////////////// double CPskDemodulator::CalcFreqError(complex s) { double x,y; complex z; if (abs(s) >1 ) z=s/abs(s); else z=s; x= z.real()*z.imag(); x /=10000.; // Adopt deviation to samplerate // x /=2.8016548; //Gain y=x_loop_1+x +0.2861361823*y_loop_1; x_loop_1=x; y_loop_1=y; return -y; } ////////////////////////////////////////////////////////////////////// // Automatic gain control calculator ////////////////////////////////////////////////////////////////////// double CPskDemodulator::CalcAGC( complex Samp) { double mag; mag = abs(Samp); if( mag > m_AGCave ) m_AGCave = (1.0-1.0/250.0)*m_AGCave + (1.0/250.0)*mag; else m_AGCave = (1.0-1.0/1000.0)*m_AGCave + (1.0/1000.0)*mag; if( m_AGCave >= 1.0 ) // divide signal by ave if not almost zero { m_BitSignal /= m_AGCave; // m_BitSignal.y /= m_AGCave; m_FreqSignal /= m_AGCave; // m_FreqSignal.y /= m_AGCave; } return(m_AGCave); } ////////////////////////////////////////////////////////////////////// // BIT FIR filters. A narrow matched(?) data filter for data // and wider filter for the AFC/AGC functions ////////////////////////////////////////////////////////////////////// void CPskDemodulator::CalcBitFilter(complex Samp) { complex acc1; complex acc2; const double* Kptr1; const double* Kptr2; complex* Firptr; complex* Qptr; complex* Inptr; Inptr = m_pInPtr3; //use local copies of member variables Qptr = m_pQue3; // for better speed. if( --Inptr < Qptr ) //deal with LPFIR pointer wrap around Inptr = Qptr+BITFIR_LENGTH-1; // Inptr->x = Samp.x; //place in circular Queue *Inptr = Samp; // acc1.x = 0.0; acc1 = complex(0.0,0.0); // acc2.x = 0.0; acc2 = complex(0.0,0.0); Firptr = Inptr; Kptr1 = FreqFirCoef; //frequency error filter Kptr2 = BitFirCoef; //bit data filter while( Kptr2 < (BitFirCoef + BITFIR_LENGTH) ) //do the MAC's { // acc1.x += ( (Firptr->x)*(*Kptr1) ); acc1 += ( (*Firptr)*(*Kptr1++) ); // acc2.x += ( (Firptr->x)*(*Kptr2) ); acc2 += ( (*Firptr)*(*Kptr2++) ); if( (++Firptr) >= (Qptr+BITFIR_LENGTH) ) //deal with wraparound Firptr = Qptr; } m_pInPtr3 = Inptr; // save position in circular delay line m_FreqSignal = acc1; m_BitSignal = acc2; } complex * CPskDemodulator::getPhasePointer() { return Phase; } int CPskDemodulator::getSquelchValue() { return (int) m_DevAve; } void CPskDemodulator::calcIMD(double *Spectrum) { int freq1,freq2; freq1 = (int) ((RxFrequency+15.625)/2.69165); freq2 = (int) ((RxFrequency+46.875)/2.69165); IMD=(Spectrum[freq2-1]+Spectrum[freq2]+Spectrum[freq2+1])/(Spectrum[freq1-1]+Spectrum[freq1]+Spectrum[freq1+1]); freq1=(int) ( (RxFrequency- 15.625)/2.69165); freq2=(int) ( (RxFrequency- 46.875)/2.69165); IMD = 10.*log10( (IMD + (Spectrum[freq2-1]+Spectrum[freq2]+Spectrum[freq2+1])/(Spectrum[freq1-1]+Spectrum[freq1]+Spectrum[freq1+1]))/2); } float CPskDemodulator::getIMD() { return IMD; } AfcMode CPskDemodulator::AfcProperties() { return Wide; } linpsk/src/input.h0000644000175000017500000000415511337745306014367 0ustar schroerschroer/*************************************************************************** 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/src/rttymodulator.h0000644000175000017500000000417411337745306016162 0ustar schroerschroer/*************************************************************************** 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/src/crecording.cpp0000644000175000017500000000401011337745306015670 0ustar schroerschroer/*************************************************************************** |FILENAME| - description ------------------- begin : |DATE| copyright : (C) |YEAR| by |AUTHOR| email : |EMAIL| ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #include "crecording.h" #include #include #include #include #include /* * Constructs a CRecording which is a child of 'parent', with the * name 'name'.' */ CRecording::CRecording( QWidget* parent ) : QGroupBox( parent ) { Record = new QRadioButton( this); languageChange(); } /* * Destroys the object and frees any allocated resources */ CRecording::~CRecording() { // no need to delete child widgets, Qt does it all for us } /* * Sets the strings of the subwidgets using the current * language. */ void CRecording::languageChange() { Record->setText( tr( "Record QSO" ) ); } void CRecording::resizeEvent( QResizeEvent * ) { calculateSizeofComponents(); } void CRecording::calculateSizeofComponents() { /** Margins **/ #define LEFTMARGIN 5 #define TOPMARGIN 30 int innerwidth,innerheight,xpos,ypos,width,height; width=this->width(); height=this->height(); xpos=width*LEFTMARGIN/100; ypos=height*TOPMARGIN/100; innerwidth=width-2*xpos; innerheight=height-3*ypos/2; Record->setGeometry(xpos,ypos,innerwidth,innerheight); } linpsk/src/waveinput.h0000644000175000017500000000402011337745306015241 0ustar schroerschroer/*************************************************************************** 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/src/fskmodulator.h0000644000175000017500000000304411337745306015736 0ustar schroerschroer/*************************************************************************** fskmodulator.h - description ------------------- begin : Sam Mr 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 FSKMODULATOR_H #define FSKMODULATOR_H #include "cmodulator.h" /** *@author Volker Schroer */ class FSKModulator : public CModulator { public: FSKModulator(int,CTxBuffer *); ~FSKModulator(); int CalcSignal( double* pData , int n); protected: virtual int getToneNumber()=0; unsigned int NumberofTones; //double *ToneFrequencyr; //double *ToneFrequencyi; double ToneFrequencyr[16]; double ToneFrequencyi[16]; double Frequencyr,Frequencyi; unsigned int SamplesperSymbol; float Baudrate; unsigned int NxSamples; private: int c; }; #endif linpsk/src/mfskvaricode.cpp0000644000175000017500000000620211337745306016233 0ustar schroerschroer/*************************************************************************** mfskvaricode.cpp - description ------------------- begin : Sam Mr 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/src/spectrumdisplay.cpp0000644000175000017500000002045111337745306017010 0ustar schroerschroer/*************************************************************************** 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 #include "spectrumdisplay.h" #include "crxchannel.h" #include "parameter.h" #include "color.h" #define SPECTRUMHEIGHT 70 #define WATERFALLHEIGHT 20 #define LABELHEIGHT 10 #define DISTANCE 3 extern Parameter settings; SpectrumDisplay::SpectrumDisplay ( QWidget* parent ) : QFrame ( parent ) { setFrameShape( QFrame::StyledPanel); setFrameShadow(QFrame::Sunken ); MaxFreq = new QSpinBox ( parent ); MaxFreq->setMaximum ( 2500 ); MaxFreq->setMinimum ( 1300 ); MaxFreq->setValue ( 2500 ); MaxFreq->setSingleStep ( 100 ); MinFreq = new QSpinBox ( parent ); MinFreq->setButtonSymbols ( QSpinBox::UpDownArrows ); MinFreq->setMaximum ( 1200 ); MinFreq->setMinimum ( 100 ); MinFreq->setSingleStep ( 100 ); Smooth=new QRadioButton(tr("Smooth"),parent); languageChange(); inputdata = 0; Phase = 0; Farbe=0; // Connections connect ( this, SIGNAL ( frequencyChanged ( int ) ), this, SLOT ( setnewFrequency ( int ) ) ); for(int i=0; i< 1024;i++) smoothedfft[i]=0.; } /* * Destroys the object and frees any allocated resources */ SpectrumDisplay::~SpectrumDisplay() { // no need to delete child widgets, Qt does it all for us } /* * Sets the strings of the subwidgets using the current * language. */ void SpectrumDisplay::languageChange() { MaxFreq->setSuffix ( " Hz" ); MinFreq->setSuffix ( " Hz" ); } void SpectrumDisplay::resizeEvent ( QResizeEvent * ) { calculateSizeofComponents(); translate(); calcFFT(); plotspectrum ( false ); } void SpectrumDisplay::calculateSizeofComponents() { int xpos, ypos, width, height, innerheight, innerwidth; width = this->width(); height =this->height(); /** Display **/ xpos = 0; ypos = height * DISTANCE / 100; innerwidth=width-2*this->frameWidth(); innerheight = height * SPECTRUMHEIGHT / 100; pdisplay =QPixmap ( innerwidth,innerheight); pwaterfall=QPixmap(innerwidth,height-innerheight); pwaterfall.fill(Qt::black); /** Controlelements of the display **/ ypos = ypos + height + DISTANCE * height / 100; innerheight = height * LABELHEIGHT / 100; innerwidth = ( width - 2 * xpos ) / 4; xpos = x(); MinFreq->setGeometry ( xpos, ypos, innerwidth, innerheight ); //xpos=this->width()-innerwidth; Smooth->setGeometry(xpos+width/2-innerwidth/2,ypos,innerwidth, innerheight ); xpos = xpos + width - innerwidth; MaxFreq->setGeometry ( xpos, ypos, innerwidth, innerheight ); } // Plot Spectrum of decimated Input void SpectrumDisplay::plotspectrum ( bool overload ) { QPainter p; int dist, y1, y2, z, ymax, xmax; int minfreq, maxfreq; double scale; scale = ( pdisplay.height() - 15 ) / 100.; minfreq = MinFreq->value(); maxfreq = MaxFreq->value(); ymax = pdisplay.height()-4; // Subtract Frame dist = ymax / 10; xmax = pdisplay.width(); pdisplay.fill(); p.begin ( &pdisplay ); p.setBrush ( Qt::white ); //Plot Frequencylines for the different Rx- Windows for (CRxChannel *pRx=settings.ChannelChain;pRx != 0;pRx= pRx->getNextChannel()) { if ( Farbe->size() > 0) { int ID = pRx->getID(); if ( ID >= 0 && ID < Farbe->size() ) p.setPen(Farbe->at(ID)); } // Calculate Centerfrequency Coordinates z=(int)((( pRx->getRxFrequency()-minfreq)*xmax)/(maxfreq-minfreq)+0.5); p.drawLine(z,0,z,ymax); if ( (z = pRx->get2RxFrequency()) != 0 ) // RTTY demands to lines { z=(( z-minfreq)*xmax)/(maxfreq-minfreq); p.drawLine(z,0,z,ymax); } } if ( overload ) p.setPen ( Qt::red ); else p.setPen ( Qt::blue ); // Plot Lineal and grid p.setPen ( Qt::black ); paintLineal ( &p, xmax, ymax ); if ( inputdata != 0 ) { for ( int i = 1;i < xmax;i++ ) { y1 = ymax - ( int ) ( scale * fftdata[i-1] ) - 15; y2 = ymax - ( int ) ( scale * fftdata[i] ) - 15; p.drawLine ( i - 1, y1, i, y2 ); } if ( Phase != 0 ) plotVector ( &p ); } p.end(); if ( inputdata != 0 ) { xmax = pwaterfall.width(); p.begin(&pwaterfall); p.drawPixmap(0,2,pwaterfall,0,0,pwaterfall.width(),pwaterfall.height()-2); for (int i=0;i 255) y1 = 255; else if ( y1 < 0 ) y1= 0; p.setPen(color[y1]); p.drawPoint(i,0); p.drawPoint(i,1); } p.end(); } update(); } void SpectrumDisplay::calcFFT() { if ( inputdata == 0 ) return; // No data available for ( int i = 0;i < pdisplay.width();i++ ) if( Smooth->isChecked()) { float x=( log10 ( inputdata[xtranslate[i]] + 100. ) - 2. ); float gain=(1. - exp(-(0.2 * x))); smoothedfft[i]=smoothedfft[i]*(1.-gain) + gain *x; fftdata[i] = ( int ) (20.*smoothedfft[i]); } else //18.4 scales to a range from 0 - 100, as max(inputdata ) = fft_length/4 ^ 2 fftdata[i] = ( int ) ( 18.4 * ( log10 ( inputdata[xtranslate[i]] + 100. ) - 2. ) ); // For Color scale should be 18.4 *2.55 } void SpectrumDisplay::translate ( void ) { int i, to, minfreq, maxfreq, displaywidth; minfreq = MinFreq->value(); maxfreq = MaxFreq->value(); to = int ( maxfreq * 1024 / 2756.25 ); displaywidth = pdisplay.width(); for ( i = 0;i < displaywidth;i++ ) xtranslate[i] = ( ( ( maxfreq - minfreq ) * i * to / displaywidth ) + minfreq * to ) / maxfreq; } void SpectrumDisplay::startPlot ( double *x, bool overload ) { inputdata = x; translate(); calcFFT(); plotspectrum ( overload ); } void SpectrumDisplay::setnewFrequency ( int position ) { double freq; int ii; ii = pdisplay.width(); freq = ( position * ( MaxFreq->value() - MinFreq->value() ) ) / ii + MinFreq->value(); settings.ActChannel->setRxFrequency ( freq ); emit FrequencyChanged ( freq ); } void SpectrumDisplay::paintLineal ( QPainter* p, int xmax, int ymax ) { int stepfrequency; float stepwidth; int i, ix, NumberofFreqs, diff; int y; QString frequency; QFontMetrics fm ( this->font() ); int minfreq = MinFreq->value(); // Calcalute Frequency- Steps diff = ( MaxFreq->value() - minfreq ); NumberofFreqs = 7; while ( NumberofFreqs > 4 ) { stepfrequency = diff / NumberofFreqs; if ( (stepfrequency * NumberofFreqs) != diff ) NumberofFreqs--; else break; } stepwidth = float ( xmax ) / NumberofFreqs; diff = ymax / 10; y = ymax - diff; for ( i = 1; i < NumberofFreqs; i++ ) { ix = ( int ) ( i * stepwidth + 0.5 ); p->drawLine ( ix, y, ix, y - 3 ); frequency.setNum ( minfreq + stepfrequency*i ); ix = ix - fm.width ( frequency ) / 2; p->drawText ( ix, ymax, frequency ); } // Plot Grid for ( i = 1;i < 10; i++ ) { p->drawLine ( 0, y, xmax, y ); y -= diff; } } void SpectrumDisplay::plotVector ( QPainter *p ) { int xc, yc; double mag; xc = pdisplay.width() / 8; yc = pdisplay.height() / 8; p->drawEllipse ( xc, yc, 40, 40 ); xc = xc + 20; yc = yc + 20; p->setPen ( Qt::green ); for(int i=0; i< 11; i++) { mag=abs(Phase[i]); if ( mag > 0.001) p->drawLine(xc,yc,xc - (int)(20.*Phase[i].imag()/mag), yc - (int)(20.*Phase[i].real()/mag) ); } } void SpectrumDisplay::setPhasePointer ( std::complex *p ) { Phase = p; } void SpectrumDisplay::setColorList ( QList *c ) { Farbe=c; } void SpectrumDisplay::mousePressEvent ( QMouseEvent *e ) { emit frequencyChanged ( e->x() - lineWidth() ); } void SpectrumDisplay::paintEvent(QPaintEvent *e) { QFrame::paintEvent(e); QPainter p(this); p.drawPixmap(frameWidth(),frameWidth(),pdisplay); p.drawPixmap(frameWidth(),frameWidth()+pdisplay.height()-4,pwaterfall); } linpsk/src/viterbisoft.h0000644000175000017500000000737011337745306015572 0ustar schroerschroer/*************************************************************************** viterbisoft.h - description ------------------- begin : Sam Mr 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 viterbisoft_H #define viterbisoft_H #define MEMORYLENGTH 256 #define NumberOfRTTYSampleStates 269 /** *@author Volker Schroer */ class ViterbiSoft { public: ViterbiSoft ( const double ( * ) ( double *, int ) ); ~ViterbiSoft(); // void decode(int,const double (*)(int,int)); void decode ( double * ); int getBit ( unsigned int i ); enum RTTYSampleStates {Start1 = 0,Start2,Start3,Start4,Start5,Start6,Start7,Start8,Start9,Start10,Start11, Stop1,Stop2,Stop3,Stop4,Stop5,Stop6,Stop7,Stop8,Stop9,Stop10,Stop11,Stop12,Stop13,Stop14,Stop15,Stop16, D1_0_1,D1_0_2,D1_0_3,D1_0_4,D1_0_5,D1_0_6,D1_0_7,D1_0_8,D1_0_9,D1_0_10,D1_0_11, D1_1_1,D1_1_2,D1_1_3,D1_1_4,D1_1_5,D1_1_6,D1_1_7,D1_1_8,D1_1_9,D1_1_10,D1_1_11, D2_0_1,D2_0_2,D2_0_3,D2_0_4,D2_0_5,D2_0_6,D2_0_7,D2_0_8,D2_0_9,D2_0_10,D2_0_11, D2_1_1,D2_1_2,D2_1_3,D2_1_4,D2_1_5,D2_1_6,D2_1_7,D2_1_8,D2_1_9,D2_1_10,D2_1_11, D3_0_1,D3_0_2,D3_0_3,D3_0_4,D3_0_5,D3_0_6,D3_0_7,D3_0_8,D3_0_9,D3_0_10,D3_0_11, D3_1_1,D3_1_2,D3_1_3,D3_1_4,D3_1_5,D3_1_6,D3_1_7,D3_1_8,D3_1_9,D3_1_10,D3_1_11, D4_0_1,D4_0_2,D4_0_3,D4_0_4,D4_0_5,D4_0_6,D4_0_7,D4_0_8,D4_0_9,D4_0_10,D4_0_11, D4_1_1,D4_1_2,D4_1_3,D4_1_4,D4_1_5,D4_1_6,D4_1_7,D4_1_8,D4_1_9,D4_1_10,D4_1_11, D5_0_1,D5_0_2,D5_0_3,D5_0_4,D5_0_5,D5_0_6,D5_0_7,D5_0_8,D5_0_9,D5_0_10,D5_0_11, D5_1_1,D5_1_2,D5_1_3,D5_1_4,D5_1_5,D5_1_6,D5_1_7,D5_1_8,D5_1_9,D5_1_10,D5_1_11, D6_0_1,D6_0_2,D6_0_3,D6_0_4,D6_0_5,D6_0_6,D6_0_7,D6_0_8,D6_0_9,D6_0_10,D6_0_11, D6_1_1,D6_1_2,D6_1_3,D6_1_4,D6_1_5,D6_1_6,D6_1_7,D6_1_8,D6_1_9,D6_1_10,D6_1_11, D7_0_1,D7_0_2,D7_0_3,D7_0_4,D7_0_5,D7_0_6,D7_0_7,D7_0_8,D7_0_9,D7_0_10,D7_0_11, D7_1_1,D7_1_2,D7_1_3,D7_1_4,D7_1_5,D7_1_6,D7_1_7,D7_1_8,D7_1_9,D7_1_10,D7_1_11, D8_0_1,D8_0_2,D8_0_3,D8_0_4,D8_0_5,D8_0_6,D8_0_7,D8_0_8,D8_0_9,D8_0_10,D8_0_11, D8_1_1,D8_1_2,D8_1_3,D8_1_4,D8_1_5,D8_1_6,D8_1_7,D8_1_8,D8_1_9,D8_1_10,D8_1_11, D9_0_1,D9_0_2,D9_0_3,D9_0_4,D9_0_5,D9_0_6,D9_0_7,D9_0_8,D9_0_9,D9_0_10,D9_0_11, D9_1_1,D9_1_2,D9_1_3,D9_1_4,D9_1_5,D9_1_6,D9_1_7,D9_1_8,D9_1_9,D9_1_10,D9_1_11, D10_0_1,D10_0_2,D10_0_3,D10_0_4,D10_0_5,D10_0_6,D10_0_7,D10_0_8,D10_0_9,D10_0_10,D10_0_11, D10_1_1,D10_1_2,D10_1_3,D10_1_4,D10_1_5,D10_1_6,D10_1_7,D10_1_8,D10_1_9,D10_1_10,D10_1_11, D11_0_1,D11_0_2,D11_0_3,D11_0_4,D11_0_5,D11_0_6,D11_0_7,D11_0_8,D11_0_9,D11_0_10,D11_0_11, D11_1_1,D11_1_2,D11_1_3,D11_1_4,D11_1_5,D11_1_6,D11_1_7,D11_1_8,D11_1_9,D11_1_10,D11_1_11}; RTTYSampleStates getState(unsigned int i); private: int BitCount; int StopBitCount; int NumberofStates; int MinimumPath; int BitTable[NumberOfRTTYSampleStates]; RTTYSampleStates StateTable[2][NumberOfRTTYSampleStates]; const double ( *dist ) ( double [], int ); double Metric[NumberOfRTTYSampleStates]; RTTYSampleStates PathMem[NumberOfRTTYSampleStates][MEMORYLENGTH]; int pathPointer; }; #endif linpsk/src/ctxdisplay.h0000644000175000017500000000322011337745306015404 0ustar schroerschroer/*************************************************************************** |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 //class QVBoxLayout; //class QHBoxLayout; //class QGridLayout; //class CTxFunctions; class CLedButton; class CTxWindow; class FrequencySelect; class CTxDisplay : public QFrame { Q_OBJECT public: CTxDisplay( QWidget* parent = 0); ~CTxDisplay(); CTxWindow* TxWindow; FrequencySelect* TxFreq; // CTxFunctions* TxFunctions; CLedButton *TxFunctions; public slots: void abbruch(); protected: void resizeEvent( QResizeEvent * ); protected slots: virtual void languageChange(); private: void calculateSizeofComponents(); signals: void startRx(); void startTx(); }; #endif // CTXDISPLAY_H linpsk/src/qpskmodulator.cpp0000644000175000017500000000625511337745306016473 0ustar schroerschroer/*************************************************************************** qpskmodulator.cpp - 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 Wheatly, AE4JY * ***************************************************************************/ #include "qpskmodulator.h" #include "constants.h" #define SYM_OFF 4 //No output #define SYM_ON 5 //constant output // For the QPSK modulator/demodulator, rate 1/2 constraint length 5 // convolutional FEC coding is used. // The generator polynomials used are: // g1(x) = x^4 + x^3 + 1 = 0x19 // g0(x) = x^4 + x^2 + x + 1 = 0x17 // // g1(x) // /----+--------+--------------------------+ // / | | | // symbol msb --- --- --- --- --- // | b4|<---| b3|<---| b2|<---| b1|<---| b0| <-- inverted data in // symbol lsb --- --- --- --- --- // \ | | | | // \----+-----------------+--------+--------+ // g0(x) // // Lookup table to get symbol from non-inverted data stream static const unsigned char ConvolutionCodeTable[32] = { 2, 1, 3, 0, 3, 0, 2, 1, 0, 3, 1, 2, 1, 2, 0, 3, 1, 2, 0, 3, 0, 3, 1, 2, 3, 0, 2, 1, 2, 1, 3, 0 }; QPskModulator::QPskModulator(int FS,double freq,CTxBuffer *TxBuffer):PSKModulator(FS,freq,TxBuffer) { m_TxCodeWord = 0; } QPskModulator::~QPskModulator() { } char QPskModulator::GetNextSymbol(void) { char symb; int ch; symb = ConvolutionCodeTable[m_TxShiftReg&0x1F]; //get next convolution code m_TxShiftReg = m_TxShiftReg<<1; if( m_TxCodeWord == 0 ) //need to get next codeword { if( m_AddEndingZero ) //if need to add a zero { m_AddEndingZero = false; //end with a zero } else { ch = GetChar(); //get next character to xmit if( ch >=0 ) //if not a control code { //get next VARICODE codeword to send m_TxCodeWord = VARICODE_TABLE[ ch&0xFF ]; } else //is a control code { switch( ch ) { case TXON_CODE: symb = SYM_ON; break; case TXTOG_CODE: m_TxCodeWord = 0; break; case TXOFF_CODE: symb = SYM_OFF; break; } } } } else { if(m_TxCodeWord&0x8000 ) { m_TxShiftReg |= 1; } m_TxCodeWord = m_TxCodeWord<<1; if(m_TxCodeWord == 0) m_AddEndingZero = true; //need to add another zero } return symb; } linpsk/src/mfskdemodulator.cpp0000644000175000017500000001364311337745306016765 0ustar schroerschroer/*************************************************************************** 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 const double MFSKDistance ( double *xa, int b ) { double dist; int a1, a2; a1 = ( b & 2 ) >> 1; a2 = b & 1; dist = abs ( xa[0] - a1 ) + abs ( xa[1] - a2 ); return dist; } MFSKDemodulator::MFSKDemodulator() : CDemodulator() { OszFrequency = 0.; Decoder = new MFSKVaricode(); viterbi = new Viterbi ( 7, 0x6D, 0x4F, MFSKDistance ); datashreg = 0; } MFSKDemodulator::~MFSKDemodulator() { if ( viterbi != 0 ) delete viterbi; if ( Decoder != 0 ) delete Decoder; } void MFSKDemodulator::ProcessInput ( double * input, double * ) { // Mix and downsample mixdown ( input ); // Result is now in downBuffer bitEstimate(); } int MFSKDemodulator::getSquelchValue() { return 0; } bool MFSKDemodulator::Init ( double FS, int NumberofSamples ) { int i; NxSamples = NumberofSamples; SampleRate = FS; // OszFreqinc = ( RxFrequency - 1000. ) * PI2 / SampleRate; OszFreqinc = 2.*M_PI * ( RxFrequency - 4*SampleRate / ( DOWNRATE * DELAY ) ) / SampleRate; OszFrequency = 0.; leave = new Deinterleaver ( 10 ); processPtr = 0; bitEstimatePtr = 0; syncPtr = 0; oscPos = 6; for ( i = 0;i < DELAY;i++ ) delayLine[i] = complex ( 0.0, 0.0 ); for ( i = 0; i < RESOLUTION;i++ ) twiddles[i] = complex ( cos ( i * M_PI / RESOLUTION ), - sin ( i * M_PI / RESOLUTION ) ); return true; } void MFSKDemodulator::afc ( int freq,double energy ) { if ( UseAfc == Off ) return; if ( (( freq - oscPos ) > 30) && (energy > 10) ) { oscPos = freq - 30; RxFrequency +=( oscPos-6 ) *7.8125 ; return; } if ( (freq < oscPos) && (energy > 10) ) { oscPos = freq; RxFrequency+= ( oscPos-6 ) *7.8125 ; } } void MFSKDemodulator::recvbit ( int bit ) { int c; char zeichen; datashreg = ( datashreg << 1 ); c = !! bit; datashreg = datashreg | c; /* search for "001" */ c = datashreg & 7; if ( ( datashreg & 7 ) == 1 ) { /* the "1" belongs to the next symbol */ c = Decoder->decode ( datashreg >> 1 ); zeichen = c; if ( c != -1 ) emit newSymbol ( ( char ) c ); /* we already received this */ datashreg = 1; } } double MFSKDemodulator::get2RxFrequency() { return RxFrequency + NumberofTones*15.625; } AfcMode MFSKDemodulator::AfcProperties() { return Narrow; } void MFSKDemodulator::mixdown ( double * inputBuffer ) { complex 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];; // 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/src/linpsk.h0000644000175000017500000000676011337745306014534 0ustar schroerschroer/*************************************************************************** |FILENAME| - description ------------------- begin : |DATE| copyright : (C) |YEAR| by |AUTHOR| email : |EMAIL| ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * The PSK part is based on WinPSK 1.0 by Moe Wheatley, AE4JY * ***************************************************************************/ #ifndef LINPSK_H #define LINPSK_H #include #include #include "constants.h" class QActionGroup; class QToolBar; class QMenu; class QCloseEvent; class CRxDisplay; class CTxDisplay; class ControlPanel; class QLabel; class CModulator; class CTxBuffer; class Input; class Macros; class Parameter; class LinPSK : public QMainWindow { Q_OBJECT public: LinPSK( QWidget* parent = 0,Qt::WFlags fl = 0); ~LinPSK(); CRxDisplay* RxDisplay; CTxDisplay* TxDisplay; ControlPanel* Control; QMenuBar *menubar; QMenu *fileMenu; QMenu *editMenu; QMenu *changeRxParams; QMenu *helpMenu; public slots: virtual void fileOpen(); virtual void Exit(); virtual void helpIndex(); virtual void helpContents(); virtual void helpAbout(); virtual void addRxWindow(); virtual void generalSettings(); virtual void chooseColor(); protected: void resizeEvent(QResizeEvent *); protected slots: virtual void languageChange(); /** Show Time */ void setclock(); /** Set IMD */ void setIMD(float); /** Start Rx **/ void startRx(); /** Start Tx **/ void startTx(); /** Calculate the TX Data **/ void process_txdata(); /** Font Settings **/ void FontSetup(); /** Switching from TX to RX after TX- Bufefr ist empty **/ void stopTx(); /** apply the settings **/ void apply_settings(); /** Changig some Channel Parameters **/ void setChannelParams(); /** Changing Rx Mode ( Moulation type ) **/ void setRxMode(); /** Save Settings **/ void saveSettings(); /** Executing Macros **/ void executeMacro(int); /** Add Macro **/ void addMacro(); /** Edit Macro **/ void editMacro(); /** Delete Macro **/ void deleteMacro(); /** Rename Macro **/ void renameMacro(); /** Recording **/ void recording(bool); /** About Info **/ void HelpAbout(); /** Closing this window **/ void closeEvent( QCloseEvent *); private: void calculateSizeofComponents(); void read_config(); void save_config(); Parameter *SaveParameters; /** Modulator **/ CModulator *Modulator; /** Characters to transmit **/ CTxBuffer *TxBuffer; /** Signalbuffer **/ double Output[BUF_SIZE]; /** Numbers of Char to transmit **/ unsigned int Txcount; /** Sound Device **/ Input *Sound; /** To show messages in Statusbar */ QLabel *msg; /** TxTimer **/ ///QTimer *TxTimer; void selectPTTDevice(); /** To show date and time **/ QLabel *datum; QLabel *zeit; QLabel *IMD; QLabel *clockadj; Macros *Macro; QList WindowColors; }; #endif // LINPSK_H linpsk/README0000644000175000017500000000113411337745305013141 0ustar schroerschroerTo build linpsk, untar the tar archiv and switch to the linpsk directory. run: qmake -unix -o Makefile linpsk.pro make The executable linpsk is build in the bin subdirectory. Move the binary into prefered location , probably /usr/local/bin LinPSK now uses the alsa sound system. The names of the used alsa devices are LinPSK_Record and LinPSK_Play. To map these names to your soundcard edit the file asoundrc in the linpsk directory appropriately and append it to .asoundrc in your homedirectory. If no .asoundrc exists copy the edited asoundrc to .asoundrc in your homedirectory instead of appending.linpsk/images/0000755000175000017500000000000011337745306013530 5ustar schroerschroerlinpsk/images/linpsk.png0000644000175000017500000000044611337745306015542 0ustar schroerschroerPNG  IHDR szzIDATxV Eg+>21:o碒A r#i"}Yr8F7! h -zV8xg}337[WL{pAmbak pW՚Zܬ΄8=p _u ?p73*5!y ğRJ#^Xu1h@߄Ex5b D?d.IqIENDB`linpsk/linpsk.pro0000644000175000017500000000035211337745305014304 0ustar schroerschroerCONFIG += warn_on \ qt \ thread \ ordered \ debug DESTDIR = . SUBDIRS += gui \ src CONFIG -= debug QT += network TEMPLATE = subdirs LIBS += gui/libgui.a TARGETDEPS += gui/libgui.a \ src/../bin/linpsk linpsk/ChangeLog0000644000175000017500000000473111337745305014041 0ustar schroerschroerLinPsk ChangeLog 1.1 Fixed wrong code for 'LF' in rttymodulator.cpp, Thanks to kf9a 'Home key' mapped to 'cr' Possibility introduced to send 'CR' 'LF' on enter key. Selectable by setup. Reintroduced squelch for rtty . Expand auto CR LF to sendfile 1.0 Reading and writing data from /to soundcard now happens in an extra threads. Switch from qt3 to qt4. This implies major modifications of gui code. LinPsk now supports Loging via LinLog New menu for taking qso data for loging. ( Right mouse click in the active rx window ) MFSK16 is now operational. Thanks to Chen, W7AY, who gave me the essential hints. 0.9 Switching from portaudio to native alsa support Modified Afc for BPSK31 decoder Integrating patches 0.8.1 Improved RTTY decoder Setting for slashed 0 now will be saved Fixed some memory leakages Removed dependancy on qwindowsstyle.h, so LinPsk now should compile on Slackware without problems. Some minor bugfixes 0.8.0.4 Experimental RTTY decoder ( rtty2 ). Now 8 bit wav files in Demo mode will be supported. In RTTY shifts up to 999 Hz are possible now. RTTY is now able to transmit in LSB. USB to Serial Converter for RX/TX switching now really works Hopefully fixed crash on quit Using UTC in QSOData 0.8.0.3 New features Supporting USB to Serial Converter for RX/TX switching ( Due to missing hardware untested ) Looks in the /dev directory for devices that contain the string usbserial. added to General Settings Delete macro Rename macro Save QSOData now implemented Data are saved in ADIF format. You can set the name of this file in General settings. The file will be located in the users home directory. Command c now copies text from the clipboard into the tx buffer, if the TX window is the active window. The proportion between colour spectrum and spectrum can be modified. Fixes Hopefully fixed the reported freeze when switching from TX to RX. Fixed that portaudio changes the output volume when level < 10. Now squelch changes colour when the level goes above selected squelch level ( like LinPsk does). Some minor bugs fixed. Now using qt 3.3.2 , which improves the layout of some buttons. Switched to fftw 3.0.1 0.8.0.2 Characters, that were deleted , won't be transmitted together with the delete anymore. Fixed bug in setting input and output volume Windows position now will be saved when exiting the application by Quit. Trying to fix crash, when closing DarwinPsk by the little red button 0.8.0.1 Fixing the "spinning disc of death" linpsk/asoundrc0000644000175000017500000000063211337745305014024 0ustar schroerschroerpcm.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/COPYING0000644000175000017500000004313111337745305013317 0ustar schroerschroer 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.