diff --git a/plugins/channelrx/demoddatv/datvdemod.cpp b/plugins/channelrx/demoddatv/datvdemod.cpp index 05cd3a2e6..42ed81ced 100644 --- a/plugins/channelrx/demoddatv/datvdemod.cpp +++ b/plugins/channelrx/demoddatv/datvdemod.cpp @@ -43,6 +43,7 @@ DATVDemod::DATVDemod(DeviceSourceAPI *deviceAPI) : m_objRegisteredVideoRender(0), m_objVideoStream(nullptr), m_objRenderThread(nullptr), + m_audioFifo(48000), m_blnRenderingVideo(false), m_blnStartStopVideo(false), m_enmModulation(DATVDemodSettings::BPSK /*DATV_FM1*/), @@ -51,6 +52,9 @@ DATVDemod::DATVDemod(DeviceSourceAPI *deviceAPI) : { setObjectName("DATVDemod"); + DSPEngine::instance()->getAudioDeviceManager()->addAudioSink(&m_audioFifo, getInputMessageQueue()); + //m_audioSampleRate = DSPEngine::instance()->getAudioDeviceManager()->getOutputSampleRate(); + //*************** DATV PARAMETERS *************** m_blnInitialized=false; CleanUpDATVFramework(false); @@ -75,6 +79,8 @@ DATVDemod::~DATVDemod() m_objVideoStream->ThreadTimeOut=0; } + DSPEngine::instance()->getAudioDeviceManager()->removeAudioSink(&m_audioFifo); + if(m_objRenderThread!=nullptr) { if(m_objRenderThread->isRunning()) @@ -101,15 +107,22 @@ bool DATVDemod::SetTVScreen(TVScreen *objScreen) return true; } -DATVideostream * DATVDemod::SetVideoRender(DATVideoRender *objScreen) +DATVideostream *DATVDemod::SetVideoRender(DATVideoRender *objScreen) { m_objRegisteredVideoRender = objScreen; - - m_objRenderThread = new DATVideoRenderThread(m_objRegisteredVideoRender,m_objVideoStream); - + m_objRegisteredVideoRender->setAudioFIFO(&m_audioFifo); + m_objRenderThread = new DATVideoRenderThread(m_objRegisteredVideoRender, m_objVideoStream); return m_objVideoStream; } +bool DATVDemod::audioActive() +{ + if (m_objRegisteredVideoRender) { + return m_objRegisteredVideoRender->getAudioStreamIndex() >= 0; + } else { + return false; + } +} bool DATVDemod::PlayVideo(bool blnStartStop) { @@ -839,6 +852,7 @@ void DATVDemod::feed(const SampleVector::const_iterator& begin, const SampleVect void DATVDemod::start() { + m_audioFifo.clear(); } void DATVDemod::stop() @@ -921,6 +935,18 @@ void DATVDemod::applySettings(const DATVDemodSettings& settings, bool force) return; } + if ((settings.m_audioDeviceName != m_settings.m_audioDeviceName) || force) + { + AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager(); + int audioDeviceIndex = audioDeviceManager->getOutputDeviceIndex(settings.m_audioDeviceName); + audioDeviceManager->addAudioSink(&m_audioFifo, getInputMessageQueue(), audioDeviceIndex); + // uint32_t audioSampleRate = audioDeviceManager->getOutputSampleRate(audioDeviceIndex); + + // if (m_audioSampleRate != audioSampleRate) { + // applyAudioSampleRate(audioSampleRate); + // } + } + if (m_settings.isDifferent(settings) || force) { m_objSettingsMutex.lock(); diff --git a/plugins/channelrx/demoddatv/datvdemod.h b/plugins/channelrx/demoddatv/datvdemod.h index 8464b2f62..c7d61f0f8 100644 --- a/plugins/channelrx/demoddatv/datvdemod.h +++ b/plugins/channelrx/demoddatv/datvdemod.h @@ -146,6 +146,7 @@ public: bool SetTVScreen(TVScreen *objScreen); DATVideostream * SetVideoRender(DATVideoRender *objScreen); + bool audioActive(); bool PlayVideo(bool blnStartStop); @@ -333,10 +334,13 @@ private: DownChannelizer* m_channelizer; //*************** DATV PARAMETERS *************** - TVScreen * m_objRegisteredTVScreen; - DATVideoRender * m_objRegisteredVideoRender; - DATVideostream * m_objVideoStream; - DATVideoRenderThread * m_objRenderThread; + TVScreen *m_objRegisteredTVScreen; + DATVideoRender *m_objRegisteredVideoRender; + DATVideostream *m_objVideoStream; + DATVideoRenderThread *m_objRenderThread; + + // Audio + AudioFifo m_audioFifo; fftfilt * m_objRFFilter; NCO m_objNCO; diff --git a/plugins/channelrx/demoddatv/datvdemodgui.cpp b/plugins/channelrx/demoddatv/datvdemodgui.cpp index 66fc7a9a2..58534470a 100644 --- a/plugins/channelrx/demoddatv/datvdemodgui.cpp +++ b/plugins/channelrx/demoddatv/datvdemodgui.cpp @@ -33,6 +33,8 @@ #include "util/simpleserializer.h" #include "util/db.h" #include "dsp/dspengine.h" +#include "gui/crightclickenabler.h" +#include "gui/audioselectdialog.h" #include "mainwindow.h" const QString DATVDemodGUI::m_strChannelID = "sdrangel.channel.demoddatv"; @@ -151,9 +153,8 @@ DATVDemodGUI::DATVDemodGUI(PluginAPI* objPluginAPI, DeviceUISet *deviceUISet, Ba m_objDATVDemod->SetTVScreen(ui->screenTV); - connect(m_objDATVDemod->SetVideoRender(ui->screenTV_2),&DATVideostream::onDataPackets,this,&DATVDemodGUI::on_StreamDataAvailable); - - connect(ui->screenTV_2,&DATVideoRender::onMetaDataChanged,this,&DATVDemodGUI::on_StreamMetaDataChanged); + connect(m_objDATVDemod->SetVideoRender(ui->screenTV_2), &DATVideostream::onDataPackets, this, &DATVDemodGUI::on_StreamDataAvailable); + connect(ui->screenTV_2, &DATVideoRender::onMetaDataChanged, this, &DATVDemodGUI::on_StreamMetaDataChanged); m_intPreviousDecodedData=0; m_intLastDecodedData=0; @@ -185,7 +186,10 @@ DATVDemodGUI::DATVDemodGUI(PluginAPI* objPluginAPI, DeviceUISet *deviceUISet, Ba m_deviceUISet->addChannelMarker(&m_objChannelMarker); m_deviceUISet->addRollupWidget(this); - ui->pushButton_3->setIcon(style()->standardIcon(QStyle::SP_MediaPlay)); + ui->videoPlay->setIcon(style()->standardIcon(QStyle::SP_MediaPlay)); + + CRightClickEnabler *audioMuteRightClickEnabler = new CRightClickEnabler(ui->audioMute); + connect(audioMuteRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(audioSelect())); resetToDefaults(); // does applySettings() } @@ -219,6 +223,7 @@ void DATVDemodGUI::displaySettings() ui->chkHardMetric->setChecked(m_settings.m_hardMetric); ui->spiRollOff->setValue((int) (m_settings.m_rollOff * 100.0f)); ui->chkViterbi->setChecked(m_settings.m_viterbi); + ui->audioMute->setChecked(m_settings.m_audioMute); ui->cmbFEC->setCurrentIndex((int) m_settings.m_fec); ui->cmbModulation->setCurrentIndex((int) m_settings.m_modulation); ui->cmbStandard->setCurrentIndex((int) m_settings.m_standard); @@ -362,6 +367,19 @@ void DATVDemodGUI::enterEvent(QEvent*) blockApplySettings(false); } +void DATVDemodGUI::audioSelect() +{ + qDebug("AMDemodGUI::audioSelect"); + AudioSelectDialog audioSelect(DSPEngine::instance()->getAudioDeviceManager(), m_settings.m_audioDeviceName); + audioSelect.exec(); + + if (audioSelect.m_selected) + { + m_settings.m_audioDeviceName = audioSelect.m_audioDeviceName; + applySettings(); + } +} + void DATVDemodGUI::tick() { if (m_objDATVDemod) @@ -377,6 +395,12 @@ void DATVDemodGUI::tick() ui->lblRate->setText(QString("Speed: %1b/s").arg(formatBytes(m_intLastSpeed))); } + if (m_objDATVDemod->audioActive()) { + ui->audioMute->setStyleSheet("QToolButton { background-color : green; }"); + } else { + ui->audioMute->setStyleSheet("QToolButton { background:rgb(79,79,79); }"); + } + m_intPreviousDecodedData = m_intLastDecodedData; //Try to start video rendering @@ -625,9 +649,9 @@ void DATVDemodGUI::on_StreamMetaDataChanged(DataTSMetaData2 *objMetaData) ui->chkDecoding->setChecked(objMetaData->OK_Decoding); if (objMetaData->OK_Decoding == true) { - ui->pushButton_3->setIcon(style()->standardIcon(QStyle::SP_MediaPause)); + ui->videoPlay->setIcon(style()->standardIcon(QStyle::SP_MediaPause)); } else { - ui->pushButton_3->setIcon(style()->standardIcon(QStyle::SP_MediaPlay)); + ui->videoPlay->setIcon(style()->standardIcon(QStyle::SP_MediaPlay)); } if (objMetaData->Height > 0) { diff --git a/plugins/channelrx/demoddatv/datvdemodgui.h b/plugins/channelrx/demoddatv/datvdemodgui.h index 9845be534..bc1d09cf2 100644 --- a/plugins/channelrx/demoddatv/datvdemodgui.h +++ b/plugins/channelrx/demoddatv/datvdemodgui.h @@ -68,6 +68,7 @@ private slots: void onWidgetRolled(QWidget* widget, bool rollDown); void onMenuDoubleClicked(); + void audioSelect(); void tick(); void on_cmbStandard_currentIndexChanged(const QString &arg1); diff --git a/plugins/channelrx/demoddatv/datvdemodgui.ui b/plugins/channelrx/demoddatv/datvdemodgui.ui index 1135f36f0..bf23d2d7c 100644 --- a/plugins/channelrx/demoddatv/datvdemodgui.ui +++ b/plugins/channelrx/demoddatv/datvdemodgui.ui @@ -204,7 +204,7 @@ QTabWidget::West - 1 + 0 @@ -756,7 +756,7 @@ false - + 400 @@ -772,12 +772,12 @@ Full Screen - + 400 300 - 91 + 56 27 @@ -785,7 +785,7 @@ Start/Stop video streaming - Video + Video @@ -916,6 +916,24 @@ true + + + + 460 + 300 + 28 + 26 + + + + ... + + + + :/sound_on.png + :/sound_off.png:/sound_on.png + + @@ -946,6 +964,8 @@ 1 - + + + diff --git a/plugins/channelrx/demoddatv/datvdemodsettings.cpp b/plugins/channelrx/demoddatv/datvdemodsettings.cpp index f4b9f9b6d..0f0d39c56 100644 --- a/plugins/channelrx/demoddatv/datvdemodsettings.cpp +++ b/plugins/channelrx/demoddatv/datvdemodsettings.cpp @@ -17,6 +17,7 @@ #include #include +#include "dsp/dspengine.h" #include "util/simpleserializer.h" #include "settings/serializable.h" @@ -46,6 +47,8 @@ void DATVDemodSettings::resetToDefaults() m_rollOff = 0.35; m_viterbi = false; m_excursion = 10; + m_audioMute = false; + m_audioDeviceName = AudioDeviceManager::m_defaultDeviceName; } QByteArray DATVDemodSettings::serialize() const @@ -63,6 +66,7 @@ QByteArray DATVDemodSettings::serialize() const s.writeU32(7, m_rgbColor); s.writeString(8, m_title); s.writeS32(9, (int) m_fec); + s.writeBool(10, m_audioMute); s.writeS32(11, m_symbolRate); s.writeS32(12, m_notchFilters); s.writeBool(13, m_allowDrift); @@ -72,6 +76,7 @@ QByteArray DATVDemodSettings::serialize() const s.writeFloat(17, m_rollOff); s.writeBool(18, m_viterbi); s.writeS32(19, m_excursion); + s.writeString(20, m_audioDeviceName); return s.final(); } @@ -116,6 +121,7 @@ bool DATVDemodSettings::deserialize(const QByteArray& data) tmp = tmp < 0 ? 0 : tmp >= (int) leansdr::code_rate::FEC_COUNT ? (int) leansdr::code_rate::FEC_COUNT - 1 : tmp; m_fec = (leansdr::code_rate) tmp; + d.readBool(10, &m_audioMute, false); d.readS32(11, &m_symbolRate, 250000); d.readS32(12, &m_notchFilters, 1); d.readBool(13, &m_allowDrift, false); @@ -129,6 +135,7 @@ bool DATVDemodSettings::deserialize(const QByteArray& data) d.readFloat(17, &m_rollOff, 0.35); d.readBool(18, &m_viterbi, false); d.readS32(19, &m_excursion, 10); + d.readString(20, &m_audioDeviceName, AudioDeviceManager::m_defaultDeviceName); return true; } @@ -155,7 +162,9 @@ void DATVDemodSettings::debug(const QString& msg) const << " m_standard: " << m_standard << " m_notchFilters: " << m_notchFilters << " m_symbolRate: " << m_symbolRate - << " m_excursion: " << m_excursion; + << " m_excursion: " << m_excursion + << " m_audioMute: " << m_audioMute + << " m_audioDeviceName: " << m_audioDeviceName; } bool DATVDemodSettings::isDifferent(const DATVDemodSettings& other) diff --git a/plugins/channelrx/demoddatv/datvdemodsettings.h b/plugins/channelrx/demoddatv/datvdemodsettings.h index d24c414f1..2b58d202e 100644 --- a/plugins/channelrx/demoddatv/datvdemodsettings.h +++ b/plugins/channelrx/demoddatv/datvdemodsettings.h @@ -61,6 +61,8 @@ struct DATVDemodSettings dvb_version m_standard; DATVModulation m_modulation; leansdr::code_rate m_fec; + bool m_audioMute; + QString m_audioDeviceName; int m_symbolRate; int m_notchFilters; bool m_allowDrift; diff --git a/plugins/channelrx/demoddatv/datvideorender.cpp b/plugins/channelrx/demoddatv/datvideorender.cpp index 39fc6e28a..04cfed6ba 100644 --- a/plugins/channelrx/demoddatv/datvideorender.cpp +++ b/plugins/channelrx/demoddatv/datvideorender.cpp @@ -21,15 +21,19 @@ DATVideoRender::DATVideoRender(QWidget * parent): TVScreen(true, parent) { installEventFilter(this); - m_blnIsFullScreen=false; - m_blnRunning=false; + m_blnIsFullScreen = false; + m_blnRunning = false; - m_blnIsFFMPEGInitialized=false; - m_blnIsOpen=false; - m_objFormatCtx=nullptr; - m_objDecoderCtx=nullptr; - m_objSwsCtx=nullptr; - m_intVideoStreamIndex=-1; + m_blnIsFFMPEGInitialized = false; + m_blnIsOpen = false; + m_objFormatCtx = nullptr; + m_objDecoderCtx = nullptr; + m_objSwsCtx = nullptr; + m_audioBuffer.resize(1<<14); + m_audioBufferFill = 0; + m_audioFifo = nullptr; + m_intVideoStreamIndex = -1; + m_audioStreamIndex = -1; m_intCurrentRenderWidth=-1; m_intCurrentRenderHeight=-1; @@ -170,6 +174,15 @@ bool DATVideoRender::PreprocessStream() m_intVideoStreamIndex = intRet; + //Find audio stream + intRet = av_find_best_stream(m_objFormatCtx, AVMEDIA_TYPE_AUDIO, -1, -1, nullptr, 0); + + if (intRet < 0) { + qDebug() << "DATVideoProcess::PreprocessStream cannot find audio stream"; + } + + m_audioStreamIndex = intRet; + //Prepare Codec and extract meta data // FIXME: codec is depreecated but replacement fails @@ -475,6 +488,10 @@ bool DATVideoRender::RenderStream() m_intFrameCount ++; } } + else if (objPacket.stream_index == m_audioStreamIndex) + { + + } av_packet_unref(&objPacket); diff --git a/plugins/channelrx/demoddatv/datvideorender.h b/plugins/channelrx/demoddatv/datvideorender.h index 081370856..678933b66 100644 --- a/plugins/channelrx/demoddatv/datvideorender.h +++ b/plugins/channelrx/demoddatv/datvideorender.h @@ -41,6 +41,8 @@ extern "C" #include "libswscale/swscale.h" } +class AudioFifo; + struct DataTSMetaData2 { int PID; @@ -92,6 +94,10 @@ public: bool RenderStream(); bool CloseStream(QIODevice *objDevice); + void setAudioFIFO(AudioFifo *fifo) { m_audioFifo = fifo; } + int getVideoStreamIndex() const { return m_intVideoStreamIndex; } + int getAudioStreamIndex() const { return m_audioStreamIndex; } + struct DataTSMetaData2 MetaData; private: @@ -106,11 +112,16 @@ private: AVCodecContext *m_objDecoderCtx; AVFrame *m_objFrame; + AudioVector m_audioBuffer; + uint32_t m_audioBufferFill; + AudioFifo *m_audioFifo; + uint8_t *m_pbytDecodedData[4]; int m_pintDecodedLineSize[4]; int m_intFrameCount; int m_intVideoStreamIndex; + int m_audioStreamIndex; int m_intCurrentRenderWidth; int m_intCurrentRenderHeight;