Browse Source

Replace libmumble with mumlib library.

Michał Słomkowski 8 years ago
parent
commit
87842318be
6 changed files with 53 additions and 169 deletions
  1. 3 1
      .gitignore
  2. 0 0
      .gitmodules
  3. 3 5
      CMakeLists.txt
  4. 28 144
      MumbleCommunicator.cpp
  5. 15 17
      MumbleCommunicator.hpp
  6. 4 2
      main.cpp

+ 3 - 1
.gitignore

@@ -1,4 +1,6 @@
 *.iml
 .idea/
 
-config.ini
+config.ini
+
+build/

+ 0 - 0
.gitmodules


+ 3 - 5
CMakeLists.txt

@@ -7,19 +7,17 @@ INCLUDE(FindPkgConfig)
 find_package(Boost COMPONENTS system unit_test_framework program_options filesystem REQUIRED)
 find_package(PkgConfig REQUIRED)
 
-pkg_check_modules(OPUS "opus")
 pkg_check_modules(PJSIP "libpjproject")
 pkg_check_modules(LOG4CPP "log4cpp")
 pkg_check_modules(SNDFILE "sndfile")
 
 
-include_directories(${OPUS_INCLUDE_DIRS})
 include_directories(${PJSIP_INCLUDE_DIRS})
 include_directories(${LOG4CPP_INCLUDE_DIRS})
 include_directories(${SNDFILE_INCLUDE_DIRS})
-include_directories(libmumble)
+include_directories(../mumlib/include)
 
