// // Agent.h // assignment-client/src // // Created by Stephen Birarda on 7/1/13. // Copyright 2013 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #ifndef hifi_Agent_h #define hifi_Agent_h #include #include #include #include #include #include #include #include #include #include #include #include #include "AudioGate.h" #include "MixedAudioStream.h" #include "entities/EntityTreeHeadlessViewer.h" #include "avatars/ScriptableAvatar.h" /**jsdoc * @namespace Agent * * @hifi-assignment-client * * @property {boolean} isAvatar * @property {boolean} isPlayingAvatarSound Read-only. * @property {boolean} isListeningToAudioStream * @property {boolean} isNoiseGateEnabled * @property {number} lastReceivedAudioLoudness Read-only. * @property {Uuid} sessionUUID Read-only. */ class Agent : public ThreadedAssignment { Q_OBJECT Q_PROPERTY(bool isAvatar READ isAvatar WRITE setIsAvatar) Q_PROPERTY(bool isPlayingAvatarSound READ isPlayingAvatarSound) Q_PROPERTY(bool isListeningToAudioStream READ isListeningToAudioStream WRITE setIsListeningToAudioStream) Q_PROPERTY(bool isNoiseGateEnabled READ isNoiseGateEnabled WRITE setIsNoiseGateEnabled) Q_PROPERTY(float lastReceivedAudioLoudness READ getLastReceivedAudioLoudness) Q_PROPERTY(QUuid sessionUUID READ getSessionUUID) public: Agent(ReceivedMessage& message); bool isPlayingAvatarSound() const { return _avatarSound != NULL; } bool isListeningToAudioStream() const { return _isListeningToAudioStream; } void setIsListeningToAudioStream(bool isListeningToAudioStream); bool isNoiseGateEnabled() const { return _isNoiseGateEnabled; } void setIsNoiseGateEnabled(bool isNoiseGateEnabled); float getLastReceivedAudioLoudness() const { return _lastReceivedAudioLoudness; } QUuid getSessionUUID() const; virtual void aboutToFinish() override; public slots: /**jsdoc * @function Agent.run * @deprecated This function is being removed from the API. */ void run() override; /**jsdoc * @function Agent.playAvatarSound * @param {object} avatarSound */ void playAvatarSound(SharedSoundPointer avatarSound); /**jsdoc * @function Agent.setIsAvatar * @param {boolean} isAvatar */ void setIsAvatar(bool isAvatar); /**jsdoc * @function Agent.isAvatar * @returns {boolean} */ bool isAvatar() const { return _isAvatar; } private slots: void requestScript(); void scriptRequestFinished(); void executeScript(); void handleAudioPacket(QSharedPointer message); void handleOctreePacket(QSharedPointer message, SharedNodePointer senderNode); void handleSelectedAudioFormat(QSharedPointer message); void nodeActivated(SharedNodePointer activatedNode); void nodeKilled(SharedNodePointer killedNode); void processAgentAvatar(); void processAgentAvatarAudio(); private: void negotiateAudioFormat(); void selectAudioFormat(const QString& selectedCodecName); void encodeFrameOfZeros(QByteArray& encodedZeros); void computeLoudness(const QByteArray* decodedBuffer, QSharedPointer); ScriptEnginePointer _scriptEngine; EntityEditPacketSender _entityEditSender; EntityTreeHeadlessViewer _entityViewer; MixedAudioStream _receivedAudioStream; float _lastReceivedAudioLoudness; void setAvatarSound(SharedSoundPointer avatarSound) { _avatarSound = avatarSound; } void sendAvatarIdentityPacket(); void queryAvatars(); QString _scriptContents; QTimer* _scriptRequestTimeout { nullptr }; ResourceRequest* _pendingScriptRequest { nullptr }; bool _isListeningToAudioStream = false; SharedSoundPointer _avatarSound; int _numAvatarSoundSentBytes = 0; bool _isAvatar = false; QTimer* _avatarIdentityTimer = nullptr; QTimer* _avatarQueryTimer = nullptr; QHash _outgoingScriptAudioSequenceNumbers; AudioGate _audioGate; bool _audioGateOpen { true }; bool _isNoiseGateEnabled { false }; CodecPluginPointer _codec; QString _selectedCodecName; Encoder* _encoder { nullptr }; QTimer _avatarAudioTimer; bool _flushEncoder { false }; }; #endif // hifi_Agent_h