diff options
Diffstat (limited to 'src/aomusicplayer.h')
| -rw-r--r-- | src/aomusicplayer.h | 47 |
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); }; |