-link_directories(libmumble)
+link_directories(../mumlib/build)
 
 set(SOURCE_FILES
         PjsuaCommunicator.cpp
@@ -40,7 +38,7 @@ target_link_libraries(mumsi ${PJSIP_LIBRARIES})
 target_link_libraries(mumsi ${LOG4CPP_LIBRARIES})
 target_link_libraries(mumsi ${SNDFILE_LIBRARIES})
 target_link_libraries(mumsi ${Boost_LIBRARIES})
-target_link_libraries(mumsi mumble)
+target_link_libraries(mumsi mumlib)
 
 #add_executable(mumsi_test ${SOURCE_FILES} ${TEST_SOURCE_FILES} test_main.cpp)
 #target_link_libraries(mumsi_test ${OPUS_LIBRARIES})

+ 28 - 144
MumbleCommunicator.cpp

@@ -3,163 +3,47 @@
 
 #include "MumbleCommunicator.hpp"
 
-void mumble::MumbleCommunicator::receiveAudioFrameCallback(uint8_t *audio_data, uint32_t audio_data_size) {
-    int dataPointer = 1;
-    opus_int16 pcmData[1024];
-
-    if (audio_data[0] == 0x80) {
-        int64_t sessionId;
-        int64_t sequenceNumber;
-        int64_t opusDataLength;
-        bool lastPacket;
-
-        dataPointer += mumble_parse_variant(&sessionId, &audio_data[dataPointer]);
-        dataPointer += mumble_parse_variant(&sequenceNumber, &audio_data[dataPointer]);
-        dataPointer += mumble_parse_variant(&opusDataLength, &audio_data[dataPointer]);
-
-        lastPacket = (opusDataLength & 0x2000) != 0;
-        opusDataLength = opusDataLength & 0x1fff;
-
-
-        unsigned int iAudioBufferSize;
-        unsigned int iFrameSize = mumble::SAMPLE_RATE / 100;
-        iAudioBufferSize = iFrameSize;
-        iAudioBufferSize *= 12;
-        int decodedSamples = opus_decode(opusDecoder,
-                                         reinterpret_cast<const unsigned char *>(&audio_data[dataPointer]),
-                                         opusDataLength,
-                                         pcmData,
-                                         iAudioBufferSize,
-                                         0);
-
-        fileHandle.write(pcmData, decodedSamples);
-
-        logger.debug("Received %d bytes of Opus data (seq %ld), decoded to %d bytes. Push it to outputQueue.",
-                     opusDataLength, sequenceNumber, decodedSamples);
-
-        samplesBuffer.pushSamples(pcmData, decodedSamples);
-
-    } else {
-        logger.warn("Received %d bytes of non-recognisable audio data.", audio_data_size);
-    }
-}
-
-static void mumble_audio_callback(uint8_t *audio_data, uint32_t audio_data_size, void *userData) {
-    mumble::MumbleCommunicator *mumbleCommunicator = static_cast<mumble::MumbleCommunicator *>(userData);
-    mumbleCommunicator->receiveAudioFrameCallback(audio_data, audio_data_size);
-}
-
-static void mumble_serversync_callback(char *welcome_text,
-                                       int32_t session,
-                                       int32_t max_bandwidth,
-                                       int64_t permissions,
-                                       void *usterData) {
-    printf("%s\n", welcome_text);
-}
-
-void mumble_cryptsetup_callback(uint32_t key_size,
-                                uint8_t *key,
-                                uint32_t client_nonce_size,
-                                uint8_t *client_nonce,
-                                uint32_t server_nonce_size,
-                                uint8_t *server_nonce,
-                                void *userData) {
-    mumble::MumbleCommunicator *mumbleCommunicator = static_cast<mumble::MumbleCommunicator *>(userData);
-    printf("received crypto nonce\n");
-}
-
-
-static int verify_cert(uint8_t *, uint32_t) {
-    // Accept every cert
-    return 1;
+namespace mumble {
+    class MumlibCallback : public mumlib::BasicCallback {
+    public:
+        std::shared_ptr<mumlib::Mumlib> mum;
+        MumbleCommunicator *communicator;
+
+        virtual void audio(
+                int16_t *pcm_data,
+                uint32_t pcm_data_size) {
+            communicator->samplesBuffer.pushSamples(pcm_data, pcm_data_size);
+        }
+    };
 }
 
 mumble::MumbleCommunicator::MumbleCommunicator(
+        boost::asio::io_service &ioService,
         ISamplesBuffer &samplesBuffer,
         std::string user,
         std::string password,
         std::string host,
-        int port) : samplesBuffer(samplesBuffer),
-                    outgoingAudioSequenceNumber(1),
+        int port) : ioService(ioService),
+                    samplesBuffer(samplesBuffer),
                     logger(log4cpp::Category::getInstance("MumbleCommunicator")) {
 
     quit = false;
 
-    opusDecoder = opus_decoder_create(SAMPLE_RATE, 1, nullptr); //todo grab error
-
-    opusEncoder = opus_encoder_create(SAMPLE_RATE, 1, OPUS_APPLICATION_VOIP, nullptr);
-    opus_encoder_ctl(opusEncoder, OPUS_SET_VBR(0));
-
-    fileHandle = SndfileHandle("capture_mumble.wav", SFM_WRITE, SF_FORMAT_WAV | SF_FORMAT_PCM_16, 1, SAMPLE_RATE);
+    callback.reset(new MumlibCallback());
 
-    struct mumble_config config;
-    std::memset(&config, 0, sizeof(config));
+    mum.reset(new mumlib::Mumlib(*callback, ioService));
+    callback->communicator = this;
+    callback->mum = mum;
 
-    config.user_data = this;
-
-    config.size = sizeof(config);
-    config.host = const_cast<char *>(host.c_str());
-    if (port > 0) {
-        config.port = const_cast<char *>(std::to_string(port).c_str());
-    }
-    config.server_password = const_cast<char *>(password.c_str());
-    config.username = const_cast<char *>(user.c_str());
-    config.user_cert_filename = nullptr;
-    config.user_privkey_filename = nullptr;
-
-    config.ssl_verification_callback = verify_cert;
-    config.audio_callback = mumble_audio_callback;
-    config.serversync_callback = mumble_serversync_callback;
-    config.cryptsetup_callback = mumble_cryptsetup_callback;
-
-    mumble = mumble_connect(nullptr, &config);
-
-    if (mumble == nullptr) {
-        throw mumble::Exception("couldn't establish mumble connection");
-    }
+    mum->connect(host, port, user, password);
 }
 
 mumble::MumbleCommunicator::~MumbleCommunicator() {
-    mumble_close(mumble);
-}
-
-void mumble::MumbleCommunicator::loop() {
-
-    senderThread.reset(new std::thread(&MumbleCommunicator::senderThreadFunction, this));
-
-    while (!quit) {
-        int status = mumble_tick(mumble);
-        logger.debug("tick");
-        if (status < 0) {
-            throw mumble::Exception("mumble_tick status " + status);
-        }
-
-        //todo Other processing here?
-    }
-}
-
-
-void mumble::MumbleCommunicator::senderThreadFunction() {
-    while (!quit) {
-        opus_int16 pcmData[1024];
-        unsigned char outputBuffer[1024];
-
-        int pcmLength = samplesBuffer.pullSamples(pcmData, 480, true);
-
-        logger.debug("Pop %d samples from inputQueue.", pcmLength);
-
-        int encodedSamples = opus_encode(opusEncoder, pcmData, pcmLength, outputBuffer, sizeof(outputBuffer));
-
-        if (encodedSamples < 1) {
-            logger.warn("opus_encode returned %d: %s", encodedSamples, opus_strerror(encodedSamples));
-        } else {
-            logger.debug("Sending %d bytes of Opus audio data (seq %d).", encodedSamples,
-                         outgoingAudioSequenceNumber);
-
-            //todo to powinno dać się bezpiecznie wykonać w osobnym wątku
-            mumble_send_audio_data(mumble, outgoingAudioSequenceNumber, outputBuffer, encodedSamples);
-
-            outgoingAudioSequenceNumber += 1;
-        }
-    }
-}
+    mum->disconnect();
+}
+//
+//void mumble::MumbleCommunicator::senderThreadFunction() {
+//    while (!quit) {
+//
+//    }
+//}

