37namespace DiscordCoreAPI {
39 namespace DiscordCoreInternal {
46 static constexpr uint32_t segmentId{ 0x18538067 };
47 static constexpr uint8_t simpleBlockId{ 0xA3 };
48 static constexpr uint8_t opusTrackId{ 0x81 };
50 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,
51 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,
52 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,
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, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
54 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 };
64 inline void writeData(std::basic_string_view<uint8_t> dataNew) {
73 frameNew = std::move(
frames.at(0));
84 if (reverseBytes<uint32_t>() != segmentId) {
85 MessagePrinter::printError<PrintMessageType::General>(
86 "Missing a Segment, which was expected at index: " + std::to_string(
currentPosition) + std::string{
"..." });
93 MessagePrinter::printSuccess<PrintMessageType::General>(
"Missing Segment, found at index: " + std::to_string(
currentPosition) +
".");
143 std::basic_string_view<uint8_t>
data{};
155 template<
typename ObjectType>
inline bool findNextId(ObjectType value) {
160 if (reverseBytes<ObjectType>() == value) {
174 return static_cast<ObjectType
>(-1);
176 ObjectType newValue{};
194 int32_t read{}, n{ 1 };
198 read = 8 - ffLog2Tab[total];
200 total ^= 1ull << ffLog2Tab[total];
204 return static_cast<int64_t
>(total);
211 frameNew += std::basic_string_view<uint8_t>{
data.data() +
currentPosition + 4,
static_cast<uint64_t
>(frameNew.currentSize) };
214 frames.emplace_back(std::move(frameNew));
251 inline OggPage(jsonifier::vector<uint8_t>& newData) {
252 data = std::move(newData);
262 auto newSpace =
static_cast<uint64_t
>(
segmentTable.front());
264 jsonifier::vector<uint8_t> returnValue{};
265 returnValue.resize(newSpace);
268 newPacket = returnValue;
280 int32_t packetLength{
data.at(27ull + x) };
281 while (
data.at(27ull + x) == 255) {
283 packetLength +=
data.at(27ull + x);
299 jsonifier::vector<uint8_t>
data{};
325 frameNew = std::move(
frames.front());
338 data.resize(inputData.size());
339 std::memcpy(
data.data(), inputData.data(), inputData.size());
340 uint64_t collectedLength{};
341 while (pos < inputData.size()) {
342 uint64_t oggPos = inputData.find(
"OggS", pos);
343 if (oggPos != std::string::npos) {
344 uint64_t nextOggPos = inputData.find(
"OggS", oggPos + 1);
345 if (nextOggPos != std::string::npos) {
346 collectedLength += nextOggPos - oggPos;
347 jsonifier::vector<uint8_t> newerString{};
348 newerString.resize(nextOggPos - oggPos);
349 std::memcpy(newerString.data(),
data.data() + oggPos, nextOggPos - oggPos);
350 pages.emplace_back(newerString);
353 jsonifier::vector<uint8_t> newerString{};
354 newerString.resize(inputData.size() - collectedLength);
355 std::memcpy(newerString.data(),
data.data() + oggPos, inputData.size() - collectedLength);
356 pages.emplace_back(newerString);
357 pos = collectedLength;
361 jsonifier::vector<uint8_t> newerString{};
362 newerString.resize(inputData.size() - collectedLength);
363 std::memcpy(newerString.data(),
data.data() + oggPos, inputData.size() - collectedLength);
364 pages.emplace_back(newerString);
383 jsonifier::string_base<uint8_t>
data{};
407 newFrame += std::basic_string_view<uint8_t>{ newPacket.
data(), newPacket.
size() };
408 newFrame.currentSize =
static_cast<int64_t
>(newPacket.
size());
410 frames.emplace_back(std::move(newFrame));
416 while (!
pages.empty()) {
421 packets.emplace_back(newPacket);
@ Encoded
Encoded audio data.
ReturnType reverseByteOrder(ReturnType net)
Reverses the byte order of a value if needed, based on the endianness.
A class for demuxing Matroska-contained audio data.
bool doWeHaveTotalSize
Flag indicating if total size has been determined.
void writeData(std::basic_string_view< uint8_t > dataNew)
Writes data to the Matroska demuxer.
void proceedDemuxing()
Proceed with the demuxing process.
int64_t totalSize
Total size of the segment.
void parseOpusFrame()
Parses an Opus frame.
MatroskaDemuxer()=default
Constructor for MatroskaDemuxer.
uint64_t currentSize
Current size of the element being processed.
bool areWeDoneVal
Flag indicating if demuxing is complete.
int64_t collectElementSize()
Collects the size of the current element being processed.
ObjectType reverseBytes()
Reverses the byte order of the current element being processed.
int64_t collectNumber()
Collects a number from the data.
bool findNextId(ObjectType value)
Finds the next occurrence of the specified value in the data.
std::basic_string_view< uint8_t > data
Input data for demuxing.
bool areWeDone()
Checks if the demuxing process is complete.
bool collectFrame(AudioFrameData &frameNew)
Collects the next frame from the demuxer.
std::deque< AudioFrameData > frames
Queue to store collected frames.
uint64_t currentPosition
Current position in the data.
A class representing an Opus packet.
uint64_t size()
Returns the size of the Opus packet data.
jsonifier::vector< uint8_t > dataVal
The data for the Opus packet.
auto data()
Returns a pointer to the Opus packet data.
OpusPacket(jsonifier::vector< uint8_t > newData)
Constructor for OpusPacket.
A class representing an Ogg page for demuxing.
bool getOpusPacket(OpusPacket &newPacket)
Retrieves the next Opus packet from the Ogg page.
void verifyAsOggPage()
Verifies that the data represents a valid Ogg page.
void getSegmentData()
Parses the segment data of the Ogg page.
uint64_t getDataSize()
Returns the size of the Ogg page data.
int32_t segmentCount
Number of segments in the Ogg page.
uint64_t currentPosition
Current position in the page data.
OggPage(jsonifier::vector< uint8_t > &newData)
Constructor for OggPage.
std::deque< int32_t > segmentTable
Segment table storing Opus packet sizes.
jsonifier::vector< uint8_t > data
The data for the Ogg page.
uint64_t totalPacketSize
Total size of Opus packets in the page.
A class for demuxing Ogg-contained audio data.
void processPackets()
Processes Opus packets extracted from Ogg pages.
std::deque< AudioFrameData > frames
Queue to store collected audio frames.
jsonifier::string_base< uint8_t > data
Input data for demuxing.
bool proceedDemuxing()
Proceeds with the demuxing process.
bool collectFrame(AudioFrameData &frameNew)
Collects the next audio frame from the demuxer.
bool processOggPage()
Processes an Ogg page for demuxing.
void processPages()
Processes Ogg pages to extract Opus packets.
std::deque< OggPage > pages
Queue to store Ogg pages.
std::deque< OpusPacket > packets
Queue to store Opus packets.
void writeData(std::string_view inputData)
Writes data to the Ogg demuxer and processes it.
Represents a single frame of audio data.
int64_t currentSize
The current size of the allocated memory.