Start dealing with thread related object lifetime issues

There are  several object  lifetime issues that  can cause  crashes on
application close down.  This change  is the first phase of addressing
these issues.

git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@5719 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
Bill Somerville 2015-07-13 11:00:55 +00:00
parent 310481bcaa
commit 76eed0ecc4
5 changed files with 76 additions and 70 deletions

View File

@ -4,6 +4,7 @@
#include <QDateTime> #include <QDateTime>
#include <QDebug> #include <QDebug>
#include "mainwindow.h" #include "mainwindow.h"
#include "soundout.h"
#include "moc_Modulator.cpp" #include "moc_Modulator.cpp"
@ -27,7 +28,6 @@ unsigned const Modulator::m_nspd = 2048 + 512; // 22.5 WPM
Modulator::Modulator (unsigned frameRate, unsigned periodLengthInSeconds, Modulator::Modulator (unsigned frameRate, unsigned periodLengthInSeconds,
QObject * parent) QObject * parent)
: AudioDevice {parent} : AudioDevice {parent}
, m_stream {nullptr}
, m_quickClose {false} , m_quickClose {false}
, m_phi {0.0} , m_phi {0.0}
, m_toneSpacing {0.0} , m_toneSpacing {0.0}

View File

@ -2,6 +2,7 @@
#define MODULATOR_HPP__ #define MODULATOR_HPP__
#include <QAudio> #include <QAudio>
#include <QPointer>
#include "AudioDevice.hpp" #include "AudioDevice.hpp"
@ -48,7 +49,7 @@ protected:
private: private:
qint16 postProcessSample (qint16 sample) const; qint16 postProcessSample (qint16 sample) const;
SoundOutput * m_stream; QPointer<SoundOutput> m_stream;
bool m_quickClose; bool m_quickClose;
unsigned m_symbolsLength; unsigned m_symbolsLength;

View File

