#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 "CDNAudioFile.h" #include "TrackQueue.h" 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; class TrackQueue; struct Context; struct TrackReference; class TrackPlayer : bell::Task { public: // Callback types typedef std::function)> TrackLoadedCallback; typedef std::function DataCallback; typedef std::function EOFCallback; typedef std::function isAiringCallback; TrackPlayer(std::shared_ptr ctx, std::shared_ptr trackQueue, EOFCallback eofCallback, TrackLoadedCallback loadedCallback); ~TrackPlayer(); void loadTrackFromRef(TrackReference& ref, size_t playbackMs, bool startAutomatically); void setDataCallback(DataCallback callback); // CDNTrackStream::TrackInfo getCurrentTrackInfo(); void seekMs(size_t ms); void resetState(); // 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 stop(); void start(); private: std::shared_ptr ctx; std::shared_ptr trackQueue; std::shared_ptr currentTrackStream; std::unique_ptr playbackSemaphore; TrackLoadedCallback trackLoaded; DataCallback dataCallback = nullptr; EOFCallback eofCallback; // Playback control std::atomic currentSongPlaying; std::mutex playbackMutex; std::mutex dataOutMutex; // Vorbis related OggVorbis_File vorbisFile; ov_callbacks vorbisCallbacks; int currentSection; std::vector pcmBuffer = std::vector(1024); bool autoStart = false; std::atomic isRunning = false; std::atomic pendingReset = false; std::atomic inFuture = false; std::atomic pendingSeekPositionMs = 0; std::mutex runningMutex; void runTask() override; }; } // namespace cspot