Initial commit of notifications spike

This commit is contained in:
Jordan Sherer 2019-10-08 14:33:38 -04:00
parent 722dd5571a
commit 9dc2c99ebd
9 changed files with 584 additions and 17 deletions

View File

@ -253,6 +253,7 @@ set (wsjtx_CXXSRCS
wsprnet.cpp
WSPRBandHopping.cpp
TransmitTextEdit.cpp
NotificationAudio.cpp
)
set (wsjt_CXXSRCS

View File

@ -530,6 +530,7 @@ private:
bool restart_sound_input_device_;
bool restart_sound_output_device_;
bool restart_notification_sound_output_device_;
Type2MsgGen type_2_msg_gen_;
@ -688,10 +689,15 @@ private:
QAudioDeviceInfo audio_input_device_;
bool default_audio_input_device_selected_;
AudioDevice::Channel audio_input_channel_;
QAudioDeviceInfo audio_output_device_;
bool default_audio_output_device_selected_;
AudioDevice::Channel audio_output_channel_;
QAudioDeviceInfo notification_audio_output_device_;
bool default_notification_audio_output_device_selected_;
AudioDevice::Channel notification_audio_output_channel_;
friend class Configuration;
};
@ -722,8 +728,11 @@ QAudioDeviceInfo const& Configuration::audio_input_device () const {return m_->a
AudioDevice::Channel Configuration::audio_input_channel () const {return m_->audio_input_channel_;}
QAudioDeviceInfo const& Configuration::audio_output_device () const {return m_->audio_output_device_;}
AudioDevice::Channel Configuration::audio_output_channel () const {return m_->audio_output_channel_;}
QAudioDeviceInfo const& Configuration::notification_audio_output_device () const {return m_->notification_audio_output_device_;}
AudioDevice::Channel Configuration::notification_audio_output_channel () const {return m_->notification_audio_output_channel_;}
bool Configuration::restart_audio_input () const {return m_->restart_sound_input_device_;}
bool Configuration::restart_audio_output () const {return m_->restart_sound_output_device_;}
bool Configuration::restart_notification_audio_output () const {return m_->restart_notification_sound_output_device_;}
auto Configuration::type_2_msg_gen () const -> Type2MsgGen {return m_->type_2_msg_gen_;}
bool Configuration::use_dynamic_grid() const {return m_->use_dynamic_info_; }
QString Configuration::my_callsign () const {return m_->my_callsign_;}
@ -1102,6 +1111,18 @@ template <typename T> void setUppercase(T* t){
t->setFont(f);
}
QWidget * centeredCheckBox(QWidget *parent, QCheckBox **ppCheckbox){
auto w = new QWidget(parent);
auto cb = new QCheckBox(parent);
auto l = new QHBoxLayout(w);
l->setContentsMargins(1, 1, 1, 1);
l->setAlignment(Qt::AlignCenter);
l->addWidget(cb);
w->setLayout(l);
if(ppCheckbox) *ppCheckbox = cb;
return w;
}
Configuration::impl::impl (Configuration * self, QDir const& temp_directory,
QSettings * settings, QWidget * parent)
: QDialog {parent}
@ -1115,6 +1136,7 @@ Configuration::impl::impl (Configuration * self, QDir const& temp_directory,
, writeable_data_dir_ {QStandardPaths::writableLocation (QStandardPaths::DataLocation)}
, restart_sound_input_device_ {false}
, restart_sound_output_device_ {false}
, restart_notification_sound_output_device_ {false}
, frequencies_ {&bands_}
, next_frequencies_ {&bands_}
, stations_ {&bands_}
@ -1277,8 +1299,12 @@ Configuration::impl::impl (Configuration * self, QDir const& temp_directory,
function<void (int)> cb (bind (&Configuration::impl::update_audio_channels, this, ui_->sound_input_combo_box, _1, ui_->sound_input_channel_combo_box, false));
connect (ui_->sound_input_combo_box, static_cast<void (QComboBox::*)(int)> (&QComboBox::currentIndexChanged), cb);
cb = bind (&Configuration::impl::update_audio_channels, this, ui_->sound_output_combo_box, _1, ui_->sound_output_channel_combo_box, true);
connect (ui_->sound_output_combo_box, static_cast<void (QComboBox::*)(int)> (&QComboBox::currentIndexChanged), cb);
cb = bind (&Configuration::impl::update_audio_channels, this, ui_->notification_sound_output_combo_box, _1, ui_->notification_sound_output_channel_combo_box, true);
connect (ui_->notification_sound_output_combo_box, static_cast<void (QComboBox::*)(int)> (&QComboBox::currentIndexChanged), cb);
}
//
@ -1335,6 +1361,63 @@ Configuration::impl::impl (Configuration * self, QDir const& temp_directory,
ui_->frequencies_table_view->insertAction (nullptr, reset_frequencies_action_);
connect (reset_frequencies_action_, &QAction::triggered, this, &Configuration::impl::reset_frequencies);
//
// setup notifications table view
//
QMap<QString, QString> notifyRows = {
{"notify_cq", "CQ Message Received"},
{"notify_hb", "HB Message Received"},
{"notify_directed", "Directed Message Received"},
{"notify_relay", "Relay Message Received"},
{"notify_new_call", "New Callsign Heard"},
{"notify_worked_call", "Worked Callsign Heard"},
};
int i = 0;
auto table = ui_->notifications_table_widget;
foreach(QString key, notifyRows.keys()){
QCheckBox *vcb;
auto w1 = centeredCheckBox(this, &vcb);
if(vcb){
vcb->setChecked(true);
}
QCheckBox *acb;
auto w2 = centeredCheckBox(this, &acb);
if(acb){
acb->setChecked(true);
}
QWidget *w3 = new QWidget(this);
QHBoxLayout *l3 = new QHBoxLayout(w3);
l3->setContentsMargins(9,1,1,1);
w3->setLayout(l3);
QLabel *sflb = new QLabel(this);
sflb->setText("/tmp/file.wav");
l3->addWidget(sflb);
QPushButton *sfpb1 = new QPushButton(this);
sfpb1->setText("Select");
l3->addWidget(sfpb1);
QPushButton *sfpb3 = new QPushButton(this);
sfpb3->setText("Clear");
l3->addWidget(sfpb3);
//
table->insertRow(i);
auto labelItem = new QTableWidgetItem(notifyRows.value(key));
table->setItem(i, 0, labelItem);
table->setCellWidget(i, 1, w1);
table->setCellWidget(i, 2, w2);
table->setCellWidget(i, 3, w3);
i++;
}
table->resizeColumnsToContents();
//
// setup stations table model & view
@ -1371,12 +1454,15 @@ Configuration::impl::impl (Configuration * self, QDir const& temp_directory,
//
default_audio_input_device_selected_ = load_audio_devices (QAudio::AudioInput, ui_->sound_input_combo_box, &audio_input_device_);
default_audio_output_device_selected_ = load_audio_devices (QAudio::AudioOutput, ui_->sound_output_combo_box, &audio_output_device_);
default_notification_audio_output_device_selected_ = load_audio_devices (QAudio::AudioOutput, ui_->notification_sound_output_combo_box, &notification_audio_output_device_);
update_audio_channels (ui_->sound_input_combo_box, ui_->sound_input_combo_box->currentIndex (), ui_->sound_input_channel_combo_box, false);
update_audio_channels (ui_->sound_output_combo_box, ui_->sound_output_combo_box->currentIndex (), ui_->sound_output_channel_combo_box, true);
update_audio_channels (ui_->notification_sound_output_combo_box, ui_->notification_sound_output_combo_box->currentIndex (), ui_->notification_sound_output_channel_combo_box, true);
ui_->sound_input_channel_combo_box->setCurrentIndex (audio_input_channel_);
ui_->sound_output_channel_combo_box->setCurrentIndex (audio_output_channel_);
ui_->notification_sound_output_channel_combo_box->setCurrentIndex (notification_audio_output_channel_);
enumerate_rigs ();
initialize_models ();
@ -1718,9 +1804,36 @@ void Configuration::impl::read_settings ()
}
}
{
//
// retrieve notification audio output device
//
auto saved_name = settings_->value("NotificationSoundOutName").toString();
// deal with special Windows default audio devices
auto default_device = QAudioDeviceInfo::defaultOutputDevice ();
if (saved_name == default_device.deviceName ())
{
notification_audio_output_device_ = default_device;
default_notification_audio_output_device_selected_ = true;
}
else
{
default_notification_audio_output_device_selected_ = false;
Q_FOREACH (auto const& p, QAudioDeviceInfo::availableDevices (QAudio::AudioOutput)) // available audio output devices
{
if (p.deviceName () == saved_name)
{
notification_audio_output_device_ = p;
}
}
}
}
// retrieve audio channel info
audio_input_channel_ = AudioDevice::fromString (settings_->value ("AudioInputChannel", "Mono").toString ());
audio_output_channel_ = AudioDevice::fromString (settings_->value ("AudioOutputChannel", "Mono").toString ());
notification_audio_output_channel_ = AudioDevice::fromString (settings_->value ("NotificationAudioOutputChannel", "Mono").toString ());
type_2_msg_gen_ = settings_->value ("Type2MsgGen", QVariant::fromValue (Configuration::type_2_msg_3_full)).value<Configuration::Type2MsgGen> ();
@ -1903,8 +2016,19 @@ void Configuration::impl::write_settings ()
settings_->setValue ("SoundOutName", audio_output_device_.deviceName ());
}
if (default_notification_audio_output_device_selected_)
{
settings_->setValue ("NotificationSoundOutName", QAudioDeviceInfo::defaultOutputDevice ().deviceName ());
}
else
{
settings_->setValue ("NotificationSoundOutName", notification_audio_output_device_.deviceName ());
}
settings_->setValue ("AudioInputChannel", AudioDevice::toString (audio_input_channel_));
settings_->setValue ("AudioOutputChannel", AudioDevice::toString (audio_output_channel_));
settings_->setValue ("NotificationAudioOutputChannel", AudioDevice::toString (notification_audio_output_channel_));
settings_->setValue ("Type2MsgGen", QVariant::fromValue (type_2_msg_gen_));
settings_->setValue ("TransmitDirected", transmit_directed_);
settings_->setValue ("AutoreplyOnAtStartup", autoreply_on_at_startup_);
@ -2432,6 +2556,35 @@ void Configuration::impl::accept ()
}
}
{
auto const& device_name = ui_->notification_sound_output_combo_box->currentText ();
if (device_name != notification_audio_output_device_.deviceName ())
{
auto const& default_device = QAudioDeviceInfo::defaultOutputDevice ();
if (device_name == default_device.deviceName ())
{
notification_audio_output_device_ = default_device;
}
else
{
bool found {false};
Q_FOREACH (auto const& d, QAudioDeviceInfo::availableDevices (QAudio::AudioOutput))
{
if (device_name == d.deviceName ())
{
notification_audio_output_device_ = d;
found = true;
}
}
if (!found)
{
notification_audio_output_device_ = default_device;
}
}
restart_notification_sound_output_device_ = true;
}
}
if (audio_input_channel_ != static_cast<AudioDevice::Channel> (ui_->sound_input_channel_combo_box->currentIndex ()))
{
audio_input_channel_ = static_cast<AudioDevice::Channel> (ui_->sound_input_channel_combo_box->currentIndex ());
@ -2446,6 +2599,13 @@ void Configuration::impl::accept ()
}
Q_ASSERT (audio_output_channel_ <= AudioDevice::Both);
if (notification_audio_output_channel_ != static_cast<AudioDevice::Channel> (ui_->notification_sound_output_channel_combo_box->currentIndex ()))
{
notification_audio_output_channel_ = static_cast<AudioDevice::Channel> (ui_->notification_sound_output_channel_combo_box->currentIndex ());
restart_notification_sound_output_device_ = true;
}
Q_ASSERT (notification_audio_output_channel_ <= AudioDevice::Both);
auto_switch_bands_ = ui_->auto_switch_bands_check_box->isChecked();
my_callsign_ = ui_->callsign_line_edit->text ().toUpper().trimmed();
my_grid_ = ui_->grid_line_edit->text ().toUpper().trimmed();