+ 15 - 17
MumbleCommunicator.hpp

@@ -2,30 +2,27 @@
 #define MUMSI_MUMBLECOMMUNICATOR_HPP
 
 #include "ISamplesBuffer.hpp"
-
-extern "C" {
-#include "libmumble.h"
-}
+#include <mumlib.hpp>
 
 #include <string>
 #include <stdexcept>
-#include <opus.h>
 #include <log4cpp/Category.hh>
 #include <sndfile.hh>
 #include <thread>
 
 namespace mumble {
 
-    constexpr unsigned int SAMPLE_RATE = 48000;
-
     class Exception : public std::runtime_error {
     public:
         Exception(const char *message) : std::runtime_error(message) { }
     };
 
+    class MumlibCallback;
+
     class MumbleCommunicator {
     public:
         MumbleCommunicator(
+                boost::asio::io_service &ioService,
                 ISamplesBuffer &samplesBuffer,
                 std::string user,
                 std::string password,
@@ -34,28 +31,29 @@ namespace mumble {
 
         ~MumbleCommunicator();
 
-        void loop();
+//        void senderThreadFunction();
+
+        //void receiveAudioFrameCallback(uint8_t *audio_data, uint32_t audio_data_size);
 
-        void senderThreadFunction();
 
-        void receiveAudioFrameCallback(uint8_t *audio_data, uint32_t audio_data_size);
+    public:
+        boost::asio::io_service &ioService;
 
-    private:
         log4cpp::Category &logger;
 
         ISamplesBuffer &samplesBuffer;
 
-        std::unique_ptr<std::thread> senderThread;
-
-        mumble_struct *mumble;
-        OpusDecoder *opusDecoder;
-        OpusEncoder *opusEncoder;
+        std::shared_ptr<mumlib::Mumlib> mum;
 
-        int outgoingAudioSequenceNumber;
+        std::unique_ptr<std::thread> senderThread;
 
         SndfileHandle fileHandle;
 
+        std::unique_ptr<MumlibCallback> callback;
+
         bool quit;
+
+        friend class MumlibCallback;
     };
 }
 

+ 4 - 2
main.cpp

@@ -22,6 +22,8 @@ int main(int argc, char *argv[]) {
 
     config::Configuration conf(argv[1]);
 
+    boost::asio::io_service ioService;
+
     sip::PjsuaCommunicator pjsuaCommunicator(
             conf.getString("sip.host"),
             conf.getString("sip.user"),
@@ -29,6 +31,7 @@ int main(int argc, char *argv[]) {
             conf.getInt("sip.port"));
 
     mumble::MumbleCommunicator mumbleCommunicator(
+            ioService,
             pjsuaCommunicator,
             conf.getString("mumble.user"),
             conf.getString("mumble.password"),
@@ -37,8 +40,7 @@ int main(int argc, char *argv[]) {
 
     logger.info("Application started.");
 
-    mumbleCommunicator.loop();
-
+    ioService.run();
 
     return 0;
 }