aboutsummaryrefslogtreecommitdiff
path: root/src/aomusicplayer.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/aomusicplayer.h')
-rw-r--r--src/aomusicplayer.h47
1 files changed, 39 insertions, 8 deletions
diff --git a/src/aomusicplayer.h b/src/aomusicplayer.h
index 707d64ad..b45c22fe 100644
--- a/src/aomusicplayer.h
+++ b/src/aomusicplayer.h
@@ -2,17 +2,20 @@
#include "aoapplication.h"
-#include <QFutureWatcher>
+#include <QNetworkAccessManager>
+#include <QPointer>
-class AOMusicPlayer
+class AOMusicPlayer : public QObject
{
+ Q_OBJECT
+
public:
// 0 = music
// 1 = ambience
static constexpr int STREAM_COUNT = 2;
explicit AOMusicPlayer(AOApplication *ao_app);
- virtual ~AOMusicPlayer();
+ ~AOMusicPlayer();
void setMuted(bool enabled);
@@ -21,18 +24,46 @@ public:
void setStreamVolume(int value, int streamId);
void setStreamLooping(bool enabled, int streamId);
- QFutureWatcher<QString> m_watcher;
+ void play_from_url(const QString &url, int id, bool looping, int flags);
+ void play_from_file(const QString &path, int id, bool looping, int flags);
private:
+ struct Stream
+ {
+ ma_sound sound;
+ QByteArray buffer;
+ ma_decoder decoder;
+ // I've had use-after-free crashes on `stop` due to QNetworkReply's lifetime
+ // being unclear (specifically, calling `abort` on it). QPointer is a
+ // bandaid fix.
+ QPointer<QNetworkReply> reply;
+ bool has_decoder;
+ enum
+ {
+ standby,
+ playing,
+ } state = standby;
+ };
+
+ // Default flags for music: STREAM decodes incrementally in 2-second chunks,
+ // the other two disable 3D positioning and Doppler effect.
+ const ma_uint32 m_flags = MA_SOUND_FLAG_STREAM | MA_SOUND_FLAG_NO_SPATIALIZATION | MA_SOUND_FLAG_NO_PITCH;
+
AOApplication *ao_app;
+ float m_volume[STREAM_COUNT]{};
bool m_muted = false;
-
- int m_volume[STREAM_COUNT]{};
- HSTREAM m_stream_list[STREAM_COUNT]{};
- HSYNC m_loop_sync[STREAM_COUNT]{};
+ Stream m_stream[STREAM_COUNT]{};
+ ma_pcm_rb m_audio_ring;
quint32 m_loop_start[STREAM_COUNT]{};
quint32 m_loop_end[STREAM_COUNT]{};
bool ensureValidStreamId(int streamId);
+
+ void on_url_download_finished(int id, QNetworkReply *reply, bool looping);
+ void start_playback(int id);
+ void stop(int id);
+
+signals:
+ void track_ready(QString label);
};