#pragma once #include // for atomic #include // for uint8_t, int64_t #include // for size_t, time #include // for function #include // for shared_ptr, unique_ptr #include // for mutex #include // for string_view #include // for vector #include "BellTask.h" // for Task #include "CDNTrackStream.h" // for CDNTrackStream, CDNTrackStream::TrackInfo namespace bell { class WrappedSemaphore; } // namespace bell #ifdef BELL_VORBIS_FLOAT #include "vorbis/vorbisfile.h" #else #include "ivorbisfile.h" // for OggVorbis_File, ov_callbacks #endif namespace cspot { class TrackProvider; struct Context; struct TrackReference; class TrackPlayer : bell::Task { public: typedef std::function TrackLoadedCallback; typedef std::function DataCallback; typedef std::function EOFCallback; typedef std::function isAiringCallback; TrackPlayer(std::shared_ptr ctx, isAiringCallback, EOFCallback, TrackLoadedCallback); ~TrackPlayer(); void loadTrackFromRef(TrackReference& ref, size_t playbackMs, bool startAutomatically); void setDataCallback(DataCallback callback); CDNTrackStream::TrackInfo getCurrentTrackInfo(); void seekMs(size_t ms); void stopTrack(); // Vorbis codec callbacks size_t _vorbisRead(void* ptr, size_t size, size_t nmemb); size_t _vorbisClose(); int _vorbisSeek(int64_t offset, int whence); long _vorbisTell(); void destroy(); private: std::shared_ptr ctx; std::shared_ptr trackProvider; std::shared_ptr currentTrackStream; size_t sequence = std::time(nullptr); std::unique_ptr playbackSemaphore; TrackLoadedCallback trackLoaded; DataCallback dataCallback = nullptr; EOFCallback eofCallback; isAiringCallback isAiring; // Playback control std::atomic currentSongPlaying; std::mutex playbackMutex; std::mutex seekMutex; // Vorbis related OggVorbis_File vorbisFile; ov_callbacks vorbisCallbacks; int currentSection; std::vector pcmBuffer = std::vector(1024); size_t playbackPosition = 0; bool autoStart = false; std::atomic isRunning = true; std::mutex runningMutex; void runTask() override; }; } // namespace cspot