diff options
| author | scatterflower <2956568+scatterflower@users.noreply.github.com> | 2020-08-19 16:40:37 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-08-19 16:40:37 -0500 |
| commit | 9eb0f53db1ae87058458eae267f2a72e3a0a8091 (patch) | |
| tree | dbf5ccd4d3a70a49cebfb84798e7b2b77583835f /src | |
| parent | cef0ebc6eb2ac549a5475bee332be35ab7f565fc (diff) | |
Reset BASS when switching devices; drop Qt Multimedia support (#262)
* Allow changing audio device on the fly while in a server
* Use default audio device if device in config doesn't exist
* Automatically change audio device to default when current one is invalid
* Destroy Qt Multimedia support
It was decided that there was not enough attention being given to Qt
Multimedia support to justify its continued maintenance simply as a
libre alternative to BASS. While substantial changes to audio were being
made in 2.8, the Qt Multimedia support code fell behind in disrepair.
It's clear that there is no vested interest in implementing audio
features twice for the sake of licensing.
When it's time to switch to another audio library, it will be done
unilaterally.
* CI: Use BASS for Linux build
Co-authored-by: oldmud0 <oldmud0@users.noreply.github.com>
Diffstat (limited to 'src')
| -rw-r--r-- | src/aoapplication.cpp | 61 | ||||
| -rw-r--r-- | src/aoblipplayer.cpp | 57 | ||||
| -rw-r--r-- | src/aomusicplayer.cpp | 69 | ||||
| -rw-r--r-- | src/aooptionsdialog.cpp | 11 | ||||
| -rw-r--r-- | src/aosfxplayer.cpp | 108 | ||||
| -rw-r--r-- | src/courtroom.cpp | 62 | ||||
| -rw-r--r-- | src/lobby.cpp | 15 |
7 files changed, 94 insertions, 289 deletions
diff --git a/src/aoapplication.cpp b/src/aoapplication.cpp index e1e9e7fe..fa58ab84 100644 --- a/src/aoapplication.cpp +++ b/src/aoapplication.cpp @@ -177,3 +177,64 @@ void AOApplication::call_announce_menu(Courtroom *court) AOCaseAnnouncerDialog announcer(nullptr, this, court); announcer.exec(); } + +// Callback for when BASS device is lost +void CALLBACK AOApplication::BASSreset(HSTREAM handle, DWORD channel, + DWORD data, void *user) +{ + doBASSreset(); +} + +void AOApplication::doBASSreset() +{ + BASS_Free(); + BASS_Init(-1, 48000, BASS_DEVICE_LATENCY, nullptr, nullptr); + load_bass_opus_plugin(); +} + +void AOApplication::initBASS() +{ + BASS_Free(); + // Change the default audio output device to be the one the user has given + // in his config.ini file for now. + unsigned int a = 0; + BASS_DEVICEINFO info; + + if (get_audio_output_device() == "default") { + BASS_Init(-1, 48000, BASS_DEVICE_LATENCY, nullptr, nullptr); + load_bass_opus_plugin(); + } + else { + for (a = 0; BASS_GetDeviceInfo(a, &info); a++) { + if (get_audio_output_device() == info.name) { + BASS_SetDevice(a); + BASS_Init(static_cast<int>(a), 48000, BASS_DEVICE_LATENCY, nullptr, + nullptr); + load_bass_opus_plugin(); + qDebug() << info.name << "was set as the default audio output device."; + return; + } + } + BASS_Init(-1, 48000, BASS_DEVICE_LATENCY, nullptr, nullptr); + load_bass_opus_plugin(); + } +} + +#if (defined(_WIN32) || defined(_WIN64)) +void AOApplication::load_bass_opus_plugin() +{ + BASS_PluginLoad("bassopus.dll", 0); +} +#elif (defined(LINUX) || defined(__linux__)) +void AOApplication::load_bass_opus_plugin() +{ + BASS_PluginLoad("libbassopus.so", 0); +} +#elif defined __APPLE__ +void AOApplication::load_bass_opus_plugin() +{ + BASS_PluginLoad("libbassopus.dylib", 0); +} +#else +#error This operating system is unsupported for BASS plugins. +#endif diff --git a/src/aoblipplayer.cpp b/src/aoblipplayer.cpp index 57b2d278..5b4d625c 100644 --- a/src/aoblipplayer.cpp +++ b/src/aoblipplayer.cpp @@ -1,6 +1,5 @@ #include "aoblipplayer.h" -#if defined(BASSAUDIO) // Using bass.dll for the blips AOBlipPlayer::AOBlipPlayer(QWidget *parent, AOApplication *p_ao_app) { m_parent = parent; @@ -37,8 +36,14 @@ void AOBlipPlayer::blip_tick() m_cycle = 0; HSTREAM f_stream = m_stream_list[f_cycle]; - if (ao_app->get_audio_output_device() != "default") + + BASS_ChannelSetDevice(f_stream, BASS_GetDevice()); + int f_bass_error = BASS_ErrorGetCode(); + if (f_bass_error == BASS_ERROR_DEVICE) { + ao_app->doBASSreset(); BASS_ChannelSetDevice(f_stream, BASS_GetDevice()); + } + BASS_ChannelPlay(f_stream, false); } @@ -56,51 +61,3 @@ void AOBlipPlayer::set_volume_internal(qreal p_value) BASS_ChannelSetAttribute(m_stream_list[n_stream], BASS_ATTRIB_VOL, volume); } } -#elif defined(QTAUDIO) // Using Qt's QSoundEffect class -AOBlipPlayer::AOBlipPlayer(QWidget *parent, AOApplication *p_ao_app) -{ - m_parent = parent; - ao_app = p_ao_app; -} - -void AOBlipPlayer::set_blips(QString p_sfx) -{ - QString f_path = ao_app->get_sounds_path(p_sfx); - - for (int n_stream = 0; n_stream < 5; ++n_stream) { - m_blips.setSource(QUrl::fromLocalFile(f_path)); - } - - set_volume(m_volume); -} - -void AOBlipPlayer::blip_tick() -{ - int f_cycle = m_cycle++; - - if (m_cycle == 5) - m_cycle = 0; - - m_blips.play(); -} - -void AOBlipPlayer::set_volume(int p_value) -{ - m_volume = p_value; - m_blips.setVolume(m_volume); -} -#else // No audio -AOBlipPlayer::AOBlipPlayer(QWidget *parent, AOApplication *p_ao_app) -{ - m_parent = parent; - ao_app = p_ao_app; -} - -void AOBlipPlayer::set_blips(QString p_sfx) {} - -void AOBlipPlayer::blip_tick() {} - -void AOBlipPlayer::set_volume(int p_value) {} - -void AOBlipPlayer::set_volume_internal(qreal p_value) {} -#endif diff --git a/src/aomusicplayer.cpp b/src/aomusicplayer.cpp index 249e01e5..6c61b9ad 100644 --- a/src/aomusicplayer.cpp +++ b/src/aomusicplayer.cpp @@ -1,14 +1,11 @@ #include "aomusicplayer.h" - AOMusicPlayer::AOMusicPlayer(QWidget *parent, AOApplication *p_ao_app) { m_parent = parent; ao_app = p_ao_app; } -#ifdef BASSAUDIO - AOMusicPlayer::~AOMusicPlayer() { for (int n_stream = 0; n_stream < m_channelmax; ++n_stream) { @@ -111,8 +108,11 @@ void AOMusicPlayer::play(QString p_song, int channel, bool loop, else this->set_volume(m_volume[channel], channel); + BASS_ChannelSetSync(m_stream_list[channel], BASS_SYNC_DEV_FAIL, 0, + ao_app->BASSreset, 0); + this->set_looping(loop, channel); // Have to do this here due to any - // crossfading-related changes, etc. + // crossfading-related changes, etc. } void AOMusicPlayer::stop(int channel) @@ -164,62 +164,13 @@ void AOMusicPlayer::set_looping(bool toggle, int channel) } if (loop_start[channel] > 0) { if (loop_end[channel] == 0) - loop_end[channel] = BASS_ChannelGetLength(m_stream_list[channel], BASS_POS_BYTE); - if (loop_end[channel] > 0) // Don't loop zero length songs even if we're asked to + loop_end[channel] = + BASS_ChannelGetLength(m_stream_list[channel], BASS_POS_BYTE); + if (loop_end[channel] > + 0) // Don't loop zero length songs even if we're asked to loop_sync[channel] = BASS_ChannelSetSync( - m_stream_list[channel], BASS_SYNC_POS | BASS_SYNC_MIXTIME, loop_end[channel], - loopProc, &loop_start[channel]); + m_stream_list[channel], BASS_SYNC_POS | BASS_SYNC_MIXTIME, + loop_end[channel], loopProc, &loop_start[channel]); } } } -#elif defined(QTAUDIO) - -AOMusicPlayer::~AOMusicPlayer() { - for (int n_stream = 0; n_stream < m_channelmax; ++n_stream) { - m_stream_list[n_stream].stop(); - } -} - -void AOMusicPlayer::play(QString p_song, int channel, bool loop, - int effect_flags) -{ - channel = channel % m_channelmax; - if (channel < 0) // wtf? - return; - QString f_path = ao_app->get_music_path(p_song); - - m_stream_list[channel].stop(); - - m_stream_list[channel].setMedia(QUrl::fromLocalFile(f_path)); - - this->set_volume(m_volume[channel], channel); - - m_stream_list[channel].play(); -} - -void AOMusicPlayer::stop(int channel) -{ - m_stream_list[channel].stop(); -} - -void AOMusicPlayer::set_volume(int p_value, int channel) -{ - m_volume[channel] = p_value; - m_stream_list[channel].setVolume(m_volume[channel]); -} - -#else - -AOMusicPlayer::~AOMusicPlayer() {} - -void AOMusicPlayer::play(QString p_song, int channel, bool loop, - int effect_flags) {} - -void AOMusicPlayer::stop(int channel) {} - -void AOMusicPlayer::set_volume(int p_value, int channel) {} - -void loopProc(int handle, int channel, int data, int *user) {} - -void AOMusicPlayer::set_looping(bool toggle, int channel) {} -#endif diff --git a/src/aooptionsdialog.cpp b/src/aooptionsdialog.cpp index 4e6aca65..6fc4d03e 100644 --- a/src/aooptionsdialog.cpp +++ b/src/aooptionsdialog.cpp @@ -445,7 +445,6 @@ AOOptionsDialog::AOOptionsDialog(QWidget *parent, AOApplication *p_ao_app) ui_audio_device_combobox->addItem("default"); //TODO translate this without breaking the default audio device } -#ifdef BASSAUDIO BASS_DEVICEINFO info; for (a = 0; BASS_GetDeviceInfo(a, &info); a++) { ui_audio_device_combobox->addItem(info.name); @@ -453,15 +452,6 @@ AOOptionsDialog::AOOptionsDialog(QWidget *parent, AOApplication *p_ao_app) ui_audio_device_combobox->setCurrentIndex( ui_audio_device_combobox->count() - 1); } -#elif defined QTAUDIO - foreach (const QAudioDeviceInfo &deviceInfo, - QAudioDeviceInfo::availableDevices(QAudio::AudioOutput)) { - ui_audio_device_combobox->addItem(deviceInfo.deviceName()); - if (p_ao_app->get_audio_output_device() == deviceInfo.deviceName()) - ui_audio_device_combobox->setCurrentIndex( - ui_audio_device_combobox->count() - 1); - } -#endif ui_audio_layout->setWidget(row, QFormLayout::FieldRole, ui_audio_device_combobox); @@ -816,6 +806,7 @@ void AOOptionsDialog::save_pressed() configini->setValue("casing_can_host_cases", ui_casing_cm_cases_textbox->text()); + ao_app->initBASS(); callwordsini->close(); done(0); } diff --git a/src/aosfxplayer.cpp b/src/aosfxplayer.cpp index 127bda63..8c4f3c86 100644 --- a/src/aosfxplayer.cpp +++ b/src/aosfxplayer.cpp @@ -1,14 +1,12 @@ #include "aosfxplayer.h" #include "file_functions.h" - AOSfxPlayer::AOSfxPlayer(QWidget *parent, AOApplication *p_ao_app) { m_parent = parent; ao_app = p_ao_app; } -#if defined(BASSAUDIO) // Using bass.dll for sfx void AOSfxPlayer::clear() { for (int n_stream = 0; n_stream < m_channelmax; ++n_stream) { @@ -68,9 +66,16 @@ void AOSfxPlayer::play(QString p_sfx, QString p_char, QString shout, set_volume_internal(m_volume); - if (ao_app->get_audio_output_device() != "default") + BASS_ChannelSetDevice(m_stream_list[m_channel], BASS_GetDevice()); + int f_bass_error = BASS_ErrorGetCode(); + if (f_bass_error == BASS_ERROR_DEVICE) { + ao_app->doBASSreset(); BASS_ChannelSetDevice(m_stream_list[m_channel], BASS_GetDevice()); + } + BASS_ChannelPlay(m_stream_list[m_channel], false); + BASS_ChannelSetSync(m_stream_list[channel], BASS_SYNC_DEV_FAIL, 0, + ao_app->BASSreset, 0); } void AOSfxPlayer::stop(int channel) @@ -112,100 +117,3 @@ void AOSfxPlayer::set_looping(bool toggle, int channel) BASS_SAMPLE_LOOP); // set the LOOP flag } } -#elif defined(QTAUDIO) // Using Qt's QSoundEffect class - -void AOSfxPlayer::clear() -{ - for (int n_stream = 0; n_stream < m_channelmax; ++n_stream) { - m_stream_list[n_stream].stop(); - } - set_volume_internal(m_volume); -} - -void AOSfxPlayer::loop_clear() -{ - for (int n_stream = 0; n_stream < m_channelmax; ++n_stream) { - m_stream_list[n_stream].stop(); - } - set_volume_internal(m_volume); -} - -void AOSfxPlayer::play(QString p_sfx, QString p_char, QString shout, - int channel) -{ - m_stream_list[channel].stop(); - - QString misc_path = ""; - QString char_path = ""; - QString sound_path = ao_app->get_sounds_path(p_sfx); - - if (shout != "") - misc_path = ao_app->get_base_path() + "misc/" + shout + "/" + p_sfx; - if (p_char != "") - char_path = ao_app->get_character_path(p_char, p_sfx); - - QString f_path; - - if (file_exists(char_path)) - f_path = char_path; - else if (file_exists(misc_path)) - f_path = misc_path; - else - f_path = sound_path; - - if (file_exists(f_path)) // if its missing, it will glitch out - { - m_stream_list[channel].setSource(QUrl::fromLocalFile(f_path)); - - set_volume_internal(m_volume); - - m_stream_list[channel].play(); - } -} - -void AOSfxPlayer::stop(int channel) -{ - if (channel == -1) { - channel = m_channel; - } - m_stream_list[channel].stop(); -} - -void AOSfxPlayer::set_volume(qreal p_value) -{ - m_volume = p_value / 100; - set_volume_internal(m_volume); -} - -void AOSfxPlayer::set_volume_internal(qreal p_value) -{ - float volume = static_cast<float>(p_value); - for (int n_stream = 0; n_stream < m_channelmax; ++n_stream) { - m_stream_list[n_stream].setVolume(volume); - } -} - -void AOSfxPlayer::set_looping(bool toggle, int channel) -{ - if (channel == -1) { - channel = m_channel; - } - m_looping = toggle; - // TODO -} -#else -void AOSfxPlayer::clear() {} - -void AOSfxPlayer::loop_clear() {} - -void AOSfxPlayer::play(QString p_sfx, QString p_char, QString shout, - int channel) {} - -void AOSfxPlayer::stop(int channel) {} - -void AOSfxPlayer::set_volume(qreal p_value) {} - -void AOSfxPlayer::set_volume_internal(qreal p_value) {} - -void AOSfxPlayer::set_looping(bool toggle, int channel) {} -#endif diff --git a/src/courtroom.cpp b/src/courtroom.cpp index fe10e134..2484bcb0 100644 --- a/src/courtroom.cpp +++ b/src/courtroom.cpp @@ -3,42 +3,7 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow() { ao_app = p_ao_app; -#ifdef BASSAUDIO - // Change the default audio output device to be the one the user has given - // in his config.ini file for now. - unsigned int a = 0; - BASS_DEVICEINFO info; - - if (ao_app->get_audio_output_device() == "default") { - BASS_Init(-1, 48000, BASS_DEVICE_LATENCY, nullptr, nullptr); - load_bass_opus_plugin(); - } - else { - for (a = 0; BASS_GetDeviceInfo(a, &info); a++) { - if (ao_app->get_audio_output_device() == info.name) { - BASS_SetDevice(a); - BASS_Init(static_cast<int>(a), 48000, BASS_DEVICE_LATENCY, nullptr, - nullptr); - load_bass_opus_plugin(); - qDebug() << info.name << "was set as the default audio output device."; - break; - } - } - } -#elif defined QTAUDIO - - if (ao_app->get_audio_output_device() != "default") { - foreach (const QAudioDeviceInfo &deviceInfo, - QAudioDeviceInfo::availableDevices(QAudio::AudioOutput)) { - if (ao_app->get_audio_output_device() == deviceInfo.deviceName()) { - ao_app->QtAudioDevice = deviceInfo; - qDebug() << deviceInfo.deviceName() - << "was set as the default audio output device."; - break; - } - } - } -#endif + ao_app->initBASS(); qsrand(static_cast<uint>(QDateTime::currentMSecsSinceEpoch() / 1000)); @@ -4750,28 +4715,3 @@ Courtroom::~Courtroom() delete objection_player; delete blip_player; } - -#if (defined(_WIN32) || defined(_WIN64)) -void Courtroom::load_bass_opus_plugin() -{ -#ifdef BASSAUDIO - BASS_PluginLoad("bassopus.dll", 0); -#endif -} -#elif (defined(LINUX) || defined(__linux__)) -void Courtroom::load_bass_opus_plugin() -{ -#ifdef BASSAUDIO - BASS_PluginLoad("libbassopus.so", 0); -#endif -} -#elif defined __APPLE__ -void Courtroom::load_bass_opus_plugin() -{ -#ifdef BASSAUDIO - BASS_PluginLoad("libbassopus.dylib", 0); -#endif -} -#else -#error This operating system is unsupported for bass plugins. -#endif diff --git a/src/lobby.cpp b/src/lobby.cpp index 3aa488ad..093b0f7d 100644 --- a/src/lobby.cpp +++ b/src/lobby.cpp @@ -5,6 +5,8 @@ #include "debug_functions.h" #include "networkmanager.h" +#include <QImageReader> + Lobby::Lobby(AOApplication *p_ao_app) : QMainWindow() { ao_app = p_ao_app; @@ -353,13 +355,7 @@ void Lobby::on_connect_released() void Lobby::on_about_clicked() { -#ifdef BASSAUDIO - const QString audio = "BASS"; -#elif defined(QTAUDIO) - const QString audio = "Qt Multimedia"; -#else - const QString audio = "null"; -#endif + const bool hasApng = QImageReader::supportedImageFormats().contains("APNG"); QString msg = tr("<h2>Attorney Online %1</h2>" @@ -389,11 +385,12 @@ void Lobby::on_about_clicked() "is copyright (c) 2016-2020 Attorney Online developers. Open-source " "licenses apply. All other assets are the property of their " "respective owners." - "<p>Running on Qt version %2 with the %3 audio engine." + "<p>Running on Qt version %2 with the BASS audio engine.<br>" + "APNG plugin loaded: %3" "<p>Built on %4") .arg(ao_app->get_version_string()) .arg(QLatin1String(QT_VERSION_STR)) - .arg(audio) + .arg(hasApng ? tr("Yes") : tr("No")) .arg(QLatin1String(__DATE__)); QMessageBox::about(this, tr("About"), msg); } |
