diff --git a/mainwindow.cpp b/mainwindow.cpp index 54de092bf..4f7538717 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -1,4 +1,4 @@ -//------------------------------------------------------------- MainWindow +//-------------------------------------------------------------- MainWindow #include "mainwindow.h" #include "ui_mainwindow.h" #include "devsetup.h" diff --git a/soundin.cpp b/soundin.cpp index 7458f06b6..7217713a1 100644 --- a/soundin.cpp +++ b/soundin.cpp @@ -1,3 +1,4 @@ +#ifndef QAUDIO_INPUT #include "soundin.h" #include @@ -184,3 +185,203 @@ void SoundInput::setMonitoring(bool b) { m_monitoring = b; } +#else // QAUDIO_INPUT + +#include "soundin.h" +#include + +#define FRAMES_PER_BUFFER 1024 +//#define NSMAX 1365 +#define NSMAX 6827 +#define NTMAX 120 + +extern "C" { +#include +extern struct { + float ss[184*NSMAX]; //This is "common/jt9com/..." in fortran + float savg[NSMAX]; +// float c0[2*NTMAX*1500]; + short int d2[NTMAX*12000]; + int nutc; //UTC as integer, HHMM + int ndiskdat; //1 ==> data read from *.wav file + int ntrperiod; //TR period (seconds) + int mousefqso; //User-selected QSO freq (kHz) + int newdat; //1 ==> new data, must do long FFT + int npts8; //npts in c0() array + int nfa; //Low decode limit (Hz) + int nfb; //High decode limit (Hz) + int ntol; //+/- decoding range around fQSO (Hz) + int kin; + int nzhsym; + int nsave; + int nagain; + int ndepth; + int ntxmode; + int nmode; + char datetime[20]; +} jt9com_; +} + +QString reportAudioError(QAudio::Error audioError) +{ + switch (audioError) { + case QAudio::NoError: Q_ASSERT(false); + case QAudio::OpenError: return QObject::tr( + "An error opening the audio device has occurred."); + case QAudio::IOError: return QObject::tr( + "An error occurred during read/write of audio device."); + case QAudio::UnderrunError: return QObject::tr( + "Audio data not being fed to the audio device fast enough."); + case QAudio::FatalError: return QObject::tr( + "Non-recoverable error, audio device not usable at this time."); + } + Q_ASSERT(false); + return ""; +} + +SoundInput::SoundInput() + : m_dataSinkBusy(false), + m_TRperiod(60), + m_nsps(6912), + m_monitoring(false), + m_intervalTimer(this) +{ + connect(&m_intervalTimer, &QTimer::timeout, this, &SoundInput::intervalNotify); +} + +void SoundInput::start(qint32 device) +{ + stop(); + +//---------------------------------------------------- Soundcard Setup + m_callbackData.kin=0; //Buffer pointer + m_callbackData.ncall=0; //Number of callbacks + m_callbackData.bzero=false; //Flag to request reset of kin + m_callbackData.monitoring=m_monitoring; + + //### Temporary: hardwired device selection + QAudioDeviceInfo DeviceInfo; + QList m_InDevices; + QAudioDeviceInfo m_InDeviceInfo; + m_InDevices = DeviceInfo.availableDevices(QAudio::AudioInput); + inputDevice = m_InDevices.at(0); + //### + + const char* pcmCodec = "audio/pcm"; + QAudioFormat audioFormat = inputDevice.preferredFormat(); + audioFormat.setChannelCount(1); + audioFormat.setCodec(pcmCodec); + audioFormat.setSampleRate(12000); + audioFormat.setSampleType(QAudioFormat::SignedInt); + audioFormat.setSampleSize(16); + + if (!audioFormat.isValid()) { + emit error(tr("Requested audio format is not available.")); + return; + } + + audioInput = new QAudioInput(inputDevice, audioFormat); +// audioInput2=audioInput; + if (audioInput->error() != QAudio::NoError) { + emit error(reportAudioError(audioInput->error())); + return; + } + + stream = audioInput->start(); + + m_ntr0 = 99; // initial value higher than any expected + m_nBusy = 0; + m_intervalTimer.start(100); + m_ms0 = QDateTime::currentMSecsSinceEpoch(); + m_nsps0 = 0; +} + +void SoundInput::intervalNotify() +{ + m_callbackData.monitoring=m_monitoring; + qint64 ms = QDateTime::currentMSecsSinceEpoch(); + ms=ms % 86400000; + int nsec = ms/1000; // Time according to this computer + int ntr = nsec % m_TRperiod; + static int k=0; + + // Reset buffer pointer and symbol number at start of minute + if(ntr < m_ntr0 or !m_monitoring or m_nsps!=m_nsps0) { + m_nstep0=0; + m_nsps0=m_nsps; + m_callbackData.bzero=true; + k=0; + } +// int k=m_callbackData.kin; + + // How many new samples have been acquired? + const qint32 bytesReady = audioInput->bytesReady(); + Q_ASSERT(bytesReady >= 0); + Q_ASSERT(bytesReady % 2 == 0); + if (bytesReady == 0) { +// msleep(50); + return; + } + + // Get the new samples + qint32 bytesRead; + qint16 buf0[4096]; + bytesRead = stream->read((char*)buf0, bytesReady); + Q_ASSERT(bytesRead <= bytesReady); + if (bytesRead < 0) { + emit error(tr("audio stream QIODevice::read returned -1.")); + return; + } + Q_ASSERT(bytesRead % 2 == 0); + +// memcpy(jt9com_.d2[k],buf0,bytesRead); +// k+=bytesRead/2; + for(int i=0; i +#include +#include +#include +#include + +// Gets audio data from soundcard and signals when a buffer of +// specified size is available. +class SoundInput : public QObject +{ + Q_OBJECT + +public: + SoundInput(); + ~SoundInput(); + + void setMonitoring(bool b); + void setPeriod(int ntrperiod, int nsps) /* this can be called while processing samples */ + { + m_TRperiod=ntrperiod; + m_nsps=nsps; + } + int mstep() const {return m_step;} + double samFacIn() const {return m_SamFacIn;} + +signals: + void readyForFFT(int k); + void error(const QString& message); + void status(const QString& message); + +public slots: + void start(qint32 device); + void intervalNotify(); + void stop(); + +private: + bool m_dataSinkBusy; + double m_SamFacIn; //(Input sample rate)/12000.0 + qint32 m_step; + qint32 m_TRperiod; + qint32 m_TRperiod0; + qint32 m_nsps; + bool m_monitoring; + qint64 m_ms0; + int m_ntr0; + int m_nBusy; + int m_nstep0; + int m_nsps0; + + QTimer m_intervalTimer; + QAudioDeviceInfo inputDevice; // audioinput device name + QAudioInput* audioInput; + QIODevice* stream; + + struct CallbackData + { + int kin; //Parameters sent to/from the portaudio callback function + int ncall; + bool bzero; + bool monitoring; + } m_callbackData; +}; +#endif // SOUNDIN_H +#endif // QAUDIO_INPUT diff --git a/widegraph.cpp b/widegraph.cpp index 56e4375fa..01bf2b645 100644 --- a/widegraph.cpp +++ b/widegraph.cpp @@ -2,6 +2,8 @@ #include "ui_widegraph.h" #include "commons.h" +#define MAX_SCREENSIZE 2048 + WideGraph::WideGraph(QWidget *parent) : QDialog(parent), ui(new Ui::WideGraph) @@ -10,7 +12,7 @@ WideGraph::WideGraph(QWidget *parent) : this->setWindowFlags(Qt::Dialog); this->installEventFilter(parent); //Installing the filter ui->widePlot->setCursor(Qt::CrossCursor); - this->setMaximumWidth(2048); + this->setMaximumWidth(MAX_SCREENSIZE); this->setMaximumHeight(880); ui->widePlot->setMaximumHeight(800); ui->widePlot->m_bCurrent=false; @@ -85,7 +87,7 @@ void WideGraph::dataSink2(float s[], float df3, int ihsym, int ndiskdata) { static float splot[NSMAX]; - static float swide[2048]; + static float swide[MAX_SCREENSIZE]; int nbpp = ui->widePlot->binsPerPixel(); static int n=0; @@ -105,6 +107,7 @@ void WideGraph::dataSink2(float s[], float df3, int ihsym, n=0; int i=int(ui->widePlot->startFreq()/df3 + 0.5); int jz=5000.0/(nbpp*df3); + if(jz>MAX_SCREENSIZE) jz=MAX_SCREENSIZE; for (int j=0; j