DiscordCoreAPI
A Discord bot library written in C++, with custom asynchronous coroutines.
Loading...
Searching...
No Matches
AudioDecoder.hpp
Go to the documentation of this file.
1/*
2 DiscordCoreAPI, A bot library for Discord, written in C++, and featuring explicit multithreading through the usage of custom, asynchronous C++ CoRoutines.
3
4 Copyright 2021, 2022 Chris M. (RealTimeChris)
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
19 USA
20*/
21/// AudioDecoder.hpp - Header for the audio decoder class.
22/// Jul 29, 2021
23/// https://discordcoreapi.com
24/// \file AudioDecoder.hpp
25
26#pragma once
27
29#include <opus/opus.h>
30
31extern "C" {
32#include <libavformat/avformat.h>
33#include <libswresample/swresample.h>
34}
35
36namespace DiscordCoreInternal {
37
38 struct DiscordCoreAPI_Dll OpusDecoderWrapper {
39 struct DiscordCoreAPI_Dll OpusDecoderDeleter {
40 void operator()(OpusDecoder*) noexcept;
41 };
42
43 OpusDecoderWrapper();
44
45 std::basic_string_view<opus_int16> decodeData(std::basic_string_view<std::byte> dataToDecode);
46
47 protected:
48 std::unique_ptr<OpusDecoder, OpusDecoderDeleter> ptr{ nullptr, OpusDecoderDeleter{} };
49 std::vector<opus_int16> data{};
50 };
51
52 struct DiscordCoreAPI_Dll AVFrameWrapper {
53 struct DiscordCoreAPI_Dll AVFrameDeleter {
54 void operator()(AVFrame* other);
55 };
56
57 AVFrameWrapper& operator=(AVFrame* other);
58
59 AVFrameWrapper(AVFrame* other);
60
61 AVFrame* operator->();
62
63 operator AVFrame*();
64
65 AVFrameWrapper() noexcept = default;
66
67 protected:
68 std::unique_ptr<AVFrame, AVFrameDeleter> ptr{ nullptr, AVFrameDeleter{} };
69 };
70
71 struct DiscordCoreAPI_Dll AVCodecContextWrapper {
72 struct DiscordCoreAPI_Dll AVCodecContextDeleter {
73 void operator()(AVCodecContext* other);
74 };
75
76 AVCodecContextWrapper& operator=(AVCodecContext* other);
77
78 AVCodecContextWrapper(AVCodecContext* other);
79
80 AVCodecContext* operator->();
81
82 operator AVCodecContext*();
83
84 AVCodecContextWrapper() noexcept = default;
85
86 protected:
87 std::unique_ptr<AVCodecContext, AVCodecContextDeleter> ptr{ nullptr, AVCodecContextDeleter{} };
88 };
89
90 struct DiscordCoreAPI_Dll AVFormatContextWrapper01 {
91 AVFormatContextWrapper01() noexcept = default;
92
93 AVFormatContext* theContext{ nullptr };
94 bool didItInitialize{};
95 };
96
97 struct DiscordCoreAPI_Dll AVFormatContextWrapper {
98 struct DiscordCoreAPI_Dll AVFormatContextDeleter {
99 void operator()(AVFormatContextWrapper01* other);
100 };
101
102 AVFormatContextWrapper& operator=(AVFormatContext* other);
103
104 AVFormatContextWrapper(AVFormatContext* other);
105
106 bool* getBoolPtr();
107
108 AVFormatContext* operator->();
109
110 AVFormatContext** operator*();
111
112 operator AVFormatContext*();
113
114 AVFormatContextWrapper() noexcept = default;
115
116 protected:
117 std::unique_ptr<AVFormatContextWrapper01, AVFormatContextDeleter> ptr{ std::make_unique<AVFormatContextWrapper01>().release(),
118 AVFormatContextDeleter{} };
119 };
120
121 struct DiscordCoreAPI_Dll SwrContextWrapper {
122 struct DiscordCoreAPI_Dll SwrContextDeleter {
123 void operator()(SwrContext* other);
124 };
125
126 SwrContextWrapper& operator=(SwrContext* other);
127
128 SwrContextWrapper(SwrContext* other);
129
130 operator SwrContext*();
131
132 SwrContextWrapper() noexcept = default;
133
134 protected:
135 std::unique_ptr<SwrContext, SwrContextDeleter> ptr{ nullptr, SwrContextDeleter{} };
136 };
137
138 struct DiscordCoreAPI_Dll AVIOContextWrapper {
139 struct DiscordCoreAPI_Dll AVIOContextDeleter {
140 void operator()(AVIOContext* other);
141 };
142
143 AVIOContextWrapper& operator=(AVIOContext* other);
144
145 AVIOContextWrapper(AVIOContext* other);
146
147 AVIOContext* operator->();
148
149 operator AVIOContext*();
150
151 AVIOContextWrapper() noexcept = default;
152
153 protected:
154 std::unique_ptr<AVIOContext, AVIOContextDeleter> ptr{ nullptr, AVIOContextDeleter{} };
155 };
156
157 struct DiscordCoreAPI_Dll AVPacketWrapper {
158 struct DiscordCoreAPI_Dll AVPacketDeleter {
159 void operator()(AVPacket* other);
160 };
161
162 AVPacketWrapper& operator=(AVPacket* other);
163
164 AVPacketWrapper(AVPacket* other);
165
166 AVPacket* operator->();
167
168 operator AVPacket*();
169
170 AVPacketWrapper() noexcept = default;
171
172 protected:
173 std::unique_ptr<AVPacket, AVPacketDeleter> ptr{ nullptr, AVPacketDeleter{} };
174 };
175
176 struct DiscordCoreAPI_Dll BuildAudioDecoderData {
177 public:
178 DiscordCoreAPI::ConfigManager* configManager{ nullptr };
179 int64_t totalFileSize{};
180 int64_t bufferMaxSize{};
181 };
182
183 class DiscordCoreAPI_Dll AudioDecoder {
184 public:
185 AudioDecoder(const BuildAudioDecoderData& dataPackage);
186
187 bool getFrame(DiscordCoreAPI::AudioFrameData& dataPackage);
188
189 void submitDataForDecoding(std::string dataToDecode);
190
191 bool haveWeFailed();
192
193 void startMe();
194
195 ~AudioDecoder();
196
197 protected:
199 int64_t audioStreamIndex{}, bufferMaxSize{}, bytesRead{}, totalFileSize{};
201 DiscordCoreAPI::ConfigManager* configManager{ nullptr };
202 std::atomic_int32_t refreshTimeForBuffer{ 10000 };
203 AVCodecContextWrapper audioDecodeContext{};
204 AVFormatContextWrapper formatContext{};
205 std::atomic_bool haveWeFailedBool{};
206 AVFrameWrapper frame{}, newFrame{};
207 std::atomic_bool areWeQuitting{};
208 AVIOContextWrapper ioContext{};
209 SwrContextWrapper swrContext{};
210 std::string currentBuffer{};
211 AVPacketWrapper packet{};
212 AVStream* audioStream{};
213 bool haveWeBooted{};
214 AVCodec* codec{};
215 std::unique_ptr<std::jthread> taskThread{ nullptr };
216
217 static int32_t ReadBufferData(void* opaque, uint8_t* buf, int32_t);
218
219 void run(std::stop_token token);
220
221 void cancelMe();
222 };
223
224}// namespace DiscordCoreAPI
Represents a single frame of audio data.
Definition: Utilities.hpp:832
A thread-safe messaging block for data-structures.
Definition: Utilities.hpp:1194