Browse Source

adding some method, and look for cause issue #3

Auzan 6 years ago
parent
commit
f6ef5949a1
5 changed files with 83 additions and 40 deletions
  1. 7 5
      include/mumlib.hpp
  2. 5 0
      include/mumlib/enums.hpp
  3. 11 1
      src/Audio.cpp
  4. 1 22
      src/CryptState.cpp
  5. 59 12
      src/mumlib.cpp

+ 7 - 5
include/mumlib.hpp

@@ -65,9 +65,9 @@ namespace mumlib {
 
         int getChannelId();
 
-        vector<MumbleUser> getListUser();
+        vector<MumbleUser> getListAllUser();
 
-        vector<MumbleChannel> getListChannel();
+        vector<MumbleChannel> getListAllChannel();
 
         void sendAudioData(int16_t *pcmData, int pcmLength);
 
@@ -79,9 +79,9 @@ namespace mumlib {
 
         void joinChannel(std::string channelName);
 
-        void sendVoiceTarget(int targetId, int channelId);
+        void sendVoiceTarget(mumlib::VoiceTargetType type, int targetId, int id);
 
-        void sendVoiceTarget(int targetId, std::string channelName);
+        bool sendVoiceTarget(mumlib::VoiceTargetType type, int targetId, std::string name);
 
         void sendUserState(mumlib::UserState state, bool val);
 
@@ -90,6 +90,8 @@ namespace mumlib {
     private:
         _Mumlib_Private *impl;
 
-        int getListChannelIdBy(std::string channelName);
+        int getChannelIdBy(std::string channelName);
+
+        int getUserIdBy(std::string userName);
     };
 }

+ 5 - 0
include/mumlib/enums.hpp

@@ -55,4 +55,9 @@ namespace mumlib {
         PRIORITY_SPEAKER,
         RECORDING
     };
+
+    enum class VoiceTargetType {
+        CHANNEL,
+        USER
+    };
 }

+ 11 - 1
src/Audio.cpp

@@ -76,6 +76,16 @@ std::pair<int, bool>  mumlib::Audio::decodeOpusPayload(uint8_t *inputBuffer,
                               % inputLength % dataPointer % opusDataLength).str());
     }
 
