1 #ifndef _skycore__music__hpp__included__
2 #define _skycore__music__hpp__included__
10 #include "library/ogg.hpp"
11 #include "library/opus.hpp"
16 extern const uint64_t past_end
; //Position past the end of song.
18 struct multistream_characteristics
20 multistream_characteristics();
30 struct subsong_transition
33 void fixup(uint64_t pregap
, uint64_t datalen
, const std::string
& ssname
);
36 //Crossfade start PTS.
40 //Set of next subsongs.
41 std::set
<uint32_t> next_subsongs
;
46 //Load song from stream.
47 song_buffer(std::istream
& stream
);
49 const std::vector
<uint8_t>& get_packet(uint32_t subsong
, uint64_t pts
);
50 //Get packet pts at or after given pts.
51 uint64_t next_timecode(uint32_t subsong
, uint64_t pts
);
52 //Get packet pts at or before given pts.
53 uint64_t prev_timecode(uint32_t subsong
, uint64_t pts
);
54 //Fill structure with multistream characteristics of a subsong.
55 void fill_ms_characteristics(uint32_t subsong
, struct multistream_characteristics
& c
);
56 //Get set of subsongs with entry flag set.
57 const std::set
<uint32_t>& entrypoints() { return entry
; }
58 //Get transition info for a subsong.
59 const struct subsong_transition
& transitions(uint32_t subsong
);
61 struct subsong_context
63 //Create a new subsong context.
64 //Note: Does not initialize psid.
72 //Last granule position recorded.
73 uint64_t last_granule
;
74 //PTS at last granule position recorded.
78 //Number of pages seen.
87 bool page_starts_new_stream(ogg::page
& p
);
88 bool parse_ogg_page(ogg::page
& p
, subsong_context
& ctx
);
89 void parse_ogg_header(ogg::packet
& p
, subsong_context
& ctx
);
90 void parse_ogg_tags(ogg::packet
& p
, subsong_context
& ctx
, const ogg::page
& debug
);
91 void parse_ogg_data(ogg::packet
& p
, subsong_context
& ctx
, const ogg::page
& debug
);
93 uint32_t register_lsid(const std::string
& ssid
);
94 uint32_t register_lsid(const std::string
& ssid
, uint32_t psid
);
95 void delete_stream(uint32_t psid
);
96 void delete_undefined_substreams();
97 std::string
reverse_lsid(uint32_t lsid
);
98 //Mappings between ssid, lsid and psid.
99 std::map
<std::string
, uint32_t> ssid_to_lsid
;
100 std::map
<uint32_t, uint32_t> lsid_to_psid
;
101 //Next LSID to allocate.
103 //LSIDs valid for entry.
104 std::set
<uint32_t> entry
;
105 //Multistream characteristics by PSID.
106 std::map
<uint32_t, multistream_characteristics
> mscharacteristics
;
107 //Subsong transitions by LSID.
108 std::map
<uint32_t, subsong_transition
> stransitions
;
109 //Packet data, indexed by (PSID,PTS).
110 std::map
<std::pair
<uint32_t, uint64_t>, std::vector
<uint8_t>> packetdata
;
112 subsong_transition dummy_transition
;
113 std::vector
<uint8_t> dummy_packet
;
116 struct packet_decoder
118 //Create a new packet decoder.
120 //Set multistream characteristics of packet decoder.
121 void set_multistream(const struct multistream_characteristics
& c
);
122 //Decode a packet, setting buffers.
123 void decode_packet(const std::vector
<uint8_t>& data
);
124 //Reset the opus codec.
128 int16_t pcmbuf
[11522];
130 opus::multistream_decoder
* d
;
132 float downmix_l
[255];
133 float downmix_r
[255];
134 std::vector
<uint8_t> memory
;
138 struct music_player_memory
148 music_player(struct music_player_memory
& m
, random
& _rng
);
149 void set_song(song_buffer
* _song
) { song
= _song
; do_preroll(); }
150 void rewind() { song_to_beginning(); do_preroll(); }
152 void decode(std::pair
<int16_t, int16_t>* output
, size_t samples
);
154 void song_to_beginning();
155 void seek_channel(packet_decoder
& i
, uint64_t& spts
, uint32_t subsong
, uint64_t pts
);
156 music_player_memory
& mem
;