#ifndef STAR_SONGBOOK_HPP #define STAR_SONGBOOK_HPP #include "StarThread.hpp" #include "StarJson.hpp" #include "StarNetElementSystem.hpp" #include "StarGameTypes.hpp" namespace Star { STAR_CLASS(Audio); STAR_CLASS(AudioInstance); STAR_CLASS(World); STAR_CLASS(Songbook); STAR_CLASS(RenderCallback); class Songbook : public NetElementSyncGroup { public: Songbook(String const& species); ~Songbook(); void update(EntityMode mode, World* world); void render(RenderCallback* renderCallback); // instrument needs to tell the songbook what type it is, and needs to keep // calling it to signal // the instrument is still equiped void keepalive(String const& instrument, Vec2F const& position); void stop(); void play(Json const& song, String const& timesource); bool active(); bool instrumentPlaying(); private: struct Note { String instrument; String file; double timecode; double duration; double fadeout; double velocity; }; struct HeldNote { AudioInstancePtr audio; double start; double end; }; struct NoteMapping { List files; double frequency; double velocity; double fadeout; }; struct TimeSource { int64_t keepalive; int64_t epoch; }; static double fundamentalFrequency(double p); static double fundamentalPitch(double p); void netElementsNeedLoad(bool full) override; void netElementsNeedStore() override; static StringMap> s_timeSources; static Mutex s_timeSourcesMutex; String m_species; Vec2F m_position; bool m_serverMode; int64_t m_globalNowDelta; int m_activeCooldown; bool m_dataUpdated; bool m_dataChanged; String m_timeSource; int64_t m_timeSourceEpoch; String m_instrument; Json m_song; bool m_stopped; Deque m_track; List m_heldNotes; shared_ptr m_timeSourceInstance; List m_pendingAudio; List parseABC(String const& abc); StringMap> m_noteMapping; NoteMapping& noteMapping(String const& instrument, String const& species, int note); StringMap m_uncompressedSamples; void playback(); NetElementData m_songNetState; NetElementInt m_timeSourceEpochNetState; NetElementString m_timeSourceNetState; NetElementBool m_activeNetState; NetElementString m_instrumentNetState; }; } #endif