29namespace DiscordCoreInternal {
31 void OpusEncoderWrapper::OpusEncoderDeleter::operator()(OpusEncoder* other)
noexcept {
33 opus_encoder_destroy(other);
38 OpusEncoderWrapper::OpusEncoderWrapper() {
40 this->ptr.reset(opus_encoder_create(this->sampleRate, this->nChannels, OPUS_APPLICATION_AUDIO, &error));
41 auto result = opus_encoder_ctl(this->ptr.get(), OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC));
42 if (result != OPUS_OK) {
43 throw DiscordCoreAPI::DCAException{
"Failed to set the Opus signal type, Reason: " + std::string{ opus_strerror(result) } };
45 result = opus_encoder_ctl(this->ptr.get(), OPUS_SET_BITRATE(OPUS_BITRATE_MAX));
46 if (result != OPUS_OK) {
47 throw DiscordCoreAPI::DCAException{
"Failed to set the Opus bitrate, Reason: " + std::string{ opus_strerror(result) } };
51 EncoderReturnData OpusEncoderWrapper::encodeData(std::basic_string_view<std::byte> inputFrame) {
52 if (inputFrame.size() == 0) {
55 if (this->encodedData.size() == 0) {
56 this->encodedData.resize(this->maxBufferSize);
58 size_t sampleCount = inputFrame.size() / 2 / 2;
59 int32_t count = opus_encode(this->ptr.get(),
reinterpret_cast<const opus_int16*
>(inputFrame.data()),
60 static_cast<int32_t
>(inputFrame.size() / 2 / 2),
reinterpret_cast<uint8_t*
>(this->encodedData.data()), this->maxBufferSize);
64 EncoderReturnData returnData{};
65 returnData.sampleCount = sampleCount;
66 returnData.data = std::basic_string_view<std::byte>{ this->encodedData.data(), this->encodedData.size() };