38 namespace discord_core_internal {
45 static constexpr uint32_t segmentId{ 0x18538067 };
46 static constexpr uint8_t simpleBlockId{ 0xA3 };
47 static constexpr uint8_t opusTrackId{ 0x81 };
49 static constexpr uint8_t ffLog2Tab[]{ 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
50 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
51 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
52 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
53 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 };
63 DCA_INLINE
void writeData(jsonifier::string_view_base<uint8_t> dataNew) {
72 frameNew = std::move(
frames.at(0));
85 jsonifier::string{
"Missing a Segment, which was expected at index: " + jsonifier::toString(
currentPosition) + jsonifier::string{
"..." } });
93 jsonifier::string{
"Missing Segment, found at index: " + jsonifier::toString(
currentPosition) +
"." });
100 while (
currentPosition + 3 <
data.size() &&
data.find(
static_cast<uint8_t
>(0xa3)) != jsonifier::string::npos) {
143 jsonifier::string_view_base<uint8_t>
data{};
155 template<
typename object_type> DCA_INLINE
bool findNextId(object_type value) {
174 return static_cast<object_type
>(-1);
176 object_type newValue{};
194 uint64_t read{}, n{ 1 };
198 read = 8ULL - ffLog2Tab[total];
200 total ^= 1ULL << ffLog2Tab[total];
204 return static_cast<int64_t
>(total);
209 audio_frame_data frameNew{};
210 frameNew.currentSize =
static_cast<int64_t
>(
currentSize - 4);
211 frameNew += jsonifier::string_view_base<uint8_t>{
data.data() +
currentPosition + 4,
static_cast<uint64_t
>(frameNew.currentSize) };
214 frames.emplace_back(std::move(frameNew));
219 using opus_packet = jsonifier::vector<uint8_t>;
226 DCA_INLINE
ogg_page(jsonifier::vector<uint8_t>&& newData) {
227 data = std::move(newData);
237 auto newSpace =
static_cast<uint64_t
>(
segmentTable.front());
239 newPacket.resize(newSpace);
253 uint64_t packetLength{
data.at(27ULL + x) };
254 while (
data.at(27ULL + x) == 255) {
256 packetLength +=
data.at(27ULL + x);
272 jsonifier::vector<uint8_t>
data{};
291 DCA_INLINE ogg_demuxer() =
default;
298 frameNew = std::move(
frames.front());
308 DCA_INLINE
void writeData(jsonifier::string_view inputData) {
311 data.resize(inputData.size());
312 std::memcpy(
data.data(), inputData.data(), inputData.size());
313 uint64_t collectedLength{};
314 while (pos < inputData.size()) {
315 uint64_t oggPos = inputData.find(
"OggS", pos);
316 if (oggPos != jsonifier::string::npos) {
317 uint64_t nextOggPos = inputData.find(
"OggS", oggPos + 1);
318 if (nextOggPos != jsonifier::string::npos) {
319 collectedLength += nextOggPos - oggPos;
320 jsonifier::vector<uint8_t> newerString{};
321 newerString.resize(nextOggPos - oggPos);
322 std::memcpy(newerString.data(),
data.data() + oggPos, nextOggPos - oggPos);
323 pages.emplace_back(std::move(newerString));
326 jsonifier::vector<uint8_t> newerString{};
327 newerString.resize(inputData.size() - collectedLength);
328 std::memcpy(newerString.data(),
data.data() + oggPos, inputData.size() - collectedLength);
329 pages.emplace_back(std::move(newerString));
330 pos = collectedLength;
334 jsonifier::vector<uint8_t> newerString{};
335 newerString.resize(inputData.size() - collectedLength);
336 std::memcpy(newerString.data(),
data.data() + oggPos, inputData.size() - collectedLength);
337 pages.emplace_back(std::move(newerString));
357 jsonifier::vector<uint8_t>
data{};
377 opus_packet newPacket =
packets.front();
379 audio_frame_data newFrame{};
380 newFrame += newPacket;
381 newFrame.currentSize =
static_cast<int64_t
>(newPacket.size());
383 frames.emplace_back(std::move(newFrame));
389 while (!
pages.empty()) {
390 ogg_page page =
pages.front();
392 opus_packet newPacket{};
394 packets.emplace_back(newPacket);
A class for demuxing Matroska-contained audio data.
DCA_INLINE int64_t collectNumber()
Collects a number from the data.
jsonifier::string_view_base< uint8_t > data
Input data for demuxing.
DCA_INLINE bool areWeDone()
Checks if the demuxing process is complete.
uint64_t currentSize
Current size of the element being processed.
DCA_INLINE bool findNextId(object_type value)
Finds the next occurrence of the specified value in the data.
DCA_INLINE object_type reverseBytes()
Reverses the byte order of the current element being processed.
DCA_INLINE bool collectFrame(audio_frame_data &frameNew)
Collects the next frame from the demuxer.
DCA_INLINE matroska_demuxer()=default
Constructor for matroska_demuxer.
bool doWeHaveTotalSize
Flag indicating if total size has been determined.
DCA_INLINE void writeData(jsonifier::string_view_base< uint8_t > dataNew)
Writes data to the Matroska demuxer.
DCA_INLINE void parseOpusFrame()
Parses an Opus frame.
DCA_INLINE int64_t collectElementSize()
Collects the size of the current element being processed.
uint64_t currentPosition
Current position in the data.
std::deque< audio_frame_data > frames
Queue to store collected frames.
DCA_INLINE void proceedDemuxing()
Proceed with the demuxing process.
int64_t totalSize
Total size of the segment.
bool areWeDoneVal
Flag indicating if demuxing is complete.
A class for demuxing Ogg-contained audio data.
DCA_INLINE void processPackets()
Processes Opus packets extracted from Ogg pages.
std::deque< ogg_page > pages
Queue to store Ogg pages.
DCA_INLINE bool collectFrame(audio_frame_data &frameNew)
Collects the next audio frame from the demuxer.
std::deque< opus_packet > packets
Queue to store Opus packets.
std::deque< audio_frame_data > frames
Queue to store collected audio frames.
jsonifier::vector< uint8_t > data
Input data for demuxing.
DCA_INLINE bool proceedDemuxing()
Proceeds with the demuxing process.
DCA_INLINE bool processOggPage()
Processes an Ogg page for demuxing.
DCA_INLINE void processPages()
Processes Ogg pages to extract Opus packets.
DCA_INLINE void writeData(jsonifier::string_view inputData)
Writes data to the Ogg demuxer and processes it.
A class representing an Ogg page for demuxing.
jsonifier::vector< uint8_t > data
The data for the Ogg page.
DCA_INLINE ogg_page(jsonifier::vector< uint8_t > &&newData)
Constructor for ogg_page.
DCA_INLINE void verifyAsOggPage()
Verifies that the data represents a valid Ogg page.
uint64_t totalPacketSize
Total size of Opus packets in the page.
std::deque< uint64_t > segmentTable
Segment table storing Opus packet sizes.
DCA_INLINE uint64_t getDataSize()
Returns the size of the Ogg page data.
DCA_INLINE bool getOpusPacket(opus_packet &newPacket)
Retrieves the next Opus packet from the Ogg page.
uint64_t segmentCount
Number of segments in the Ogg page.
uint64_t currentPosition
Current position in the page data.
DCA_INLINE void getSegmentData()
Parses the segment data of the Ogg page.
static DCA_INLINE void printSuccess(const string_type &what, std::source_location where=std::source_location::current())
Print a success message of the specified type.
static DCA_INLINE void printError(const string_type &what, std::source_location where=std::source_location::current())
Print an error message of the specified type.
DCA_INLINE void reverseByteOrder(return_type &net)
Reverses the byte order of a value if needed, based on the endianness.
@ encoded
Encoded audio data.
The main namespace for the forward-facing interfaces.