Esempio n. 1
0
void AudioMixerClientData::processStreamPacket(ReceivedMessage& message, ConcurrentAddedStreams &addedStreams) {

    if (!containsValidPosition(message)) {
        qDebug() << "Refusing to process audio stream from" << message.getSourceID() << "with invalid position";
        return;
    }

    SharedStreamPointer matchingStream;

    auto packetType = message.getType();
    bool newStream = false;

    if (packetType == PacketType::MicrophoneAudioWithEcho
        || packetType == PacketType::MicrophoneAudioNoEcho
        || packetType == PacketType::SilentAudioFrame) {

        auto micStreamIt = std::find_if(_audioStreams.begin(), _audioStreams.end(), [](const SharedStreamPointer& stream){
            return stream->getStreamIdentifier().isNull();
        });

        if (micStreamIt == _audioStreams.end()) {
            // we don't have a mic stream yet, so add it

            // hop past the sequence number that leads the packet
            message.seek(sizeof(StreamSequenceNumber));

            // pull the codec string from the packet
            auto codecString = message.readString();

            // determine if the stream is stereo or not
            bool isStereo;
            if (packetType == PacketType::SilentAudioFrame || packetType == PacketType::ReplicatedSilentAudioFrame) {
                SilentSamplesBytes numSilentSamples;
                message.readPrimitive(&numSilentSamples);
                isStereo = numSilentSamples == AudioConstants::NETWORK_FRAME_SAMPLES_STEREO;
            } else {
                ChannelFlag channelFlag;
                message.readPrimitive(&channelFlag);
                isStereo = channelFlag == 1;
            }

            auto avatarAudioStream = new AvatarAudioStream(isStereo, AudioMixer::getStaticJitterFrames());
            avatarAudioStream->setupCodec(_codec, _selectedCodecName, isStereo ? AudioConstants::STEREO : AudioConstants::MONO);

            if (_isIgnoreRadiusEnabled) {
                avatarAudioStream->enableIgnoreBox();
            } else {
                avatarAudioStream->disableIgnoreBox();
            }

            qCDebug(audio) << "creating new AvatarAudioStream... codec:" << _selectedCodecName << "isStereo:" << isStereo;

            connect(avatarAudioStream, &InboundAudioStream::mismatchedAudioCodec,
                    this, &AudioMixerClientData::handleMismatchAudioFormat);

            matchingStream = SharedStreamPointer(avatarAudioStream);
            _audioStreams.push_back(matchingStream);

            newStream = true;
        } else {
            matchingStream = *micStreamIt;
        }
    } else if (packetType == PacketType::InjectAudio) {

        // this is injected audio
        // skip the sequence number and codec string and grab the stream identifier for this injected audio
        message.seek(sizeof(StreamSequenceNumber));
        message.readString();

        QUuid streamIdentifier = QUuid::fromRfc4122(message.readWithoutCopy(NUM_BYTES_RFC4122_UUID));

        auto streamIt = std::find_if(_audioStreams.begin(), _audioStreams.end(), [&streamIdentifier](const SharedStreamPointer& stream) {
            return stream->getStreamIdentifier() == streamIdentifier;
        });

        if (streamIt == _audioStreams.end()) {
            bool isStereo;
            message.readPrimitive(&isStereo);

            // we don't have this injected stream yet, so add it
            auto injectorStream = new InjectedAudioStream(streamIdentifier, isStereo, AudioMixer::getStaticJitterFrames());

#if INJECTORS_SUPPORT_CODECS
            injectorStream->setupCodec(_codec, _selectedCodecName, isStereo ? AudioConstants::STEREO : AudioConstants::MONO);
            qCDebug(audio) << "creating new injectorStream... codec:" << _selectedCodecName << "isStereo:" << isStereo;
#endif

            matchingStream = SharedStreamPointer(injectorStream);
            _audioStreams.push_back(matchingStream);

            newStream = true;
        } else {
            matchingStream = *streamIt;
        }
    }

    // seek to the beginning of the packet so that the next reader is in the right spot
    message.seek(0);

    // check the overflow count before we parse data
    auto overflowBefore = matchingStream->getOverflowCount();
    matchingStream->parseData(message);

    if (matchingStream->getOverflowCount() > overflowBefore) {
        qCDebug(audio) << "Just overflowed on stream" << matchingStream->getStreamIdentifier()
            << "from" << message.getSourceID();
    }

    if (newStream) {
        // whenever a stream is added, push it to the concurrent vector of streams added this frame
        addedStreams.push_back(AddedStream(getNodeID(), getNodeLocalID(), matchingStream->getStreamIdentifier(), matchingStream.get()));
    }
}