aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSalanto <62221668+Salanto@users.noreply.github.com>2021-12-24 21:05:01 +0100
committerGitHub <noreply@github.com>2021-12-24 14:05:01 -0600
commit5ce0e6416e9e821be69219cc8a949c00e2cb462c (patch)
tree63e21560ce7fda46b7f61e82d109a7aebfcb8510 /src
parentd1fb7fde16ec37dfa7b13e0a02489417655d315d (diff)
Fix animation freeze when loading music files (#609)
* Implement async music loading * Simplify music filename parsing and fix "missing" on streams Co-authored-by: oldmud0 <oldmud0@users.noreply.github.com>
Diffstat (limited to 'src')
-rw-r--r--src/aomusicplayer.cpp39
-rw-r--r--src/courtroom.cpp47
2 files changed, 55 insertions, 31 deletions
diff --git a/src/aomusicplayer.cpp b/src/aomusicplayer.cpp
index d0d95635..16d6df7a 100644
--- a/src/aomusicplayer.cpp
+++ b/src/aomusicplayer.cpp
@@ -13,12 +13,13 @@ AOMusicPlayer::~AOMusicPlayer()
}
}
-int AOMusicPlayer::play(QString p_song, int channel, bool loop,
+QString AOMusicPlayer::play(QString p_song, int channel, bool loop,
int effect_flags)
{
+ QFuture<QString> invoking_future = music_watcher.future();
channel = channel % m_channelmax;
if (channel < 0) // wtf?
- return BASS_ERROR_NOCHAN;
+ return "[ERROR] Invalid Channel";
QString f_path = ao_app->get_real_path(ao_app->get_music_path(p_song));
unsigned int flags = BASS_STREAM_PRESCAN | BASS_STREAM_AUTOFREE |
@@ -43,6 +44,14 @@ int AOMusicPlayer::play(QString p_song, int channel, bool loop,
newstream = BASS_StreamCreateFile(FALSE, f_path.utf16(), 0, 0, flags);
}
+ int error_code = BASS_ErrorGetCode();
+
+ if (invoking_future.isCanceled() && channel == 0) {
+ // Target future has changed. This stream has become irrelevant.
+ // So even if the stream manages to finish after the latest one, we don't run
+ // into order issues.
+ return QString();
+ }
if (ao_app->get_audio_output_device() != "default")
BASS_ChannelSetDevice(m_stream_list[channel], BASS_GetDevice());
@@ -109,7 +118,7 @@ int AOMusicPlayer::play(QString p_song, int channel, bool loop,
BASS_ChannelStop(m_stream_list[channel]);
m_stream_list[channel] = newstream;
- BASS_ChannelPlay(m_stream_list[channel], false);
+ BASS_ChannelPlay(newstream, false);
if (effect_flags & FADE_IN) {
// Fade in our sample
BASS_ChannelSetAttribute(newstream, BASS_ATTRIB_VOL, 0);
@@ -120,12 +129,32 @@ int 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,
+ BASS_ChannelSetSync(newstream, 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.
- return BASS_ErrorGetCode();
+
+ bool is_stop = (p_song == "~stop.mp3");
+ QString p_song_clear = QUrl(p_song).fileName();
+ p_song_clear = p_song_clear.left(p_song_clear.lastIndexOf('.'));
+
+ if (is_stop) {
+ return QObject::tr("None");
+ }
+
+ if (error_code == BASS_ERROR_HANDLE) { // Cheap hack to see if file missing
+ return QObject::tr("[MISSING] %1").arg(p_song_clear);
+ }
+
+ if (p_song.startsWith("http") && channel == 0) {
+ return QObject::tr("[STREAM] %1").arg(p_song_clear);
+ }
+
+ if (channel == 0)
+ return p_song_clear;
+
+ return "";
}
void AOMusicPlayer::stop(int channel)
diff --git a/src/courtroom.cpp b/src/courtroom.cpp
index 3eda1635..a9f2da64 100644
--- a/src/courtroom.cpp
+++ b/src/courtroom.cpp
@@ -27,6 +27,8 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow()
music_player = new AOMusicPlayer(this, ao_app);
music_player->set_volume(0);
+ connect(&music_player->music_watcher, &QFutureWatcher<QString>::finished,
+ this, &Courtroom::update_ui_music_name, Qt::QueuedConnection);
sfx_player = new AOSfxPlayer(this, ao_app);
sfx_player->set_volume(0);
@@ -3807,13 +3809,8 @@ void Courtroom::handle_song(QStringList *p_contents)
int effect_flags = 0; // No effects by default - vanilla functionality
QString f_song = f_contents.at(0);
- QString f_song_clear = f_song.left(f_song.lastIndexOf("."));
- if (f_song.startsWith("http")) {
- QByteArray f_song_bytearray = f_song.toUtf8();
- QString f_song_decoded = QUrl::fromPercentEncoding(f_song_bytearray);
- f_song_clear = f_song_decoded.left(f_song_decoded.lastIndexOf("."));
- }
- f_song_clear = f_song_clear.right(f_song_clear.length() - (f_song_clear.lastIndexOf("/") + 1));
+ QString f_song_clear = QUrl(f_song).fileName();
+ f_song_clear = f_song_clear.left(f_song_clear.lastIndexOf('.'));
int n_char = f_contents.at(1).toInt(&ok);
if (!ok)
@@ -3862,27 +3859,25 @@ void Courtroom::handle_song(QStringList *p_contents)
}
}
- int error_code = music_player->play(f_song, channel, looping, effect_flags);
-
- if (is_stop) {
- ui_music_name->setText(tr("None"));
- return;
- }
-
- if (error_code == BASS_ERROR_HANDLE) { // Cheap hack to see if file missing
- ui_music_name->setText(tr("[MISSING] %1").arg(f_song_clear));
- return;
- }
-
- if (f_song.startsWith("http") && channel == 0) {
- ui_music_name->setText(tr("[STREAM] %1").arg(f_song_clear));
- return;
+ QFuture<QString> future = QtConcurrent::run(music_player, &AOMusicPlayer::play, f_song, channel,
+ looping, effect_flags);
+ if (channel == 0) {
+ // Current song UI only displays the song playing, not other channels.
+ // Any other music playing is irrelevant.
+ if (music_player->music_watcher.isRunning()) {
+ music_player->music_watcher.cancel();
+ }
+ music_player->music_watcher.setFuture(future);
+ ui_music_name->setText(tr("[LOADING] %1").arg(f_song_clear));
}
+}
- if (channel == 0){
- ui_music_name->setText(f_song_clear);
- return;
- }
+void Courtroom::update_ui_music_name()
+{
+ QString result = music_player->music_watcher.result();
+ if (result.isEmpty())
+ return;
+ ui_music_name->setText(result);
}
void Courtroom::handle_wtce(QString p_wtce, int variant)