diff --git a/include/aoapplication.h b/include/aoapplication.h index cf9eb2b..48b30a1 100644 --- a/include/aoapplication.h +++ b/include/aoapplication.h @@ -204,6 +204,9 @@ public: // Returns the value of default_blip in config.ini int get_default_blip(); + // Returns the value of suppress_audio in config.ini + int get_default_suppress_audio(); + // Returns the value if objections interrupt and skip the message queue // from the config.ini. bool is_instant_objection_enabled(); diff --git a/include/aoblipplayer.h b/include/aoblipplayer.h index a11e29d..ea2dcd3 100644 --- a/include/aoblipplayer.h +++ b/include/aoblipplayer.h @@ -18,6 +18,7 @@ public: void set_blips(QString p_sfx); void blip_tick(); void set_volume(int p_volume); + void set_muted(bool toggle); int m_cycle = 0; @@ -26,6 +27,8 @@ private: AOApplication *ao_app; qreal m_volume; + bool m_muted = false; + void set_volume_internal(qreal p_volume); HSTREAM m_stream_list[5]; diff --git a/include/aomusicplayer.h b/include/aomusicplayer.h index d00ab8e..037525f 100644 --- a/include/aomusicplayer.h +++ b/include/aomusicplayer.h @@ -20,6 +20,7 @@ public: virtual ~AOMusicPlayer(); void set_volume(int p_value, int channel = -1); void set_looping(bool toggle, int channel = 0); + void set_muted(bool toggle); const int m_channelmax = 4; @@ -39,6 +40,7 @@ private: AOApplication *ao_app; bool m_looping = false; + bool m_muted = false; int m_volume[4] = {0, 0, 0, 0}; // Channel 0 = music diff --git a/include/aooptionsdialog.h b/include/aooptionsdialog.h index 2180379..cb9b71b 100644 --- a/include/aooptionsdialog.h +++ b/include/aooptionsdialog.h @@ -127,8 +127,10 @@ private: QLabel *ui_music_volume_lbl; QSpinBox *ui_sfx_volume_spinbox; QSpinBox *ui_blips_volume_spinbox; + QSpinBox *ui_suppress_audio_spinbox; QLabel *ui_sfx_volume_lbl; QLabel *ui_blips_volume_lbl; + QLabel *ui_suppress_audio_lbl; QFrame *ui_volume_blip_divider; QSpinBox *ui_bliprate_spinbox; QLabel *ui_bliprate_lbl; diff --git a/include/aosfxplayer.h b/include/aosfxplayer.h index 7597636..077a7ef 100644 --- a/include/aosfxplayer.h +++ b/include/aosfxplayer.h @@ -20,14 +20,16 @@ public: void stop(int channel = -1); void set_volume(qreal p_volume); void set_looping(bool toggle, int channel = -1); + void set_muted(bool toggle); int m_channel = 0; - + int get_volume() { return m_volume * 100; }; private: QWidget *m_parent; AOApplication *ao_app; qreal m_volume = 0; bool m_looping = true; + bool m_muted = false; void set_volume_internal(qreal p_volume); const int m_channelmax = 5; diff --git a/include/courtroom.h b/include/courtroom.h index 73ef6fb..43cecf3 100644 --- a/include/courtroom.h +++ b/include/courtroom.h @@ -69,6 +69,8 @@ class Courtroom : public QMainWindow { public: explicit Courtroom(AOApplication *p_ao_app); + void update_audio_volume(); + void append_char(char_type p_char) { char_list.append(p_char); } void append_evidence(evi_type p_evi) { evidence_list.append(p_evi); } void append_music(QString f_music) { music_list.append(f_music); } @@ -338,6 +340,9 @@ public: private: AOApplication *ao_app; + // Percentage of audio that is suppressed when client is not in focus + int suppress_audio = 0; + int m_courtroom_width = 714; int m_courtroom_height = 668; @@ -988,6 +993,8 @@ private slots: void on_casing_clicked(); + void on_application_state_changed(Qt::ApplicationState state); + void ping_server(); // Proceed to parse the oldest chatmessage and remove it from the stack diff --git a/src/aoblipplayer.cpp b/src/aoblipplayer.cpp index 307a0bd..5dc2467 100644 --- a/src/aoblipplayer.cpp +++ b/src/aoblipplayer.cpp @@ -37,6 +37,12 @@ void AOBlipPlayer::blip_tick() BASS_ChannelPlay(f_stream, false); } +void AOBlipPlayer::set_muted(bool toggle) +{ + m_muted = toggle; + set_volume_internal(m_volume); +} + void AOBlipPlayer::set_volume(int p_value) { m_volume = static_cast(p_value) / 100; @@ -45,7 +51,8 @@ void AOBlipPlayer::set_volume(int p_value) void AOBlipPlayer::set_volume_internal(qreal p_value) { - float volume = static_cast(p_value); + // If muted, volume will always be 0 + float volume = static_cast(p_value) * !m_muted; for (int n_stream = 0; n_stream < 5; ++n_stream) { BASS_ChannelSetAttribute(m_stream_list[n_stream], BASS_ATTRIB_VOL, volume); diff --git a/src/aomusicplayer.cpp b/src/aomusicplayer.cpp index 16db163..59cf4d2 100644 --- a/src/aomusicplayer.cpp +++ b/src/aomusicplayer.cpp @@ -159,10 +159,20 @@ void AOMusicPlayer::stop(int channel) BASS_ChannelStop(m_stream_list[channel]); } +void AOMusicPlayer::set_muted(bool toggle) +{ + m_muted = toggle; + // Update all volume based on the mute setting + for (int n_stream = 0; n_stream < m_channelmax; ++n_stream) { + set_volume(m_volume[n_stream], n_stream); + } +} + void AOMusicPlayer::set_volume(int p_value, int channel) { m_volume[channel] = p_value; - float volume = m_volume[channel] / 100.0f; + // If muted, volume will always be 0 + float volume = (m_volume[channel] / 100.0f) * !m_muted; if (channel < 0) { for (int n_stream = 0; n_stream < m_channelmax; ++n_stream) { BASS_ChannelSetAttribute(m_stream_list[n_stream], BASS_ATTRIB_VOL, diff --git a/src/aooptionsdialog.cpp b/src/aooptionsdialog.cpp index 759d49d..c0ac7c5 100644 --- a/src/aooptionsdialog.cpp +++ b/src/aooptionsdialog.cpp @@ -595,6 +595,21 @@ AOOptionsDialog::AOOptionsDialog(QWidget *parent, AOApplication *p_ao_app) ui_audio_layout->setWidget(row, QFormLayout::FieldRole, ui_blips_volume_spinbox); + row += 1; + ui_suppress_audio_lbl = new QLabel(ui_audio_widget); + ui_suppress_audio_lbl->setText(tr("Suppress Audio:")); + ui_suppress_audio_lbl->setToolTip( + tr("How much of the volume to suppress when client is not in focus.")); + + ui_audio_layout->setWidget(row, QFormLayout::LabelRole, ui_suppress_audio_lbl); + + ui_suppress_audio_spinbox = new QSpinBox(ui_audio_widget); + ui_suppress_audio_spinbox->setMaximum(100); + ui_suppress_audio_spinbox->setSuffix("%"); + + ui_audio_layout->setWidget(row, QFormLayout::FieldRole, + ui_suppress_audio_spinbox); + row += 1; ui_volume_blip_divider = new QFrame(ui_audio_widget); ui_volume_blip_divider->setFrameShape(QFrame::HLine); @@ -1192,6 +1207,7 @@ void AOOptionsDialog::update_values() { ui_music_volume_spinbox->setValue(ao_app->get_default_music()); ui_sfx_volume_spinbox->setValue(ao_app->get_default_sfx()); ui_blips_volume_spinbox->setValue(ao_app->get_default_blip()); + ui_suppress_audio_spinbox->setValue(ao_app->get_default_suppress_audio()); ui_bliprate_spinbox->setValue(ao_app->read_blip_rate()); ui_default_showname_textbox->setText(ao_app->get_default_showname()); @@ -1272,6 +1288,7 @@ void AOOptionsDialog::save_pressed() configini->setValue("default_music", ui_music_volume_spinbox->value()); configini->setValue("default_sfx", ui_sfx_volume_spinbox->value()); configini->setValue("default_blip", ui_blips_volume_spinbox->value()); + configini->setValue("suppress_audio", ui_suppress_audio_spinbox->value()); configini->setValue("blip_rate", ui_bliprate_spinbox->value()); configini->setValue("blank_blip", ui_blank_blips_cb->isChecked()); configini->setValue("looping_sfx", ui_loopsfx_cb->isChecked()); diff --git a/src/aosfxplayer.cpp b/src/aosfxplayer.cpp index fcdeb94..8d88667 100644 --- a/src/aosfxplayer.cpp +++ b/src/aosfxplayer.cpp @@ -60,15 +60,23 @@ void AOSfxPlayer::stop(int channel) BASS_ChannelStop(m_stream_list[channel]); } +void AOSfxPlayer::set_muted(bool toggle) +{ + m_muted = toggle; + // Update the audio volume + set_volume_internal(m_volume); +} + void AOSfxPlayer::set_volume(qreal p_value) { - m_volume = p_value / 100; + m_volume = p_value * 0.01; set_volume_internal(m_volume); } void AOSfxPlayer::set_volume_internal(qreal p_value) { - float volume = static_cast(p_value); + // If muted, volume will always be 0 + float volume = static_cast(p_value) * !m_muted; for (int n_stream = 0; n_stream < m_channelmax; ++n_stream) { BASS_ChannelSetAttribute(m_stream_list[n_stream], BASS_ATTRIB_VOL, volume); } diff --git a/src/courtroom.cpp b/src/courtroom.cpp index 30d226e..e76ba41 100644 --- a/src/courtroom.cpp +++ b/src/courtroom.cpp @@ -26,18 +26,18 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow() sfx_delay_timer->setSingleShot(true); music_player = new AOMusicPlayer(this, ao_app); - music_player->set_volume(0); + music_player->set_muted(true); connect(&music_player->music_watcher, &QFutureWatcher::finished, this, &Courtroom::update_ui_music_name, Qt::QueuedConnection); sfx_player = new AOSfxPlayer(this, ao_app); - sfx_player->set_volume(0); + sfx_player->set_muted(true); objection_player = new AOSfxPlayer(this, ao_app); - objection_player->set_volume(0); + objection_player->set_muted(true); blip_player = new AOBlipPlayer(this, ao_app); - blip_player->set_volume(0); + blip_player->set_muted(true); modcall_player = new AOSfxPlayer(this, ao_app); modcall_player->set_volume(50); @@ -555,6 +555,9 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow() connect(ui_evidence_button, &AOButton::clicked, this, &Courtroom::on_evidence_button_clicked); + connect(qApp, QOverload::of(&QApplication::applicationStateChanged), this, + &Courtroom::on_application_state_changed); + connect(ui_vp_evidence_display, &AOEvidenceDisplay::show_evidence_details, this, &Courtroom::show_evidence); set_widgets(); @@ -562,6 +565,35 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow() set_char_select(); } +void Courtroom::on_application_state_changed(Qt::ApplicationState state) +{ + // Unsuppressed + suppress_audio = 0; + if (state != Qt::ApplicationActive) { + // Suppressed audio setting + suppress_audio = ao_app->get_default_suppress_audio(); + } + update_audio_volume(); +} + +void Courtroom::update_audio_volume() +{ + float remaining_percent = 1.0f - static_cast(suppress_audio / 100.0f); + if (remaining_percent > 1) + remaining_percent = 1; + if (remaining_percent < 0) + remaining_percent = 0; + + music_player->set_volume(ui_music_slider->value() * remaining_percent, 0); // set music + // Set the ambience and other misc. music layers + for (int i = 1; i < music_player->m_channelmax; ++i) { + music_player->set_volume(ui_sfx_slider->value() * remaining_percent, i); + } + sfx_player->set_volume(ui_sfx_slider->value() * remaining_percent); + objection_player->set_volume(ui_sfx_slider->value() * remaining_percent); + blip_player->set_volume(ui_blip_slider->value() * remaining_percent); +} + void Courtroom::set_courtroom_size() { QString filename = "courtroom_design.ini"; @@ -1282,11 +1314,6 @@ void Courtroom::done_received() { m_cid = -1; - music_player->set_volume(0); - sfx_player->set_volume(0); - objection_player->set_volume(0); - blip_player->set_volume(0); - if (char_list.size() > 0) { set_char_select(); @@ -1543,11 +1570,7 @@ void Courtroom::update_character(int p_cid) ui_char_select_background->hide(); ui_ic_chat_message->setEnabled(m_cid != -1); ui_ic_chat_message->setFocus(); - // have to call these to make sure music, sfx, and blips don't get accidentally muted forever when we change characters - music_player->set_volume(ui_music_slider->value(), 0); - objection_player->set_volume(ui_sfx_slider->value()); - sfx_player->set_volume(ui_sfx_slider->value()); - blip_player->set_volume(ui_blip_slider->value()); + update_audio_volume(); } void Courtroom::enter_courtroom() @@ -1594,14 +1617,14 @@ void Courtroom::enter_courtroom() break; } - music_player->set_volume(ui_music_slider->value(), 0); // set music - // Set the ambience and other misc. music layers - for (int i = 1; i < music_player->m_channelmax; ++i) { - music_player->set_volume(ui_sfx_slider->value(), i); - } - sfx_player->set_volume(ui_sfx_slider->value()); - objection_player->set_volume(ui_sfx_slider->value()); - blip_player->set_volume(ui_blip_slider->value()); + // Unmute everything + music_player->set_muted(false); + objection_player->set_muted(false); + sfx_player->set_muted(false); + blip_player->set_muted(false); + + // Update the audio sliders + update_audio_volume(); ui_vp_testimony->stop(); // ui_server_chatlog->setHtml(ui_server_chatlog->toHtml()); @@ -2902,7 +2925,7 @@ void Courtroom::display_evidence_image() bool is_left_side = !(side == "def" || side == "hlp" || side == "jud" || side == "jur"); ui_vp_evidence_display->show_evidence(f_evi_id, f_image, is_left_side, - ui_sfx_slider->value()); + sfx_player->get_volume()); } } @@ -5371,8 +5394,8 @@ void Courtroom::on_guilty_clicked() void Courtroom::on_change_character_clicked() { - sfx_player->set_volume(0); - blip_player->set_volume(0); + sfx_player->set_muted(true); + blip_player->set_muted(true); set_char_select(); diff --git a/src/text_file_functions.cpp b/src/text_file_functions.cpp index be162b2..dc95dc3 100644 --- a/src/text_file_functions.cpp +++ b/src/text_file_functions.cpp @@ -40,6 +40,12 @@ int AOApplication::get_default_blip() return result; } +int AOApplication::get_default_suppress_audio() +{ + int result = configini->value("suppress_audio", 50).toInt(); + return result; +} + int AOApplication::get_max_log_size() { int result = configini->value("log_maximum", 200).toInt();