+    // Issue #3 (Users speaking simultaneously)
+    // https://mf4.xiph.org/jenkins/view/opus/job/opus/ws/doc/html/group__opus__decoder.html
+    // Opus is a stateful codec with overlapping blocks and as a result Opus packets are not coded independently of each other. 
+    // Packets must be passed into the decoder serially and in the correct order for a correct decode. 
+    // Lost packets can be replaced with loss concealment by calling the decoder with a null pointer and zero length for the missing packet.
+    // A single codec state may only be accessed from a single thread at a time and any required locking must be performed by the caller. 
+    // Separate streams must be decoded with separate decoder states and can be decoded in parallel unless the library was compiled with NONTHREADSAFE_PSEUDOSTACK defined.
+
+    int frame = opus_packet_get_nb_frames(&inputBuffer[dataPointer], opusDataLength);
+    int samples = frame * opus_packet_get_samples_per_frame(&inputBuffer[dataPointer], sampleRate);
     int outputSize = opus_decode(opusDecoder,
                                  reinterpret_cast<const unsigned char *>(&inputBuffer[dataPointer]),
                                  opusDataLength,
@@ -133,7 +143,7 @@ int mumlib::Audio::encodeAudioPacket(int target, int16_t *inputPcmBuffer, int in
     memcpy(outputBuffer, &header[0], header.size());
     memcpy(outputBuffer + header.size(), tmpOpusBuffer, (size_t) outputSize);
 
-    int incrementNumber = 100 * inputLength / this->sampleRate;
+    int incrementNumber = 100 * inputLength / sampleRate;
 
     outgoingSequenceNumber += incrementNumber;
 

+ 1 - 22
src/CryptState.cpp

@@ -191,34 +191,13 @@ bool mumlib::CryptState::decrypt(const unsigned char *source, unsigned char *dst
     return true;
 }
 
-#if defined(__LP64__)
-
 #define BLOCKSIZE 2
 #define SHIFTBITS 63
 typedef uint64_t subblock;
 
-#ifdef __x86_64__
-static inline uint64_t SWAP64(register uint64_t __in) { register uint64_t __out; __asm__("bswap %q0" : "=r"(__out) : "0"(__in)); return __out; }
-#else
-#define SWAP64(x) ((static_cast<uint64_t>(x) << 56) | \
-					((static_cast<uint64_t>(x) << 40) & 0xff000000000000ULL) | \
-					((static_cast<uint64_t>(x) << 24) & 0xff0000000000ULL) | \
-					((static_cast<uint64_t>(x) << 8)  & 0xff00000000ULL) | \
-					((static_cast<uint64_t>(x) >> 8)  & 0xff000000ULL) | \
-					((static_cast<uint64_t>(x) >> 24) & 0xff0000ULL) | \
-					((static_cast<uint64_t>(x) >> 40) & 0xff00ULL) | \
-					((static_cast<uint64_t>(x)  >> 56)))
-#endif
-// #define SWAP64(x) (__builtin_bswap64(x))
+#define SWAP64(x) (__builtin_bswap64(x))
 #define SWAPPED(x) SWAP64(x)
 
-#else
-#define BLOCKSIZE 4
-#define SHIFTBITS 31
-typedef uint32_t subblock;
-#define SWAPPED(x) htonl(x)
-#endif
-
 typedef subblock keyblock[BLOCKSIZE];
 
 static void inline XOR(subblock *dst, const subblock *a, const subblock *b) {

+ 59 - 12
src/mumlib.cpp

@@ -65,6 +65,8 @@ namespace mumlib {
                 auto incomingAudioPacket = audio.decodeIncomingAudioPacket(buffer, length);
 
                 if (type == AudioPacketType::OPUS) {
+                    // todo: multiple users speaking simultaneously (Issue #3)
+                    // something weird while decoding the opus payload
                     int16_t pcmData[5000];
                     auto status = audio.decodeOpusPayload(incomingAudioPacket.audioPayload,
                                                           incomingAudioPacket.audioPayloadLength,
@@ -127,6 +129,11 @@ namespace mumlib {
                 case MessageType::CHANNELREMOVE: {
                     MumbleProto::ChannelRemove channelRemove;
                     channelRemove.ParseFromArray(buffer, length);
+                    
+                    if(isListChannelContains(channelRemove.channel_id())) {
+                        listChannelRemovedBy(channelRemove.channel_id());
+                    }
+
                     callback.channelRemove(channelRemove.channel_id());
                 }
                     break;
@@ -381,6 +388,12 @@ namespace mumlib {
                     return true;
             return false;
         }
+
+        void listChannelRemovedBy(int channelId) {
+            for(int i = 0; i < listMumbleChannel.size(); i++) 
+                if(listMumbleChannel[i].channelId == channelId)
+                    listMumbleChannel.erase(listMumbleChannel.begin() + i);
+        }
     };
 
     Mumlib::Mumlib(Callback &callback) {
@@ -413,11 +426,11 @@ namespace mumlib {
         return impl->channelId;
     }
 
-    vector<mumlib::MumbleUser> Mumlib::getListUser() {
+    vector<mumlib::MumbleUser> Mumlib::getListAllUser() {
         return impl->listMumbleUser;
     }
 
-    vector<mumlib::MumbleChannel> Mumlib::getListChannel() {
+    vector<mumlib::MumbleChannel> Mumlib::getListAllChannel() {
         return impl->listMumbleChannel;
     }
 
@@ -468,23 +481,48 @@ namespace mumlib {
     }
 
     void Mumlib::joinChannel(string name) {
-        int channelId = Mumlib::getListChannelIdBy(name);
-        Mumlib::joinChannel(channelId);
+        int channelId = Mumlib::getChannelIdBy(name);
+        if(!channelId < 0) // when channel has not been registered / create
+            Mumlib::joinChannel(channelId);
     }
 
-    void Mumlib::sendVoiceTarget(int targetId, int channelId) {
+    void Mumlib::sendVoiceTarget(VoiceTargetType type, int targetId, int id) {
         MumbleProto::VoiceTarget voiceTarget;
         MumbleProto::VoiceTarget_Target voiceTargetTarget;
-        voiceTargetTarget.set_channel_id(channelId);
-        voiceTargetTarget.set_children(true);        
+        switch(type) {
+            case VoiceTargetType::CHANNEL: {
+                voiceTargetTarget.set_channel_id(id);
+                voiceTargetTarget.set_children(true);
+            }
+            break;
+            case VoiceTargetType::USER: {
+                voiceTargetTarget.add_session(id);
+            }
+            break;
+            default:
+                return;
+        }
         voiceTarget.set_id(targetId);
         voiceTarget.add_targets()->CopyFrom(voiceTargetTarget);
         impl->transport.sendControlMessage(MessageType::VOICETARGET, voiceTarget);
     }
 
-    void Mumlib::sendVoiceTarget(int targetId, string channelName) {
-        int channelId = Mumlib::getListChannelIdBy(channelName);
-        Mumlib::sendVoiceTarget(targetId, channelId);
+    bool Mumlib::sendVoiceTarget(VoiceTargetType type, int targetId, string name) {
+        int id = -1;
+        switch(type) {
+            case VoiceTargetType::CHANNEL: 
+                id = getChannelIdBy(name);
+                break;
+            case VoiceTargetType::USER:
+                id = getUserIdBy(name);
+                break;
+            default:
+                break;
+        }        
+        if(id < 0)
+            return false;
+        sendVoiceTarget(type, targetId, id);
+        return true;
     }
 
     void Mumlib::sendUserState(mumlib::UserState field, bool val) {
@@ -551,12 +589,21 @@ namespace mumlib {
         impl->transport.sendControlMessage(MessageType::USERSTATE, userState);
     }
 
-    int Mumlib::getListChannelIdBy(string name) {
+    int Mumlib::getChannelIdBy(string name) {
         vector<mumlib::MumbleChannel> listMumbleChannel = impl->listMumbleChannel;
-        int channelId = impl->channelId;
+        int channelId = -1;
         for(int i = 0; i < listMumbleChannel.size(); i++)
             if(listMumbleChannel[i].name == name)
                 channelId = listMumbleChannel[i].channelId;
         return channelId;
     }
+
+    int Mumlib::getUserIdBy(string name) {
+        vector<mumlib::MumbleUser> listMumbleUser = impl->listMumbleUser;
+        int sessionId = -1;
+        for(int i = 0; i < listMumbleUser.size(); i++)
+            if(listMumbleUser[i].name == name)
+                sessionId = listMumbleUser[i].sessionId;
+        return sessionId;
+    }
 }