From bb132e354bc24d9665524ab882b1674d589f766d Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 9 Jul 2015 09:24:07 -0700 Subject: [PATCH] Update AudioClient to use packet callbacks --- libraries/audio-client/src/AudioClient.cpp | 95 ++++++++++++++++++++++ libraries/audio-client/src/AudioClient.h | 12 ++- 2 files changed, 104 insertions(+), 3 deletions(-) diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index a75b9124db..3856e32fca 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -140,6 +140,14 @@ AudioClient::AudioClient() : // create GVerb filter _gverb = createGverbFilter(); configureGverbFilter(_gverb); + + auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); + packetReceiver.registerPacketListener(PacketType::AudioEnvironment, this, "handleAudioStreamStatsPacket"); + packetReceiver.registerPacketListener(PacketType::AudioStreamStats, this, "handleAudioEnvironmentDataPacket"); + packetReceiver.registerPacketListener(PacketType::MixedAudio, this, "handleAudioDataPacket"); + packetReceiver.registerPacketListener(PacketType::SilentAudioFrame, this, "handleSilentAudioFrame"); + packetReceiver.registerPacketListener(PacketType::NoisyMute, this, "handleNoisyMutePacket"); + packetReceiver.registerPacketListener(PacketType::MuteEnvironment, this, "handleMuteEnvironmentPacket"); } AudioClient::~AudioClient() { @@ -527,6 +535,93 @@ void AudioClient::stop() { } } +void AudioClient::handleAudioStreamStatsPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr) { + _stats.parseAudioStreamStatsPacket(packet->getData()); + + updateLastHeardFromAudioMixer(packet); +} + +void AudioClient::handleAudioEnvironmentDataPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr) { + const char* dataAt = packet->getPayload(); + + char bitset; + memcpy(&bitset, dataAt, sizeof(char)); + dataAt += sizeof(char); + + bool hasReverb = oneAtBit(bitset, HAS_REVERB_BIT);; + if (hasReverb) { + float reverbTime, wetLevel; + memcpy(&reverbTime, dataAt, sizeof(float)); + dataAt += sizeof(float); + memcpy(&wetLevel, dataAt, sizeof(float)); + dataAt += sizeof(float); + _receivedAudioStream.setReverb(reverbTime, wetLevel); + } else { + _receivedAudioStream.clearReverb(); + } + + updateLastHeardFromAudioMixer(packet); +} + +void AudioClient::handleAudioDataPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr) { + auto nodeList = DependencyManager::get(); + nodeList->flagTimeForConnectionStep(LimitedNodeList::ConnectionStep::ReceiveFirstAudioPacket); + + if (_audioOutput) { + + if (!_hasReceivedFirstPacket) { + _hasReceivedFirstPacket = true; + + // have the audio scripting interface emit a signal to say we just connected to mixer + emit receivedFirstPacket(); + } + + // Audio output must exist and be correctly set up if we're going to process received audio + _receivedAudioStream.parseData(packet->getData()); + } + + updateLastHeardFromAudioMixer(packet); +} + +void AudioClient::handleSilentAudioFrame(std::unique_ptr packet, HifiSockAddr senderSockAddr) { + updateLastHeardFromAudioMixer(packet); +} + +void AudioClient::handleNoisyMutePacket(std::unique_ptr packet, HifiSockAddr senderSockAddr) { + if (!_muted) { + toggleMute(); + // TODO reimplement on interface side + //AudioScriptingInterface::getInstance().mutedByMixer(); + } +} + +void AudioClient::handleMuteEnvironmentPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr) { + glm::vec3 position; + float radius; + + int headerSize = numBytesForPacketHeaderGivenPacketType(PacketType::MuteEnvironment); + memcpy(&position, packet->getPayload(), sizeof(glm::vec3)); + memcpy(&radius, packet->getPayload() + sizeof(glm::vec3), sizeof(float)); + float distance = glm::distance(DependencyManager::get()->getMyAvatar()->getPosition(), + position); + bool shouldMute = !_muted && (distance < radius); + + if (shouldMute) { + toggleMute(); + // TODO reimplement on interface side + //AudioScriptingInterface::getInstance().environmentMuted(); + } +} + +void AudioClient::updateLastHeardFromAudioMixer(std::unique_ptr& packet) { + // update having heard from the audio-mixer and record the bytes received + SharedNodePointer audioMixer = nodeList->nodeWithUUID(packet->getSourceID()); + if (audioMixer) { + audioMixer->setLastHeardMicrostamp(usecTimestampNow()); + } + +} + QString AudioClient::getDefaultDeviceName(QAudio::Mode mode) { QAudioDeviceInfo deviceInfo = defaultAudioDeviceForMode(mode); return deviceInfo.deviceName(); diff --git a/libraries/audio-client/src/AudioClient.h b/libraries/audio-client/src/AudioClient.h index 484e3a14e8..59b7fc48a9 100644 --- a/libraries/audio-client/src/AudioClient.h +++ b/libraries/audio-client/src/AudioClient.h @@ -133,10 +133,15 @@ public: public slots: void start(); void stop(); - void addReceivedAudioToStream(const QByteArray& audioByteArray); - void parseAudioEnvironmentData(const QByteArray& packet); + + void handleAudioStreamStatsPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr); + void handleAudioEnvironmentDataPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr); + void handleAudioDataPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr); + void handleSilentAudioFrame(std::unique_ptr packet, HifiSockAddr senderSockAddr); + void handleNoisyMutePacket(std::unique_ptr packet, HifiSockAddr senderSockAddr); + void handleMuteEnvironmentPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr); + void sendDownstreamAudioStatsPacket() { _stats.sendDownstreamAudioStatsPacket(); } - void parseAudioStreamStatsPacket(const QByteArray& packet) { _stats.parseAudioStreamStatsPacket(packet); } void handleAudioInput(); void reset(); void audioMixerKilled(); @@ -202,6 +207,7 @@ private slots: void audioStateChanged(QAudio::State state); private: + void updateLastHeardFromAudioMixer(std::unique_ptr& packet); void outputFormatChanged(); QByteArray firstInputFrame;