lsnes rr2-β24
[lsnes.git] / src / emulation / sky / music.hpp
blobf46fed50f013f176f1c84a8f3a284c70d77357cc
1 #ifndef _skycore__music__hpp__included__
2 #define _skycore__music__hpp__included__
4 #include <stdexcept>
5 #include <cstdint>
6 #include <vector>
7 #include <map>
8 #include <set>
9 #include "random.hpp"
10 #include "library/ogg.hpp"
11 #include "library/opus.hpp"
13 namespace sky
15 struct song_buffer;
16 extern const uint64_t past_end; //Position past the end of song.
18 struct multistream_characteristics
20 multistream_characteristics();
21 uint8_t channels;
22 uint8_t streams;
23 uint8_t coupled;
24 uint8_t mapping[255];
25 float downmix_l[255];
26 float downmix_r[255];
27 int16_t gain;
30 struct subsong_transition
32 subsong_transition();
33 void fixup(uint64_t pregap, uint64_t datalen, const std::string& ssname);
34 //Starting PTS.
35 uint64_t start_pts;
36 //Crossfade start PTS.
37 uint64_t xfade_pts;
38 //Ending pts.
39 uint64_t end_pts;
40 //Set of next subsongs.
41 std::set<uint32_t> next_subsongs;
44 struct song_buffer
46 //Load song from stream.
47 song_buffer(std::istream& stream);
48 //Access a packet.
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);
60 private:
61 struct subsong_context
63 //Create a new subsong context.
64 //Note: Does not initialize psid.
65 subsong_context();
66 //Demuxer.
67 ogg::demuxer demux;
68 //Stream ID.
69 uint32_t psid;
70 //Ogg Stream ID.
71 uint32_t oggid;
72 //Last granule position recorded.
73 uint64_t last_granule;
74 //PTS at last granule position recorded.
75 uint64_t last_pts;
76 //Current PTS.
77 uint64_t pts;
78 //Number of pages seen.
79 uint64_t pages;
80 //Pregap.
81 uint32_t pregap;
82 //Gain
83 uint16_t gain;
84 //Seen EOS flag.
85 bool eos_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);
92 //Register a LSID.
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.
102 uint32_t next_lsid;
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;
111 //Dummy data.
112 subsong_transition dummy_transition;
113 std::vector<uint8_t> dummy_packet;
116 struct packet_decoder
118 //Create a new packet decoder.
119 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.
125 void reset();
126 uint16_t pcmpos;
127 uint16_t pcmlen;
128 int16_t pcmbuf[11522];
129 private:
130 opus::multistream_decoder* d;
131 uint8_t channels;
132 float downmix_l[255];
133 float downmix_r[255];
134 std::vector<uint8_t> memory;
135 float* dmem;
138 struct music_player_memory
140 uint64_t pcmpos1;
141 uint64_t pcmpos2;
142 uint32_t subsong1;
143 uint32_t subsong2;
146 struct music_player
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(); }
151 void do_preroll();
152 void decode(std::pair<int16_t, int16_t>* output, size_t samples);
153 private:
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;
157 packet_decoder i1;
158 packet_decoder i2;
159 song_buffer* song;
160 random& rng;
164 #endif