From b7720cc7f3dca118ff3e3f9de6ddcb0fc0293b23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20S=C5=82omkowski?= Date: Fri, 15 Apr 2016 03:13:56 +0200 Subject: [PATCH] Add support for changing Opus encoder bitrate. #11 --- include/mumlib.hpp | 11 +++++++++++ include/mumlib/Audio.hpp | 6 +++++- mumlib_example.cpp | 4 +++- src/Audio.cpp | 23 ++++++++++++++++++++++- src/mumlib.cpp | 28 ++++++++++++++++++++-------- 5 files changed, 61 insertions(+), 11 deletions(-) diff --git a/include/mumlib.hpp b/include/mumlib.hpp index 5df4f50..95afe02 100644 --- a/include/mumlib.hpp +++ b/include/mumlib.hpp @@ -10,6 +10,8 @@ namespace mumlib { + constexpr int DEFAULT_OPUS_ENCODER_BITRATE = 16000; + using namespace std; using namespace boost::asio; @@ -18,6 +20,11 @@ namespace mumlib { MumlibException(string message) : runtime_error(message) { } }; + struct MumlibConfiguration { + int opusEncoderBitrate = DEFAULT_OPUS_ENCODER_BITRATE; + // additional fields will be added in the future + }; + struct _Mumlib_Private; @@ -27,6 +34,10 @@ namespace mumlib { Mumlib(Callback &callback, io_service &ioService); + Mumlib(Callback &callback, MumlibConfiguration &configuration); + + Mumlib(Callback &callback, io_service &ioService, MumlibConfiguration &configuration); + virtual ~Mumlib(); void connect(string host, int port, string user, string password); diff --git a/include/mumlib/Audio.hpp b/include/mumlib/Audio.hpp index b00120c..d98f41a 100644 --- a/include/mumlib/Audio.hpp +++ b/include/mumlib/Audio.hpp @@ -28,7 +28,7 @@ namespace mumlib { class Audio : boost::noncopyable { public: - Audio(); + Audio(int opusEncoderBitrate = DEFAULT_OPUS_ENCODER_BITRATE); virtual ~Audio(); @@ -46,6 +46,10 @@ namespace mumlib { uint8_t *outputBuffer, int outputBufferSize = MAX_UDP_LENGTH); + void setOpusEncoderBitrate(int bitrate); + + int getOpusEncoderBitrate(); + void resetEncoder(); private: diff --git a/mumlib_example.cpp b/mumlib_example.cpp index b36383d..2e874d6 100644 --- a/mumlib_example.cpp +++ b/mumlib_example.cpp @@ -48,7 +48,9 @@ int main(int argc, char *argv[]) { while (true) { try { - mumlib::Mumlib mum(myCallback); + mumlib::MumlibConfiguration conf; + conf.opusEncoderBitrate = 32000; + mumlib::Mumlib mum(myCallback, conf); myCallback.mum = &mum; mum.connect(argv[1], 64738, "mumlib_example", argv[2]); mum.run(); diff --git a/src/Audio.cpp b/src/Audio.cpp index b117a4f..3ce7594 100644 --- a/src/Audio.cpp +++ b/src/Audio.cpp @@ -4,7 +4,7 @@ static boost::posix_time::seconds RESET_SEQUENCE_NUMBER_INTERVAL(5); -mumlib::Audio::Audio() +mumlib::Audio::Audio(int opusEncoderBitrate) : logger(log4cpp::Category::getInstance("mumlib.Audio")), opusDecoder(nullptr), opusEncoder(nullptr), @@ -24,6 +24,8 @@ mumlib::Audio::Audio() opus_encoder_ctl(opusEncoder, OPUS_SET_VBR(0)); + setOpusEncoderBitrate(opusEncoderBitrate); + resetEncoder(); } @@ -37,6 +39,23 @@ mumlib::Audio::~Audio() { } } +void mumlib::Audio::setOpusEncoderBitrate(int bitrate) { + int error = opus_encoder_ctl(opusEncoder, OPUS_SET_BITRATE(bitrate)); + if (error != OPUS_OK) { + throw AudioException((boost::format("failed to initialize transmission bitrate to %d B/s: %s") + % bitrate % opus_strerror(error)).str()); + } +} + +int mumlib::Audio::getOpusEncoderBitrate() { + opus_int32 bitrate; + int error = opus_encoder_ctl(opusEncoder, OPUS_GET_BITRATE(&bitrate)); + if (error != OPUS_OK) { + throw AudioException((boost::format("failed to read Opus bitrate: %s") % opus_strerror(error)).str()); + } + return bitrate; +} + std::pair mumlib::Audio::decodeOpusPayload(uint8_t *inputBuffer, int inputLength, int16_t *pcmBuffer, @@ -166,3 +185,5 @@ mumlib::IncomingAudioPacket mumlib::Audio::decodeIncomingAudioPacket(uint8_t *in return incomingAudioPacket; } + + diff --git a/src/mumlib.cpp b/src/mumlib.cpp index a5dbb3a..08197d1 100644 --- a/src/mumlib.cpp +++ b/src/mumlib.cpp @@ -33,17 +33,20 @@ namespace mumlib { int sessionId = 0; int channelId = 0; - _Mumlib_Private(Callback &callback) - : _Mumlib_Private(callback, *(new io_service())) { + _Mumlib_Private(Callback &callback, MumlibConfiguration &configuration) + : _Mumlib_Private(callback, *(new io_service()), configuration) { externalIoService = false; } - _Mumlib_Private(Callback &callback, io_service &ioService) + _Mumlib_Private(Callback &callback, io_service &ioService, MumlibConfiguration &configuration) : callback(callback), ioService(ioService), externalIoService(true), transport(ioService, boost::bind(&_Mumlib_Private::processIncomingTcpMessage, this, _1, _2, _3), - boost::bind(&_Mumlib_Private::processAudioPacket, this, _1, _2, _3)) { } + boost::bind(&_Mumlib_Private::processAudioPacket, this, _1, _2, _3)) { + + audio.setOpusEncoderBitrate(configuration.opusEncoderBitrate); + } virtual ~_Mumlib_Private() { if (not externalIoService) { @@ -334,12 +337,21 @@ namespace mumlib { }; - Mumlib::Mumlib(Callback &callback) - : impl(new _Mumlib_Private(callback)) { + Mumlib::Mumlib(Callback &callback) { + MumlibConfiguration conf; + impl = new _Mumlib_Private(callback, conf); } - Mumlib::Mumlib(Callback &callback, io_service &ioService) - : impl(new _Mumlib_Private(callback, ioService)) { } + Mumlib::Mumlib(Callback &callback, io_service &ioService) { + MumlibConfiguration conf; + impl = new _Mumlib_Private(callback, ioService, conf); + } + + Mumlib::Mumlib(Callback &callback, MumlibConfiguration &configuration) + : impl(new _Mumlib_Private(callback, configuration)) { } + + Mumlib::Mumlib(Callback &callback, io_service &ioService, MumlibConfiguration &configuration) + : impl(new _Mumlib_Private(callback, ioService, configuration)) { } Mumlib::~Mumlib() { disconnect();