@ -4,7 +4,6 @@
#include <cinttypes> #include <cinttypes>
#include <limits> #include <limits>
#include <QThread>
#include <QLineEdit> #include <QLineEdit>
#include <QRegExpValidator> #include <QRegExpValidator>
#include <QRegExp> #include <QRegExp>
@ -21,6 +20,9 @@
#include "revision_utils.hpp" #include "revision_utils.hpp"
#include "qt_helpers.hpp" #include "qt_helpers.hpp"
#include "soundout.h" #include "soundout.h"
#include "soundin.h"
#include "Modulator.hpp"
#include "Detector.hpp"
#include "plotter.h" #include "plotter.h"
#include "echoplot.h" #include "echoplot.h"
#include "echograph.h" #include "echograph.h"
@ -83,9 +85,10 @@ MainWindow::MainWindow(bool multiple, QSettings * settings, QSharedMemory *shdme
m_echoGraph (new EchoGraph(settings)), m_echoGraph (new EchoGraph(settings)),
m_logDlg (new LogQSO (program_title (), settings, this)), m_logDlg (new LogQSO (program_title (), settings, this)),
m_dialFreq {std::numeric_limits<Radio::Frequency>::max ()}, m_dialFreq {std::numeric_limits<Radio::Frequency>::max ()},
m_detector (RX_SAMPLE_RATE, NTMAX, 6912 / 2, downSampleFactor), m_detector {new Detector {RX_SAMPLE_RATE, NTMAX, 6912 / 2, downSampleFactor}},
m_modulator (TX_SAMPLE_RATE, NTMAX), m_soundInput {new SoundInput},
m_audioThread {new QThread}, m_modulator {new Modulator {TX_SAMPLE_RATE, NTMAX}},
m_soundOutput {new SoundOutput},
m_XIT {0}, m_XIT {0},
m_pctx {0}, m_pctx {0},
m_diskData {false}, m_diskData {false},
@ -133,39 +136,39 @@ MainWindow::MainWindow(bool multiple, QSettings * settings, QSharedMemory *shdme
// start audio thread and hook up slots & signals for shutdown management // start audio thread and hook up slots & signals for shutdown management
// these objects need to be in the audio thread so that invoking // these objects need to be in the audio thread so that invoking
// their slots is done in a thread safe way // their slots is done in a thread safe way
m_soundOutput.moveToThread (m_audioThread); m_soundOutput->moveToThread (&m_audioThread);
m_modulator.moveToThread (m_audioThread); m_modulator->moveToThread (&m_audioThread);
m_soundInput.moveToThread (m_audioThread); m_soundInput->moveToThread (&m_audioThread);
m_detector.moveToThread (m_audioThread); m_detector->moveToThread (&m_audioThread);
connect (this, &MainWindow::finished, m_audioThread, &QThread::quit); // quit thread event loop // hook up sound output stream slots & signals and disposal
connect (m_audioThread, &QThread::finished, m_audioThread, &QThread::deleteLater); // disposal connect (this, &MainWindow::initializeAudioOutputStream, m_soundOutput, &SoundOutput::setFormat);
connect (m_soundOutput, &SoundOutput::error, this, &MainWindow::showSoundOutError);
// connect (m_soundOutput, &SoundOutput::status, this, &MainWindow::showStatusMessage);
connect (this, &MainWindow::outAttenuationChanged, m_soundOutput, &SoundOutput::setAttenuation);
connect (&m_audioThread, &QThread::finished, m_soundOutput, &QObject::deleteLater);
// hook up sound output stream slots & signals // hook up Modulator slots and disposal
connect (this, &MainWindow::initializeAudioOutputStream, &m_soundOutput, &SoundOutput::setFormat); connect (this, &MainWindow::transmitFrequency, m_modulator, &Modulator::setFrequency);
connect (&m_soundOutput, &SoundOutput::error, this, &MainWindow::showSoundOutError); connect (this, &MainWindow::endTransmitMessage, m_modulator, &Modulator::stop);
// connect (&m_soundOutput, &SoundOutput::status, this, &MainWindow::showStatusMessage); connect (this, &MainWindow::tune, m_modulator, &Modulator::tune);
connect (this, &MainWindow::outAttenuationChanged, &m_soundOutput, &SoundOutput::setAttenuation); connect (this, &MainWindow::sendMessage, m_modulator, &Modulator::start);
connect (&m_audioThread, &QThread::finished, m_modulator, &QObject::deleteLater);
// hook up Modulator slots // hook up the audio input stream signals, slots and disposal
connect (this, &MainWindow::transmitFrequency, &m_modulator, &Modulator::setFrequency); connect (this, &MainWindow::startAudioInputStream, m_soundInput, &SoundInput::start);
connect (this, &MainWindow::endTransmitMessage, &m_modulator, &Modulator::stop); connect (this, &MainWindow::suspendAudioInputStream, m_soundInput, &SoundInput::suspend);
connect (this, &MainWindow::tune, &m_modulator, &Modulator::tune); connect (this, &MainWindow::resumeAudioInputStream, m_soundInput, &SoundInput::resume);
connect (this, &MainWindow::sendMessage, &m_modulator, &Modulator::start); connect (this, &MainWindow::finished, m_soundInput, &SoundInput::stop);
connect(m_soundInput, &SoundInput::error, this, &MainWindow::showSoundInError);
// hook up the audio input stream // connect(m_soundInput, &SoundInput::status, this, &MainWindow::showStatusMessage);
connect (this, &MainWindow::startAudioInputStream, &m_soundInput, &SoundInput::start); connect (&m_audioThread, &QThread::finished, m_soundInput, &QObject::deleteLater);
connect (this, &MainWindow::suspendAudioInputStream, &m_soundInput, &SoundInput::suspend);
connect (this, &MainWindow::resumeAudioInputStream, &m_soundInput, &SoundInput::resume);
connect (this, &MainWindow::finished, &m_soundInput, &SoundInput::stop);
connect (this, &MainWindow::finished, this, &MainWindow::close); connect (this, &MainWindow::finished, this, &MainWindow::close);
connect(&m_soundInput, &SoundInput::error, this, &MainWindow::showSoundInError); // hook up the detector signals, slots and disposal
// connect(&m_soundInput, &SoundInput::status, this, &MainWindow::showStatusMessage); connect(m_detector, &Detector::framesWritten, this, &MainWindow::dataSink);
connect (&m_audioThread, &QThread::finished, m_detector, &QObject::deleteLater);
// hook up the detector
connect(&m_detector, &Detector::framesWritten, this, &MainWindow::dataSink);
// setup the waterfall // setup the waterfall
connect(m_wideGraph.data (), SIGNAL(freezeDecode2(int)),this, connect(m_wideGraph.data (), SIGNAL(freezeDecode2(int)),this,
@ -428,7 +431,7 @@ MainWindow::MainWindow(bool multiple, QSettings * settings, QSharedMemory *shdme
readSettings(); //Restore user's setup params readSettings(); //Restore user's setup params
// start the audio thread // start the audio thread
m_audioThread->start (m_audioThreadPriority); m_audioThread.start (m_audioThreadPriority);
#ifdef WIN32 #ifdef WIN32
if (!m_multiple) if (!m_multiple)
@ -523,7 +526,7 @@ MainWindow::MainWindow(bool multiple, QSettings * settings, QSharedMemory *shdme
watcher2 = new QFutureWatcher<void>; watcher2 = new QFutureWatcher<void>;
connect(watcher2, SIGNAL(finished()),this,SLOT(diskWriteFinished())); connect(watcher2, SIGNAL(finished()),this,SLOT(diskWriteFinished()));
Q_EMIT startAudioInputStream (m_config.audio_input_device (), m_framesAudioInputBuffered, &m_detector, m_downSampleFactor, m_config.audio_input_channel ()); Q_EMIT startAudioInputStream (m_config.audio_input_device (), m_framesAudioInputBuffered, m_detector, m_downSampleFactor, m_config.audio_input_channel ());
Q_EMIT initializeAudioOutputStream (m_config.audio_output_device (), AudioDevice::Mono == m_config.audio_output_channel () ? 1 : 2, m_msAudioOutputBuffered); Q_EMIT initializeAudioOutputStream (m_config.audio_output_device (), AudioDevice::Mono == m_config.audio_output_channel () ? 1 : 2, m_msAudioOutputBuffered);
Q_EMIT transmitFrequency (ui->TxFreqSpinBox->value () - m_XIT); Q_EMIT transmitFrequency (ui->TxFreqSpinBox->value () - m_XIT);
@ -557,7 +560,7 @@ MainWindow::MainWindow(bool multiple, QSettings * settings, QSharedMemory *shdme
m_hsymStop=173; m_hsymStop=173;
if(m_config.decode_at_52s()) m_hsymStop=181; if(m_config.decode_at_52s()) m_hsymStop=181;
} }
m_modulator.setPeriod(m_TRperiod); m_modulator->setPeriod(m_TRperiod); // TODO - not thread safe
m_dialFreqRxWSPR=0; m_dialFreqRxWSPR=0;
wsprNet = new WSPRNet(this); wsprNet = new WSPRNet(this);
connect( wsprNet, SIGNAL(uploadStatus(QString)), this, SLOT(uploadResponse(QString))); connect( wsprNet, SIGNAL(uploadStatus(QString)), this, SLOT(uploadResponse(QString)));
@ -574,7 +577,8 @@ MainWindow::~MainWindow()
QString fname {QDir::toNativeSeparators(m_dataDir.absoluteFilePath ("wsjtx_wisdom.dat"))}; QString fname {QDir::toNativeSeparators(m_dataDir.absoluteFilePath ("wsjtx_wisdom.dat"))};
QByteArray cfname=fname.toLocal8Bit(); QByteArray cfname=fname.toLocal8Bit();
fftwf_export_wisdom_to_filename(cfname); fftwf_export_wisdom_to_filename(cfname);
m_audioThread->wait (); m_audioThread.quit ();
m_audioThread.wait ();
delete ui, ui = 0; delete ui, ui = 0;
} }
@ -898,7 +902,7 @@ void MainWindow::on_actionSettings_triggered() //Setup Dialog
if(m_mode=="JT9W-1") m_toneSpacing=pow(2,m_config.jt9w_bw_mult ())*12000.0/6912.0; if(m_mode=="JT9W-1") m_toneSpacing=pow(2,m_config.jt9w_bw_mult ())*12000.0/6912.0;
if(m_config.restart_audio_input ()) { if(m_config.restart_audio_input ()) {
Q_EMIT startAudioInputStream (m_config.audio_input_device (), m_framesAudioInputBuffered, &m_detector, m_downSampleFactor, m_config.audio_input_channel ()); Q_EMIT startAudioInputStream (m_config.audio_input_device (), m_framesAudioInputBuffered, m_detector, m_downSampleFactor, m_config.audio_input_channel ());
} }
if(m_config.restart_audio_output ()) { if(m_config.restart_audio_output ()) {
Q_EMIT initializeAudioOutputStream (m_config.audio_output_device (), AudioDevice::Mono == m_config.audio_output_channel () ? 1 : 2, m_msAudioOutputBuffered); Q_EMIT initializeAudioOutputStream (m_config.audio_output_device (), AudioDevice::Mono == m_config.audio_output_channel () ? 1 : 2, m_msAudioOutputBuffered);
@ -2124,12 +2128,12 @@ void MainWindow::guiUpdate()
void MainWindow::startTx2() void MainWindow::startTx2()
{ {
if (!m_modulator.isActive ()) { if (!m_modulator->isActive ()) { // TODO - not thread safe
double fSpread=0.0; double fSpread=0.0;
double snr=99.0; double snr=99.0;
QString t=ui->tx5->currentText(); QString t=ui->tx5->currentText();
if(t.mid(0,1)=="#") fSpread=t.mid(1,5).toDouble(); if(t.mid(0,1)=="#") fSpread=t.mid(1,5).toDouble();
m_modulator.setSpread(fSpread); m_modulator->setSpread(fSpread); // TODO - not thread safe
t=ui->tx6->text(); t=ui->tx6->text();
if(t.mid(0,1)=="#") snr=t.mid(1,5).toDouble(); if(t.mid(0,1)=="#") snr=t.mid(1,5).toDouble();
if(snr>0.0 or snr < -50.0) snr=99.0; if(snr>0.0 or snr < -50.0) snr=99.0;
@ -2818,7 +2822,7 @@ void MainWindow::on_tx6_editingFinished() //tx6 edited
// double snr=t.mid(1,5).toDouble(); // double snr=t.mid(1,5).toDouble();
// if(snr>0.0 or snr < -50.0) snr=99.0; // if(snr>0.0 or snr < -50.0) snr=99.0;
// m_modulator.setTxSNR(snr); // m_modulator->setTxSNR(snr); // TODO - not thread safe
} }
void MainWindow::on_dxCallEntry_textChanged(const QString &t) //dxCall changed void MainWindow::on_dxCallEntry_textChanged(const QString &t) //dxCall changed
@ -2907,8 +2911,8 @@ void MainWindow::on_actionJT9_1_triggered()
if(m_modeTx!="JT9") on_pbTxMode_clicked(); if(m_modeTx!="JT9") on_pbTxMode_clicked();
statusChanged(); statusChanged();
m_TRperiod=60; m_TRperiod=60;
m_modulator.setPeriod(m_TRperiod); m_modulator->setPeriod(m_TRperiod); // TODO - not thread safe
m_detector.setPeriod(m_TRperiod); m_detector->setPeriod(m_TRperiod); // TODO - not thread safe
m_nsps=6912; m_nsps=6912;
m_hsymStop=173; m_hsymStop=173;
if(m_config.decode_at_52s()) m_hsymStop=181; if(m_config.decode_at_52s()) m_hsymStop=181;
@ -2935,8 +2939,8 @@ void MainWindow::on_actionJT9W_1_triggered()
if(m_modeTx!="JT9") on_pbTxMode_clicked(); if(m_modeTx!="JT9") on_pbTxMode_clicked();
statusChanged(); statusChanged();
m_TRperiod=60; m_TRperiod=60;
m_modulator.setPeriod(m_TRperiod); m_modulator->setPeriod(m_TRperiod); // TODO - not thread safe
m_detector.setPeriod(m_TRperiod); m_detector->setPeriod(m_TRperiod); // TODO - not thread safe
m_nsps=6912; m_nsps=6912;
m_hsymStop=173; m_hsymStop=173;
if(m_config.decode_at_52s()) m_hsymStop=181; if(m_config.decode_at_52s()) m_hsymStop=181;
@ -2969,8 +2973,8 @@ void MainWindow::on_actionJT65_triggered()
if(m_modeTx!="JT65") on_pbTxMode_clicked(); if(m_modeTx!="JT65") on_pbTxMode_clicked();
statusChanged(); statusChanged();
m_TRperiod=60; m_TRperiod=60;
m_modulator.setPeriod(m_TRperiod); m_modulator->setPeriod(m_TRperiod); // TODO - not thread safe
m_detector.setPeriod(m_TRperiod); m_detector->setPeriod(m_TRperiod); // TODO - not thread safe
m_nsps=6912; //For symspec only m_nsps=6912; //For symspec only
m_hsymStop=173; m_hsymStop=173;
if(m_config.decode_at_52s()) m_hsymStop=181; if(m_config.decode_at_52s()) m_hsymStop=181;
@ -3008,8 +3012,8 @@ void MainWindow::on_actionJT9_JT65_triggered()
m_nSubMode=0; //Dual-mode always means JT9 and JT65A m_nSubMode=0; //Dual-mode always means JT9 and JT65A
statusChanged(); statusChanged();
m_TRperiod=60; m_TRperiod=60;
m_modulator.setPeriod(m_TRperiod); m_modulator->setPeriod(m_TRperiod); // TODO - not thread safe
m_detector.setPeriod(m_TRperiod); m_detector->setPeriod(m_TRperiod); // TODO - not thread safe
m_nsps=6912; m_nsps=6912;
m_hsymStop=173; m_hsymStop=173;
if(m_config.decode_at_52s()) m_hsymStop=181; if(m_config.decode_at_52s()) m_hsymStop=181;
@ -3036,8 +3040,8 @@ void MainWindow::on_actionJT4_triggered()
m_modeTx="JT4"; m_modeTx="JT4";
statusChanged(); statusChanged();
m_TRperiod=60; m_TRperiod=60;
m_modulator.setPeriod(m_TRperiod); m_modulator->setPeriod(m_TRperiod); // TODO - not thread safe
m_detector.setPeriod(m_TRperiod); m_detector->setPeriod(m_TRperiod); // TODO - not thread safe
m_nsps=6912; //For symspec only m_nsps=6912; //For symspec only
m_hsymStop=181; m_hsymStop=181;
// if(m_config.decode_at_52s()) m_hsymStop=181; // if(m_config.decode_at_52s()) m_hsymStop=181;
@ -3075,8 +3079,8 @@ void MainWindow::on_actionWSPR_2_triggered()
m_modeTx="WSPR-2"; //### not needed ?? ### m_modeTx="WSPR-2"; //### not needed ?? ###
statusChanged(); statusChanged();
m_TRperiod=120; m_TRperiod=120;
m_modulator.setPeriod(m_TRperiod); m_modulator->setPeriod(m_TRperiod); // TODO - not thread safe
m_detector.setPeriod(m_TRperiod); m_detector->setPeriod(m_TRperiod); // TODO - not thread safe
m_nsps=6912; //For symspec only m_nsps=6912; //For symspec only
m_hsymStop=396; m_hsymStop=396;
m_toneSpacing=12000.0/8192.0; m_toneSpacing=12000.0/8192.0;
@ -3103,8 +3107,8 @@ void MainWindow::on_actionEcho_triggered()
m_mode="Echo"; m_mode="Echo";
ui->actionEcho->setChecked(true); ui->actionEcho->setChecked(true);
m_TRperiod=3; m_TRperiod=3;
m_modulator.setPeriod(m_TRperiod); m_modulator->setPeriod(m_TRperiod); // TODO - not thread safe
m_detector.setPeriod(m_TRperiod); m_detector->setPeriod(m_TRperiod); // TODO - not thread safe
m_nsps=6912; //For symspec only m_nsps=6912; //For symspec only
m_hsymStop=10; m_hsymStop=10;
m_toneSpacing=1.0; m_toneSpacing=1.0;
@ -3618,13 +3622,13 @@ void MainWindow::transmit (double snr)
if(m_nSubMode==2) toneSpacing=4*11025.0/4096.0; if(m_nSubMode==2) toneSpacing=4*11025.0/4096.0;
Q_EMIT sendMessage (NUM_JT65_SYMBOLS, Q_EMIT sendMessage (NUM_JT65_SYMBOLS,
4096.0*12000.0/11025.0, ui->TxFreqSpinBox->value () - m_XIT, 4096.0*12000.0/11025.0, ui->TxFreqSpinBox->value () - m_XIT,
toneSpacing, &m_soundOutput, m_config.audio_output_channel (), toneSpacing, m_soundOutput, m_config.audio_output_channel (),
true, snr); true, snr);
} }
if (m_modeTx == "JT9") { if (m_modeTx == "JT9") {
Q_EMIT sendMessage (NUM_JT9_SYMBOLS, m_nsps, Q_EMIT sendMessage (NUM_JT9_SYMBOLS, m_nsps,
ui->TxFreqSpinBox->value () - m_XIT, m_toneSpacing, ui->TxFreqSpinBox->value () - m_XIT, m_toneSpacing,
&m_soundOutput, m_config.audio_output_channel (), true, snr); m_soundOutput, m_config.audio_output_channel (), true, snr);
} }
if (m_modeTx == "JT4") { if (m_modeTx == "JT4") {
if(m_nSubMode==0) toneSpacing=4.375; if(m_nSubMode==0) toneSpacing=4.375;
@ -3636,18 +3640,18 @@ void MainWindow::transmit (double snr)
if(m_nSubMode==6) toneSpacing=72*4.375; if(m_nSubMode==6) toneSpacing=72*4.375;
Q_EMIT sendMessage (NUM_JT4_SYMBOLS, Q_EMIT sendMessage (NUM_JT4_SYMBOLS,
2520.0*12000.0/11025.0, ui->TxFreqSpinBox->value () - m_XIT, 2520.0*12000.0/11025.0, ui->TxFreqSpinBox->value () - m_XIT,
toneSpacing, &m_soundOutput, m_config.audio_output_channel (), toneSpacing, m_soundOutput, m_config.audio_output_channel (),
true, snr); true, snr);
} }
if (m_mode=="WSPR-2") { //### Similar code needed for WSPR-15 ### if (m_mode=="WSPR-2") { //### Similar code needed for WSPR-15 ###
Q_EMIT sendMessage (NUM_WSPR_SYMBOLS, 8192.0, Q_EMIT sendMessage (NUM_WSPR_SYMBOLS, 8192.0,
ui->TxFreqSpinBox->value() - 1.5 * 12000 / 8192, m_toneSpacing, ui->TxFreqSpinBox->value() - 1.5 * 12000 / 8192, m_toneSpacing,
&m_soundOutput, m_config.audio_output_channel(), m_soundOutput, m_config.audio_output_channel(),
true, snr); true, snr);
} }
if(m_mode=="Echo") { if(m_mode=="Echo") {
Q_EMIT sendMessage (27, 1024.0, 1500.0, 0.0, &m_soundOutput, Q_EMIT sendMessage (27, 1024.0, 1500.0, 0.0, m_soundOutput,
m_config.audio_output_channel(),false, snr); m_config.audio_output_channel(),false, snr);
} }
} }

View File

@ -18,9 +18,7 @@
#include <QHostAddress> #include <QHostAddress>
#include <QPointer> #include <QPointer>
#include "soundin.h"
#include "AudioDevice.hpp" #include "AudioDevice.hpp"
#include "soundout.h"
#include "commons.h" #include "commons.h"
#include "Radio.hpp" #include "Radio.hpp"
#include "Modes.hpp" #include "Modes.hpp"
@ -29,8 +27,6 @@
#include "Transceiver.hpp" #include "Transceiver.hpp"
#include "psk_reporter.h" #include "psk_reporter.h"
#include "logbook/logbook.h" #include "logbook/logbook.h"
#include "Detector.hpp"
#include "Modulator.hpp"
#include "decodedtext.h" #include "decodedtext.h"
#define NUM_JT4_SYMBOLS 206 #define NUM_JT4_SYMBOLS 206
@ -63,6 +59,10 @@ class QTime;
class WSPRBandHopping; class WSPRBandHopping;
class HelpTextWindow; class HelpTextWindow;
class WSPRNet; class WSPRNet;
class SoundOutput;
class Modulator;
class SoundInput;
class Detector;
class MainWindow : public QMainWindow class MainWindow : public QMainWindow
{ {
@ -282,11 +282,11 @@ private:
Frequency m_dialFreq; Frequency m_dialFreq;
Frequency m_dialFreqRxWSPR; Frequency m_dialFreqRxWSPR;
Detector m_detector; Detector * m_detector;
SoundInput m_soundInput; SoundInput * m_soundInput;
Modulator m_modulator; Modulator * m_modulator;
SoundOutput m_soundOutput; SoundOutput * m_soundOutput;
QThread * m_audioThread; QThread m_audioThread;
qint64 m_msErase; qint64 m_msErase;
qint64 m_secBandChanged; qint64 m_secBandChanged;

View File

@ -6,6 +6,7 @@
#include <QString> #include <QString>
#include <QDateTime> #include <QDateTime>
#include <QScopedPointer> #include <QScopedPointer>
#include <QPointer>
#include <QAudioInput> #include <QAudioInput>
#include "AudioDevice.hpp" #include "AudioDevice.hpp"
@ -45,7 +46,7 @@ private:
bool audioError () const; bool audioError () const;
QScopedPointer<QAudioInput> m_stream; QScopedPointer<QAudioInput> m_stream;
AudioDevice * m_sink; QPointer<AudioDevice> m_sink;
}; };
#endif #endif