use a vector for audio streams

This commit is contained in:
Stephen Birarda 2018-08-03 12:11:41 -07:00
parent aed79b3b17
commit 09cfe4dbc1
3 changed files with 38 additions and 40 deletions

View file

@ -213,9 +213,12 @@ void AudioMixerClientData::parseRadiusIgnoreRequest(QSharedPointer<ReceivedMessa
AvatarAudioStream* AudioMixerClientData::getAvatarAudioStream() { AvatarAudioStream* AudioMixerClientData::getAvatarAudioStream() {
QReadLocker readLocker { &_streamsLock }; QReadLocker readLocker { &_streamsLock };
auto it = _audioStreams.find(QUuid()); auto it = std::find_if(_audioStreams.begin(), _audioStreams.end(), [](const SharedStreamPointer& stream){
return stream->getStreamIdentifier().isNull();
});
if (it != _audioStreams.end()) { if (it != _audioStreams.end()) {
return dynamic_cast<AvatarAudioStream*>(it->second.get()); return dynamic_cast<AvatarAudioStream*>(it->get());
} }
// no mic stream found - return NULL // no mic stream found - return NULL
@ -238,11 +241,14 @@ void AudioMixerClientData::removeHRTFForStream(const QUuid& nodeID, const QUuid&
void AudioMixerClientData::removeAgentAvatarAudioStream() { void AudioMixerClientData::removeAgentAvatarAudioStream() {
QWriteLocker writeLocker { &_streamsLock }; QWriteLocker writeLocker { &_streamsLock };
auto it = _audioStreams.find(QUuid());
auto it = std::remove_if(_audioStreams.begin(), _audioStreams.end(), [](const SharedStreamPointer& stream){
return stream->getStreamIdentifier().isNull();
});
if (it != _audioStreams.end()) { if (it != _audioStreams.end()) {
_audioStreams.erase(it); _audioStreams.erase(it);
} }
writeLocker.unlock();
} }
int AudioMixerClientData::parseData(ReceivedMessage& message) { int AudioMixerClientData::parseData(ReceivedMessage& message) {
@ -271,7 +277,9 @@ int AudioMixerClientData::parseData(ReceivedMessage& message) {
QWriteLocker writeLocker { &_streamsLock }; QWriteLocker writeLocker { &_streamsLock };
auto micStreamIt = _audioStreams.find(QUuid()); auto micStreamIt = std::find_if(_audioStreams.begin(), _audioStreams.end(), [](const SharedStreamPointer& stream){
return stream->getStreamIdentifier().isNull();
});
if (micStreamIt == _audioStreams.end()) { if (micStreamIt == _audioStreams.end()) {
// we don't have a mic stream yet, so add it // we don't have a mic stream yet, so add it
@ -301,16 +309,12 @@ int AudioMixerClientData::parseData(ReceivedMessage& message) {
connect(avatarAudioStream, &InboundAudioStream::mismatchedAudioCodec, connect(avatarAudioStream, &InboundAudioStream::mismatchedAudioCodec,
this, &AudioMixerClientData::handleMismatchAudioFormat); this, &AudioMixerClientData::handleMismatchAudioFormat);
auto emplaced = _audioStreams.emplace( matchingStream = SharedStreamPointer(avatarAudioStream);
QUuid(), _audioStreams.push_back(matchingStream);
std::unique_ptr<PositionalAudioStream> { avatarAudioStream } } else {
); matchingStream = *micStreamIt;
micStreamIt = emplaced.first;
} }
matchingStream = micStreamIt->second;
writeLocker.unlock(); writeLocker.unlock();
isMicStream = true; isMicStream = true;
@ -327,7 +331,9 @@ int AudioMixerClientData::parseData(ReceivedMessage& message) {
QWriteLocker writeLock { &_streamsLock }; QWriteLocker writeLock { &_streamsLock };
auto streamIt = _audioStreams.find(streamIdentifier); auto streamIt = std::find_if(_audioStreams.begin(), _audioStreams.end(), [&streamIdentifier](const SharedStreamPointer& stream) {
return stream->getStreamIdentifier() == streamIdentifier;
});
if (streamIt == _audioStreams.end()) { if (streamIt == _audioStreams.end()) {
// we don't have this injected stream yet, so add it // we don't have this injected stream yet, so add it
@ -338,16 +344,12 @@ int AudioMixerClientData::parseData(ReceivedMessage& message) {
qCDebug(audio) << "creating new injectorStream... codec:" << _selectedCodecName << "isStereo:" << isStereo; qCDebug(audio) << "creating new injectorStream... codec:" << _selectedCodecName << "isStereo:" << isStereo;
#endif #endif
auto emplaced = _audioStreams.emplace( matchingStream = SharedStreamPointer(injectorStream);
streamIdentifier, _audioStreams.push_back(matchingStream);
std::unique_ptr<InjectedAudioStream> { injectorStream } } else {
); matchingStream = *streamIt;
streamIt = emplaced.first;
} }
matchingStream = streamIt->second;
writeLock.unlock(); writeLock.unlock();
} }
@ -373,7 +375,7 @@ int AudioMixerClientData::checkBuffersBeforeFrameSend() {
auto it = _audioStreams.begin(); auto it = _audioStreams.begin();
while (it != _audioStreams.end()) { while (it != _audioStreams.end()) {
SharedStreamPointer stream = it->second; SharedStreamPointer stream = *it;
if (stream->popFrames(1, true) > 0) { if (stream->popFrames(1, true) > 0) {
stream->updateLastPopOutputLoudnessAndTrailingLoudness(); stream->updateLastPopOutputLoudnessAndTrailingLoudness();
@ -388,7 +390,7 @@ int AudioMixerClientData::checkBuffersBeforeFrameSend() {
// this is an inactive injector, pull it from our streams // this is an inactive injector, pull it from our streams
// first emit that it is finished so that the HRTF objects for this source can be cleaned up // first emit that it is finished so that the HRTF objects for this source can be cleaned up
emit injectorStreamFinished(it->second->getStreamIdentifier()); emit injectorStreamFinished(stream->getStreamIdentifier());
// erase the stream to drop our ref to the shared pointer and remove it // erase the stream to drop our ref to the shared pointer and remove it
it = _audioStreams.erase(it); it = _audioStreams.erase(it);
@ -441,7 +443,7 @@ void AudioMixerClientData::sendAudioStreamStatsPackets(const SharedNodePointer&
// pack the calculated number of stream stats // pack the calculated number of stream stats
for (int i = 0; i < numStreamStatsToPack; i++) { for (int i = 0; i < numStreamStatsToPack; i++) {
PositionalAudioStream* stream = it->second.get(); PositionalAudioStream* stream = it->get();
stream->perSecondCallbackForUpdatingStats(); stream->perSecondCallbackForUpdatingStats();
@ -513,12 +515,12 @@ QJsonObject AudioMixerClientData::getAudioStreamStats() {
QJsonArray injectorArray; QJsonArray injectorArray;
auto streamsCopy = getAudioStreams(); auto streamsCopy = getAudioStreams();
for (auto& injectorPair : streamsCopy) { for (auto& injectorPair : streamsCopy) {
if (injectorPair.second->getType() == PositionalAudioStream::Injector) { if (injectorPair->getType() == PositionalAudioStream::Injector) {
QJsonObject upstreamStats; QJsonObject upstreamStats;
AudioStreamStats streamStats = injectorPair.second->getAudioStreamStats(); AudioStreamStats streamStats = injectorPair->getAudioStreamStats();
upstreamStats["inj.desired"] = streamStats._desiredJitterBufferFrames; upstreamStats["inj.desired"] = streamStats._desiredJitterBufferFrames;
upstreamStats["desired_calc"] = injectorPair.second->getCalculatedJitterBufferFrames(); upstreamStats["desired_calc"] = injectorPair->getCalculatedJitterBufferFrames();
upstreamStats["available_avg_10s"] = streamStats._framesAvailableAverage; upstreamStats["available_avg_10s"] = streamStats._framesAvailableAverage;
upstreamStats["available"] = (double) streamStats._framesAvailable; upstreamStats["available"] = (double) streamStats._framesAvailable;
upstreamStats["unplayed"] = (double) streamStats._unplayedMs; upstreamStats["unplayed"] = (double) streamStats._unplayedMs;

View file

@ -34,13 +34,12 @@ public:
~AudioMixerClientData(); ~AudioMixerClientData();
using SharedStreamPointer = std::shared_ptr<PositionalAudioStream>; using SharedStreamPointer = std::shared_ptr<PositionalAudioStream>;
using AudioStreamMap = std::unordered_map<QUuid, SharedStreamPointer>; using AudioStreamVector = std::vector<SharedStreamPointer>;
void queuePacket(QSharedPointer<ReceivedMessage> packet, SharedNodePointer node); void queuePacket(QSharedPointer<ReceivedMessage> packet, SharedNodePointer node);
void processPackets(); void processPackets();
// locks the mutex to make a copy AudioStreamVector& getAudioStreams() { return _audioStreams; }
AudioStreamMap getAudioStreams() { QReadLocker readLock { &_streamsLock }; return _audioStreams; }
AvatarAudioStream* getAvatarAudioStream(); AvatarAudioStream* getAvatarAudioStream();
// returns whether self (this data's node) should ignore node, memoized by frame // returns whether self (this data's node) should ignore node, memoized by frame
@ -127,7 +126,7 @@ private:
PacketQueue _packetQueue; PacketQueue _packetQueue;
QReadWriteLock _streamsLock; QReadWriteLock _streamsLock;
AudioStreamMap _audioStreams; // microphone stream from avatar is stored under key of null UUID AudioStreamVector _audioStreams; // microphone stream from avatar is stored under key of null UUID
void optionallyReplicatePacket(ReceivedMessage& packet, const Node& node); void optionallyReplicatePacket(ReceivedMessage& packet, const Node& node);

View file

@ -36,7 +36,7 @@
#include "InjectedAudioStream.h" #include "InjectedAudioStream.h"
#include "AudioHelpers.h" #include "AudioHelpers.h"
using AudioStreamMap = AudioMixerClientData::AudioStreamMap; using AudioStreamVector = AudioMixerClientData::AudioStreamVector;
// packet helpers // packet helpers
std::unique_ptr<NLPacket> createAudioPacket(PacketType type, int size, quint16 sequence, QString codec); std::unique_ptr<NLPacket> createAudioPacket(PacketType type, int size, quint16 sequence, QString codec);
@ -146,8 +146,7 @@ bool AudioMixerSlave::prepareMix(const SharedNodePointer& listener) {
auto forAllStreams = [&](const SharedNodePointer& node, AudioMixerClientData* nodeData, MixFunctor mixFunctor) { auto forAllStreams = [&](const SharedNodePointer& node, AudioMixerClientData* nodeData, MixFunctor mixFunctor) {
auto nodeID = node->getUUID(); auto nodeID = node->getUUID();
for (auto& streamPair : nodeData->getAudioStreams()) { for (auto& streamPair : nodeData->getAudioStreams()) {
auto nodeStream = streamPair.second; (this->*mixFunctor)(*listenerData, nodeID, *listenerAudioStream, *streamPair);
(this->*mixFunctor)(*listenerData, nodeID, *listenerAudioStream, *nodeStream);
} }
}; };
@ -164,9 +163,8 @@ bool AudioMixerSlave::prepareMix(const SharedNodePointer& listener) {
if (*node == *listener) { if (*node == *listener) {
// only mix the echo, if requested // only mix the echo, if requested
for (auto& streamPair : nodeData->getAudioStreams()) { for (auto& streamPair : nodeData->getAudioStreams()) {
auto nodeStream = streamPair.second; if (streamPair->shouldLoopbackForNode()) {
if (nodeStream->shouldLoopbackForNode()) { mixStream(*listenerData, node->getUUID(), *listenerAudioStream, *streamPair);
mixStream(*listenerData, node->getUUID(), *listenerAudioStream, *nodeStream);
} }
} }
} else if (!listenerData->shouldIgnore(listener, node, _frame)) { } else if (!listenerData->shouldIgnore(listener, node, _frame)) {
@ -177,8 +175,7 @@ bool AudioMixerSlave::prepareMix(const SharedNodePointer& listener) {
// compute the node's max relative volume // compute the node's max relative volume
float nodeVolume = 0.0f; float nodeVolume = 0.0f;
for (auto& streamPair : nodeData->getAudioStreams()) { for (auto& nodeStream : nodeData->getAudioStreams()) {
auto nodeStream = streamPair.second;
// approximate the gain // approximate the gain
glm::vec3 relativePosition = nodeStream->getPosition() - listenerAudioStream->getPosition(); glm::vec3 relativePosition = nodeStream->getPosition() - listenerAudioStream->getPosition();