diff options
author | Thorvald Natvig <slicer@users.sourceforge.net> | 2009-04-20 17:54:56 +0400 |
---|---|---|
committer | Thorvald Natvig <slicer@users.sourceforge.net> | 2009-04-20 17:54:56 +0400 |
commit | 1a36b561219fe62e93686e1a597751ceaa008b07 (patch) | |
tree | ea4fb88480b329ea789c249d997582b2e3edceb8 | |
parent | 820194a0718e6b5e8d0789914e0793eeb6aeb5b7 (diff) |
Handle positional audio distribution server-side
-rw-r--r-- | src/PacketDataStream.h | 18 | ||||
-rw-r--r-- | src/Player.h | 2 | ||||
-rw-r--r-- | src/mumble/AudioInput.cpp | 24 | ||||
-rw-r--r-- | src/mumble/AudioOutput.cpp | 14 | ||||
-rw-r--r-- | src/mumble/Messages.cpp | 4 | ||||
-rw-r--r-- | src/mumble/Plugins.h | 2 | ||||
-rw-r--r-- | src/murmur/Messages.cpp | 13 | ||||
-rw-r--r-- | src/murmur/Server.cpp | 35 | ||||
-rw-r--r-- | src/murmur/Server.h | 3 |
9 files changed, 78 insertions, 37 deletions
diff --git a/src/PacketDataStream.h b/src/PacketDataStream.h index 948cb03dd..eb1d99652 100644 --- a/src/PacketDataStream.h +++ b/src/PacketDataStream.h @@ -328,6 +328,24 @@ class PacketDataStream { return *this; } + union float32u { + quint32 ui; + float f; + }; + + PacketDataStream &operator <<(const float v) { + float32u u; + u.f = v; + return *this << u.ui; + } + + PacketDataStream &operator >>(float &v) { + float32u u; + *this >> u.ui; + v = u.f; + return *this; + } + template <typename T> PacketDataStream &operator <<(const QList<T> &l) { *this << l.size(); diff --git a/src/Player.h b/src/Player.h index d5ce8eead..610ec1003 100644 --- a/src/Player.h +++ b/src/Player.h @@ -50,8 +50,6 @@ class Player { bool bTalking, bAltSpeak; Channel *cChannel; QByteArray qbaTexture; - std::string ssContext; - QString qsIdentity; QString getFlagsString() const; Player(); diff --git a/src/mumble/AudioInput.cpp b/src/mumble/AudioInput.cpp index 24742e652..0028c5f5a 100644 --- a/src/mumble/AudioInput.cpp +++ b/src/mumble/AudioInput.cpp @@ -658,24 +658,6 @@ void AudioInput::encodeAudioFrame() { if (! iIsSpeech) { memset(psMic, 0, sizeof(short) * iFrameSize); } - /* - FIXME: Once per packet, moved into flushCheck - if (g.s.bTransmitPosition && g.p && ! g.bCenterPosition && (iFrames == 0) && g.p->fetch()) { - QByteArray q; - QDataStream ds(&q, QIODevice::WriteOnly); - ds << g.p->fPosition[0]; - ds << g.p->fPosition[1]; - ds << g.p->fPosition[2]; - - speex_bits_pack(&sbBits, 13, 5); - speex_bits_pack(&sbBits, q.size(), 4); - - const unsigned char *d=reinterpret_cast<const unsigned char*>(q.data()); - for (i=0;i<q.size();i++) { - speex_bits_pack(&sbBits, d[i], 8); - } - } - */ unsigned char buffer[512]; int len = celt_encode(ceEncoder, psSource, NULL, buffer, 75); iBitrate = len * 100 * 8; @@ -701,6 +683,12 @@ void AudioInput::flushCheck(const QByteArray &qba) { pds << iFrameCounter; pds << qlFrames; + if (g.s.bTransmitPosition && g.p && ! g.bCenterPosition && g.p->fetch()) { + pds << g.p->fPosition[0]; + pds << g.p->fPosition[1]; + pds << g.p->fPosition[2]; + } + // TODO: Loopback if (g.s.lmLoopMode == Settings::Local) LoopPlayer::lpLoopy.addFrame(QByteArray(data+1, pds.size())); diff --git a/src/mumble/AudioOutput.cpp b/src/mumble/AudioOutput.cpp index 8f81bd748..21f0457e0 100644 --- a/src/mumble/AudioOutput.cpp +++ b/src/mumble/AudioOutput.cpp @@ -381,8 +381,17 @@ bool AudioOutputSpeech::needSamples(unsigned int snum) { if (jitter_buffer_get(jbJitter, &jbp, iFrameSize, &startofs) == JITTER_BUFFER_OK) { PacketDataStream pds(jbp.data, jbp.len); pds >> qlFrames; - if (pds.isValid()) + if (pds.left()) { + pds >> fPos[0]; + pds >> fPos[1]; + pds >> fPos[2]; + } else { + fPos[0] = fPos[1] = fPos[2] = 0.0f; + } + if (pds.isValid()) { + iMissCount = 0; bLastAlive = true; + } } else { iMissCount++; if (iMissCount > 10) { @@ -522,6 +531,7 @@ void AudioOutput::addFrameToBuffer(ClientPlayer *player, const QByteArray &qbaPa return; qrwlOutputs.lockForRead(); AudioOutputSpeech *aop = dynamic_cast<AudioOutputSpeech *>(qmOutputs.value(player)); + if (! aop) { qrwlOutputs.unlock(); @@ -751,6 +761,7 @@ bool AudioOutput::mix(void *outbuff, unsigned int nsamp) { } validListener = true; } + foreach(aop, qlMix) { const float * RESTRICT pfBuffer = aop->pfBuffer; @@ -794,6 +805,7 @@ bool AudioOutput::mix(void *outbuff, unsigned int nsamp) { } } } + // Clip if (eSampleFormat == SampleFloat) for (unsigned int i=0;i<nsamp*iChannels;i++) diff --git a/src/mumble/Messages.cpp b/src/mumble/Messages.cpp index 68a754992..d136c464e 100644 --- a/src/mumble/Messages.cpp +++ b/src/mumble/Messages.cpp @@ -221,10 +221,6 @@ void MainWindow::msgUserState(const MumbleProto::UserState &msg) { pDst->qbaTexture = QByteArray(str.data(), str.size()); g.o->verifyTexture(pDst); } - if (msg.has_plugin_context()) { - QMutexLocker qml(&g.p->qmPlugins); - pDst->ssContext = msg.plugin_context(); - } } void MainWindow::msgUserRemove(const MumbleProto::UserRemove &msg) { diff --git a/src/mumble/Plugins.h b/src/mumble/Plugins.h index f2c5013a9..24eb2082c 100644 --- a/src/mumble/Plugins.h +++ b/src/mumble/Plugins.h @@ -62,11 +62,11 @@ class Plugins : public QObject { Q_OBJECT Q_DISABLE_COPY(Plugins) protected: + QMutex qmPlugins; QList<PluginInfo *> qlPlugins; PluginInfo *locked; PluginInfo *prevlocked; public: - QMutex qmPlugins; std::string ssContext, ssContextSent; std::wstring swsIdentity, swsIdentitySent; bool bValid; diff --git a/src/murmur/Messages.cpp b/src/murmur/Messages.cpp index e8c303c2d..a708b453e 100644 --- a/src/murmur/Messages.cpp +++ b/src/murmur/Messages.cpp @@ -242,9 +242,6 @@ void Server::msgAuthenticate(User *uSource, MumbleProto::Authenticate &msg) { else if (u->bSelfMute) mpus.set_self_mute(true); - if (! u->ssContext.empty()) - mpus.set_plugin_context(u->ssContext); - sendMessage(uSource, mpus); } @@ -327,6 +324,8 @@ void Server::msgUserState(User *uSource, MumbleProto::UserState &msg) { MSG_SETUP(Player::Authenticated); VICTIM_SETUP; + bool bNoBroadcast = false; + if (pDstUser->iId == 0) { PERM_DENIED_TEXT("Can't modify SuperUser"); return; @@ -376,14 +375,15 @@ void Server::msgUserState(User *uSource, MumbleProto::UserState &msg) { uSource->bSelfDeaf = false; } } - + if (msg.has_plugin_context()) { + bNoBroadcast = true; uSource->ssContext = msg.plugin_context(); } if (msg.has_plugin_identity()) { + bNoBroadcast = true; uSource->qsIdentity = u8(msg.plugin_identity()); - msg.clear_plugin_identity(); } if (msg.has_channel_id()) { @@ -413,7 +413,8 @@ void Server::msgUserState(User *uSource, MumbleProto::UserState &msg) { log(uSource, QString("Changed speak-state of %1 (%2 %3 %4)").arg(*pDstUser).arg(pDstUser->bMute).arg(pDstUser->bDeaf).arg(pDstUser->bSuppressed)); } - sendAll(msg); + if (! bNoBroadcast) + sendAll(msg); emit playerStateChanged(pDstUser); } diff --git a/src/murmur/Server.cpp b/src/murmur/Server.cpp index 912c55dcc..954f6c111 100644 --- a/src/murmur/Server.cpp +++ b/src/murmur/Server.cpp @@ -475,10 +475,13 @@ void Server::processMsg(User *u, const char *data, int len) { Player *p; BandwidthRecord *bw = & u->bwr; Channel *c = u->cChannel; - QByteArray qba; + QByteArray qba, qba_npos; + unsigned int counter; char buffer[512]; + PacketDataStream pdi(data + 1, len - 1); PacketDataStream pds(buffer+1, 511); unsigned int target = data[0] & 0x1f; + unsigned int poslen; // IP + UDP + Crypt + Data int packetsize = 20 + 8 + 4 + len; @@ -489,6 +492,18 @@ void Server::processMsg(User *u, const char *data, int len) { return; } + pdi >> counter; + + // Skip QList<QByteArray> + pdi >> counter; + while (counter && pdi.isValid()) { + unsigned int v; + pdi >> v; + pdi.skip(v); + } + + poslen = pdi.left(); + buffer[0] = target; pds << u->uiSession; pds.append(data + 1, len - 1); @@ -501,8 +516,13 @@ void Server::processMsg(User *u, const char *data, int len) { } foreach(p, c->qlPlayers) { - if (! p->bDeaf && ! p->bSelfDeaf && (p != static_cast<Player *>(u))) - sendMessage(static_cast<User *>(p), buffer, len, qba); + User *pDst = static_cast<User *>(p); + if (! p->bDeaf && ! p->bSelfDeaf && (pDst != u)) { + if (poslen && pDst->ssContext == u->ssContext) + sendMessage(pDst, buffer, len, qba); + else + sendMessage(pDst, buffer, len - poslen, qba_npos); + } } if (! c->qhLinks.isEmpty()) { @@ -514,8 +534,13 @@ void Server::processMsg(User *u, const char *data, int len) { foreach(Channel *l, chans) { if (ChanACL::hasPermission(u, l, (target == 1) ? ChanACL::AltSpeak : ChanACL::Speak, acCache)) { foreach(p, l->qlPlayers) { - if (! p->bDeaf && ! p->bSelfDeaf) - sendMessage(static_cast<User *>(p), buffer, len, qba); + User *pDst = static_cast<User *>(pDst); + if (! p->bDeaf && ! p->bSelfDeaf) { + if (poslen && pDst->ssContext == u->ssContext) + sendMessage(pDst, buffer, len, qba); + else + sendMessage(pDst, buffer, len - poslen, qba_npos); + } } } } diff --git a/src/murmur/Server.h b/src/murmur/Server.h index b1dd25ced..38ce4d42f 100644 --- a/src/murmur/Server.h +++ b/src/murmur/Server.h @@ -105,6 +105,9 @@ class User : public Connection, public Player { QString qsOS; QString qsOSVersion; + std::string ssContext; + QString qsIdentity; + BandwidthRecord bwr; struct sockaddr_in saiUdpAddress; User(Server *parent, QSslSocket *socket); |