View File

@ -86,6 +86,8 @@ public:
AudioDevice::Channel audio_input_channel () const;
QAudioDeviceInfo const& audio_output_device () const;
AudioDevice::Channel audio_output_channel () const;
QAudioDeviceInfo const& notification_audio_output_device () const;
AudioDevice::Channel notification_audio_output_channel () const;
// These query methods should be used after a call to exec() to
// determine if either the audio input or audio output stream
@ -93,6 +95,7 @@ public:
// re-opened if they return true.
bool restart_audio_input () const;
bool restart_audio_output () const;
bool restart_notification_audio_output () const;
bool use_dynamic_grid() const;
QString my_callsign () const;

View File

@ -23,7 +23,7 @@
<string>Select tab to change configuration parameters.</string>
</property>
<property name="currentIndex">
<number>0</number>
<number>6</number>
</property>
<widget class="QWidget" name="general_tab">
<attribute name="title">
@ -793,8 +793,8 @@ text message.</string>
<rect>
<x>0</x>
<y>0</y>
<width>738</width>
<height>453</height>
<width>616</width>
<height>331</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_16">
@ -1517,7 +1517,7 @@ a few, particularly some Kenwood rigs, require it).</string>
<rect>
<x>0</x>
<y>0</y>
<width>494</width>
<width>718</width>
<height>490</height>
</rect>
</property>
@ -1921,8 +1921,8 @@ this setting allows you to select which audio input will be used
<rect>
<x>0</x>
<y>0</y>
<width>266</width>
<height>329</height>
<width>760</width>
<height>502</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_29">
@ -1944,7 +1944,7 @@ this setting allows you to select which audio input will be used
<string>Souncard</string>
</property>
<property name="title">
<string>Soundcard</string>
<string>Modulation Soundcard</string>
</property>
<layout class="QGridLayout" name="gridLayout_6">
<item row="1" column="1">
@ -2057,6 +2057,72 @@ both here.</string>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="notification_soundcard_group_box">
<property name="title">
<string>Notification Soundcard</string>
</property>
<layout class="QGridLayout" name="gridLayout_18">
<item row="0" column="0">
<widget class="QLabel" name="notification_sound_output_label">
<property name="text">
<string>O&amp;utput:</string>
</property>
<property name="buddy">
<cstring>sound_output_combo_box</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="notification_sound_output_combo_box">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Select the audio CODEC to use for transmitting.
If this is your default device for system sounds then
ensure that all system sounds are disabled otherwise
you will broadcast any systems sounds generated during
transmitting periods.</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QComboBox" name="notification_sound_output_channel_combo_box">
<property name="toolTip">
<string>Select the audio channel used for transmission.
Unless you have multiple radios connected on different
channels; then you will usually want to select mono or
both here.</string>
</property>
<item>
<property name="text">
<string>Mono</string>
</property>
</item>
<item>
<property name="text">
<string>Left</string>
</property>
</item>
<item>
<property name="text">
<string>Right</string>
</property>
</item>
<item>
<property name="text">
<string>Both</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="save_path_group_box">
<property name="toolTip">
@ -2201,6 +2267,9 @@ both here.</string>
</property>
</spacer>
</item>
<item>
<widget class="QWidget" name="widget_2" native="true"/>
</item>
</layout>
</widget>
</widget>
@ -2234,7 +2303,7 @@ both here.</string>
<rect>
<x>0</x>
<y>0</y>
<width>562</width>
<width>746</width>
<height>663</height>
</rect>
</property>
@ -2729,8 +2798,8 @@ for assessing propagation and system performance.</string>
<rect>
<x>0</x>
<y>0</y>
<width>487</width>
<height>341</height>
<width>760</width>
<height>502</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_31">
@ -3045,6 +3114,95 @@ QListView::item:hover {
</item>
</layout>
</widget>
<widget class="QWidget" name="notifications_tab">
<attribute name="title">
<string>&amp;Notifications</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_32">
<item>
<widget class="QScrollArea" name="scrollArea_12">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents_11">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>760</width>
<height>502</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_35">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QTableWidget" name="notifications_table_widget">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum>
</property>
<property name="showGrid">
<bool>true</bool>
</property>
<attribute name="horizontalHeaderDefaultSectionSize">
<number>125</number>
</attribute>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
<column>
<property name="text">
<string>Event</string>
</property>
</column>
<column>
<property name="text">
<string>Visual Alert?</string>
</property>
</column>
<column>
<property name="text">
<string>Audio Alert?</string>
</property>
</column>
<column>
<property name="text">
<string>Sound File</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="colors_tab">
<attribute name="title">
<string>&amp;UI</string>
@ -3110,8 +3268,8 @@ QListView::item:hover {
<rect>
<x>0</x>
<y>0</y>
<width>274</width>
<height>690</height>
<width>724</width>
<height>418</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_14">
@ -4370,12 +4528,12 @@ soundcard changes</string>
</connection>
</connections>
<buttongroups>
<buttongroup name="CAT_handshake_button_group"/>
<buttongroup name="TX_audio_source_button_group"/>
<buttongroup name="TX_mode_button_group"/>
<buttongroup name="CAT_stop_bits_button_group"/>
<buttongroup name="PTT_method_button_group"/>
<buttongroup name="split_mode_button_group"/>
<buttongroup name="TX_audio_source_button_group"/>
<buttongroup name="CAT_handshake_button_group"/>
<buttongroup name="CAT_data_bits_button_group"/>
<buttongroup name="CAT_stop_bits_button_group"/>
</buttongroups>
</ui>

158
NotificationAudio.cpp Normal file
View File

@ -0,0 +1,158 @@
#include "NotificationAudio.h"
NotificationAudio::NotificationAudio(QObject *parent) :
QIODevice(parent),
m_state(State::Stopped),
m_input(&m_data),
m_output(&m_data),
m_decoder(nullptr),
m_audio(nullptr)
{
setOpenMode(QIODevice::ReadOnly);
m_init = false;
m_isDecodingFinished = false;
}
// initialize an audio device
void NotificationAudio::init(const QAudioDeviceInfo &device, const QAudioFormat& format) {
m_device = device;
m_format = format;
if(!m_decoder){
m_decoder = new QAudioDecoder(this);
connect(m_decoder, &QAudioDecoder::bufferReady, this, &NotificationAudio::bufferReady);
connect(m_decoder, &QAudioDecoder::finished, this, &NotificationAudio::finished);
}
m_decoder->setAudioFormat(m_format);
if(!m_audio){
m_audio = new QAudioOutput(m_device, m_format);
}
if (!m_output.open(QIODevice::ReadOnly) || !m_input.open(QIODevice::WriteOnly)){
m_init = false;
return;
}
m_init = true;
emit initialized();
}
// play an audio file
void NotificationAudio::play(const QString &filePath) {
QFile *file = new QFile(this);
file->setFileName(filePath);
if (!file->open(QIODevice::ReadOnly)){
return;
}
playFile(file);
}
void NotificationAudio::playFile(QFile *file){
if(!m_init || !m_decoder || !m_audio || !file){
return;
}
resetBuffers();
m_file = file;
m_decoder->setSourceDevice(m_file);
m_decoder->start();
m_state = State::Playing;
emit stateChanged(m_state);
m_audio->start(this);
}
// Stop playing audio
void NotificationAudio::stop() {
resetBuffers();
m_state = State::Stopped;
emit stateChanged(m_state);
}
// Reset the internal buffers and ensure the decoder and audio device is stopped
void NotificationAudio::resetBuffers() {
if(m_audio){
if(m_audio->state() != QAudio::StoppedState){
m_audio->stop();
}
}
if(m_decoder){
if(m_decoder->state() != QAudioDecoder::StoppedState){
m_decoder->stop();
}
}
if(m_file){
if(m_file->isOpen()){
m_file->close();
}
delete m_file;
m_file = nullptr;
}
m_data.clear();
m_isDecodingFinished = false;
}
// io device, read into buffer.
qint64 NotificationAudio::readData(char* data, qint64 maxlen) {
memset(data, 0, maxlen);
if (m_state == State::Playing)
{
m_output.read(data, maxlen);
// There is we send readed audio data via signal, for ability get audio signal for the who listen this signal.
// Other word this emulate QAudioProbe behaviour for retrieve audio data which of sent to output device (speaker).
if (maxlen > 0)
{
QByteArray buff(data, maxlen);
emit newData(buff);
}
// Is finish of file
if (atEnd())
{
stop();
}
}
return maxlen;
}
// io device, unused.
qint64 NotificationAudio::writeData(const char* data, qint64 len) {
Q_UNUSED(data);
Q_UNUSED(len);
return 0;
}
// io device, at end of device
bool NotificationAudio::atEnd() const {
return m_output.size()
&& m_output.atEnd()
&& m_isDecodingFinished;
}
// handle buffered data ready
void NotificationAudio::bufferReady() {
const QAudioBuffer &buffer = m_decoder->read();
const int length = buffer.byteCount();
const char *data = buffer.constData<char>();
m_input.write(data, length);
}
// handle buffered data decoding is finished
void NotificationAudio::finished() {
m_isDecodingFinished = true;
}

65
NotificationAudio.h Normal file
View File

@ -0,0 +1,65 @@
#ifndef NOTIFICATIONAUDIO_H
#define NOTIFICATIONAUDIO_H
#include <QIODevice>
#include <QBuffer>
#include <QAudioDecoder>
#include <QAudioDeviceInfo>
#include <QAudioFormat>
#include <QAudioOutput>
#include <QFile>
// Class for decode audio files like MP3 and push decoded audio data to QOutputDevice (like speaker) and also signal newData().
// For decoding it uses QAudioDecoder which uses QAudioFormat for decode audio file for desire format, then put decoded data to buffer.
// based on: https://github.com/Znurre/QtMixer
class NotificationAudio : public QIODevice
{
Q_OBJECT
public:
NotificationAudio(QObject * parent=nullptr);
bool isInitialized() const { return m_init; }
enum State { Playing, Stopped };
bool atEnd() const override;
public slots:
void init(const QAudioDeviceInfo &device, const QAudioFormat& format);
void play(const QString &filePath);
void stop();
protected:
qint64 readData(char* data, qint64 maxlen) override;
qint64 writeData(const char* data, qint64 len) override;
private:
QFile *m_file;
State m_state;
QBuffer m_input;
QBuffer m_output;
QByteArray m_data;
QAudioFormat m_format;
QAudioDeviceInfo m_device;
QAudioDecoder * m_decoder;
QAudioOutput * m_audio;
bool m_init;
bool m_isDecodingFinished;
void playFile(QFile *file);
void resetBuffers();
private slots:
void bufferReady();
void finished();
signals:
void initialized();
void stateChanged(NotificationAudio::State state);
void newData(const QByteArray& data);
};
#endif // NOTIFICATIONAUDIO_H

View File

@ -84,7 +84,8 @@ SOURCES += \
messagewindow.cpp \
SpotClient.cpp \
TCPClient.cpp \
TransmitTextEdit.cpp
TransmitTextEdit.cpp \
NotificationAudio.cpp
HEADERS += qt_helpers.hpp \
pimpl_h.hpp pimpl_impl.hpp \
@ -120,7 +121,8 @@ HEADERS += qt_helpers.hpp \
SpotClient.h \
TCPClient.h \
logbook/n3fjp.h \
TransmitTextEdit.h
TransmitTextEdit.h \
NotificationAudio.h
INCLUDEPATH += qmake_only

View File

@ -72,6 +72,7 @@
#include "jsc_checker.h"
#include "Inbox.h"
#include "messagewindow.h"
#include "NotificationAudio.h"
#include "ui_mainwindow.h"
#include "moc_mainwindow.cpp"
@ -300,6 +301,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
m_soundInput {new SoundInput},
m_modulator {new Modulator {TX_SAMPLE_RATE, NTMAX}},
m_soundOutput {new SoundOutput},
m_notification {new NotificationAudio},
m_msErase {0},
m_secBandChanged {0},
m_freqNominal {0},
@ -501,6 +503,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
m_modulator->moveToThread (&m_audioThread);
m_soundInput->moveToThread (&m_audioThread);
m_detector->moveToThread (&m_audioThread);
m_notification->moveToThread(&m_audioThread);
// hook up sound output stream slots & signals and disposal
connect (this, &MainWindow::initializeAudioOutputStream, m_soundOutput, &SoundOutput::setFormat);
@ -509,6 +512,13 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
connect (this, &MainWindow::outAttenuationChanged, m_soundOutput, &SoundOutput::setAttenuation);
connect (&m_audioThread, &QThread::finished, m_soundOutput, &QObject::deleteLater);
connect(this, &MainWindow::initializeNotificationAudioOutputStream, m_notification, &NotificationAudio::init);
connect(m_notification, &NotificationAudio::initialized, this, [this](){
emit playNotification("/tmp/test.wav");
});
connect(this, &MainWindow::playNotification, m_notification, &NotificationAudio::play);
connect (&m_audioThread, &QThread::finished, m_notification, &QObject::deleteLater);
// hook up Modulator slots and disposal
connect (this, &MainWindow::transmitFrequency, m_modulator, &Modulator::setFrequency);
connect (this, &MainWindow::endTransmitMessage, m_modulator, &Modulator::stop);
@ -3003,6 +3013,12 @@ void MainWindow::openSettings(int tab){
m_msAudioOutputBuffered);
}
if(m_config.restart_notification_audio_output ()) {
Q_EMIT initializeNotificationAudioOutputStream(
m_config.notification_audio_output_device(),
m_config.notification_audio_output_device().preferredFormat());
}
ui->bandComboBox->view ()->setMinimumWidth (ui->bandComboBox->view ()->sizeHintForColumn (FrequencyList_v2::frequency_mhz_column));
displayDialFrequency ();

View File

@ -48,6 +48,7 @@
#include "SpotClient.h"
#include "APRSISClient.h"
#include "keyeater.h"
#include "NotificationAudio.h"
#define NUM_JT4_SYMBOLS 206 //(72+31)*2, embedded sync
#define NUM_JT65_SYMBOLS 126 //63 data + 63 sync
@ -434,6 +435,8 @@ private slots:
void refreshTextDisplay();
private:
Q_SIGNAL void playNotification(const QString &name);
Q_SIGNAL void initializeNotificationAudioOutputStream(QAudioDeviceInfo, QAudioFormat);
Q_SIGNAL void initializeAudioOutputStream (QAudioDeviceInfo,
unsigned channels, unsigned msBuffered) const;
Q_SIGNAL void stopAudioOutputStream () const;
@ -502,6 +505,7 @@ private:
SoundInput * m_soundInput;
Modulator * m_modulator;
SoundOutput * m_soundOutput;
NotificationAudio * m_notification;
QThread m_audioThread;
qint64 m_msErase;