Browse Source

Add option to set frame length in PJSIP. #14

Michał Słomkowski 8 years ago
parent
commit
c04ead2ff5
5 changed files with 33 additions and 12 deletions
  1. 3 3
      Configuration.cpp
  2. 17 7
      PjsuaCommunicator.cpp
  3. 5 1
      PjsuaCommunicator.hpp
  4. 7 0
      config.ini.example
  5. 1 1
      main.cpp

+ 3 - 3
Configuration.cpp

@@ -2,8 +2,7 @@
 
 #include <boost/property_tree/ptree.hpp>
 #include <boost/property_tree/ini_parser.hpp>
-
-#include <fstream>
+#include <boost/format.hpp>
 
 using namespace config;
 
@@ -17,7 +16,8 @@ namespace config {
         try {
             return tree.get<TYPE>(property);
         } catch (boost::property_tree::ptree_bad_path) {
-            throw ConfigException(std::string(typeid(TYPE).name()) + " key \'" + property + "\' not found");
+            throw ConfigException((boost::format("Configuration option '%s' (type: %s) not found.")
+                                   % property % typeid(TYPE).name()).str());
         }
     }
 }

+ 17 - 7
PjsuaCommunicator.cpp

@@ -38,9 +38,9 @@ namespace sip {
 
     class _MumlibAudioMedia : public pj::AudioMedia {
     public:
-        _MumlibAudioMedia(sip::PjsuaCommunicator &comm)
+        _MumlibAudioMedia(sip::PjsuaCommunicator &comm, int frameTimeLength)
                 : communicator(comm) {
-            createMediaPort();
+            createMediaPort(frameTimeLength);
             registerMediaPort(&mediaPort);
         }
 
@@ -62,18 +62,26 @@ namespace sip {
             return communicator->mediaPortPutFrame(port, frame);
         }
 
-        void createMediaPort() {
+        void createMediaPort(int frameTimeLength) {
 
             auto name = pj_str((char *) "MumsiMediaPort");
 
+            if (frameTimeLength != 10
+                and frameTimeLength != 20
+                and frameTimeLength != 40
+                and frameTimeLength != 60) {
+                throw sip::Exception(
+                        (boost::format("valid frame time length value: %d. valid values are: 10, 20, 40, 60") %
+                         frameTimeLength).str());
+            }
+
             pj_status_t status = pjmedia_port_info_init(&(mediaPort.info),
                                                         &name,
                                                         PJMEDIA_SIG_CLASS_PORT_AUD('s', 'i'),
                                                         SAMPLING_RATE,
                                                         1,
                                                         16,
-                                                        SAMPLING_RATE * 20 /
-                                                        1000); // todo recalculate to match mumble specs
+                                                        SAMPLING_RATE * frameTimeLength / 1000);
 
             if (status != PJ_SUCCESS) {
                 throw sip::Exception("error while calling pjmedia_port_info_init()", status);
@@ -208,7 +216,7 @@ namespace sip {
     }
 }
 
-sip::PjsuaCommunicator::PjsuaCommunicator(IncomingConnectionValidator &validator)
+sip::PjsuaCommunicator::PjsuaCommunicator(IncomingConnectionValidator &validator, int frameTimeLength)
         : logger(log4cpp::Category::getInstance("SipCommunicator")),
           pjsuaLogger(log4cpp::Category::getInstance("Pjsua")),
           uriValidator(validator) {
@@ -232,7 +240,9 @@ sip::PjsuaCommunicator::PjsuaCommunicator(IncomingConnectionValidator &validator
 
     mixer.reset(new mixer::AudioFramesMixer(cachingPool.factory));
 
-    media.reset(new _MumlibAudioMedia(*this));
+    media.reset(new _MumlibAudioMedia(*this, frameTimeLength));
+
+    logger.info("Created Pjsua communicator with frame length %d ms.", frameTimeLength);
 }
 
 void sip::PjsuaCommunicator::connect(

+ 5 - 1
PjsuaCommunicator.hpp

@@ -29,6 +29,10 @@ namespace sip {
             mesg += title;
         }
 
+        Exception(std::string title) : std::runtime_error(title) {
+            mesg += title;
+        }
+
         Exception(const char *title, pj_status_t status) : std::runtime_error(title) {
             char errorMsgBuffer[500];
             pj_strerror(status, errorMsgBuffer, sizeof(errorMsgBuffer));
@@ -56,7 +60,7 @@ namespace sip {
 
     class PjsuaCommunicator : boost::noncopyable {
     public:
-        PjsuaCommunicator(IncomingConnectionValidator &validator);
+        PjsuaCommunicator(IncomingConnectionValidator &validator, int frameTimeLength);
 
         void connect(
                 std::string host,

+ 7 - 0
config.ini.example

@@ -12,10 +12,17 @@ port = 5060
 user = mumsi
 password = foobar
 
+# length of single voice frame in ms. Valid values are 10, 20, 40, 60 ms.
+# Adjust it if you need to meet the specific bandwidth requirements of Murmur server
+frameLength = 40
+
 [mumble]
 host = example.org
 port = 64738
 user = mumsi
 password = foobar
 channelNameExpression =
+
+# Bitrate of Opus encoder in B/s
+# Adjust it if you need to meet the specific bandwidth requirements of Murmur server
 opusEncoderBitrate = 16000

+ 1 - 1
main.cpp

@@ -48,7 +48,7 @@ int main(int argc, char *argv[]) {
 
     boost::asio::io_service ioService;
 
-    sip::PjsuaCommunicator pjsuaCommunicator(connectionValidator);
+    sip::PjsuaCommunicator pjsuaCommunicator(connectionValidator, conf.getInt("sip.frameLength"));
 
     mumble::MumbleCommunicator mumbleCommunicator(ioService);