Overte C++ Documentation
AudioInjector.h
1 //
2 // AudioInjector.h
3 // libraries/audio/src
4 //
5 // Created by Stephen Birarda on 1/2/2014.
6 // Copyright 2014 High Fidelity, Inc.
7 //
8 // Distributed under the Apache License, Version 2.0.
9 // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
10 //
11 
12 #ifndef hifi_AudioInjector_h
13 #define hifi_AudioInjector_h
14 
15 #include <memory>
16 
17 #include <QtCore/QElapsedTimer>
18 #include <QtCore/QObject>
19 #include <QtCore/QSharedPointer>
20 #include <QtCore/QThread>
21 
22 #include <shared/ReadWriteLockable.h>
23 
24 #include <glm/glm.hpp>
25 #include <glm/gtx/quaternion.hpp>
26 
27 #include <NLPacket.h>
28 
29 #include "AudioInjectorLocalBuffer.h"
30 #include "AudioInjectorOptions.h"
31 #include "AudioHRTF.h"
32 #include "AudioFOA.h"
33 #include "Sound.h"
34 
35 class AbstractAudioInterface;
36 class AudioInjectorManager;
37 class AudioInjector;
38 using AudioInjectorPointer = QSharedPointer<AudioInjector>;
39 
40 
41 enum class AudioInjectorState : uint8_t {
42  NotFinished = 0,
43  Finished = 1,
44  PendingDelete = 2,
45  LocalInjectionFinished = 4,
46  NetworkInjectionFinished = 8
47 };
48 
49 AudioInjectorState operator& (AudioInjectorState lhs, AudioInjectorState rhs);
50 AudioInjectorState& operator|= (AudioInjectorState& lhs, AudioInjectorState rhs);
51 
52 // In order to make scripting cleaner for the AudioInjector, the script now holds on to the AudioInjector object
53 // until it dies.
54 class AudioInjector : public QObject, public QEnableSharedFromThis<AudioInjector>, public ReadWriteLockable {
55  Q_OBJECT
56 public:
57  AudioInjector(SharedSoundPointer sound, const AudioInjectorOptions& injectorOptions);
58  AudioInjector(AudioDataPointer audioData, const AudioInjectorOptions& injectorOptions);
59  ~AudioInjector();
60 
61  bool isFinished() const { return (stateHas(AudioInjectorState::Finished)); }
62 
63  int getCurrentSendOffset() const { return _currentSendOffset; }
64  void setCurrentSendOffset(int currentSendOffset) { _currentSendOffset = currentSendOffset; }
65 
66  QSharedPointer<AudioInjectorLocalBuffer> getLocalBuffer() const { return _localBuffer; }
67  AudioHRTF& getLocalHRTF() { return _localHRTF; }
68  AudioFOA& getLocalFOA() { return _localFOA; }
69 
70  float getLoudness() const { return resultWithReadLock<float>([&] { return _loudness; }); }
71  bool isPlaying() const { return !stateHas(AudioInjectorState::Finished); }
72 
73  bool isLocalOnly() const { return resultWithReadLock<bool>([&] { return _options.localOnly; }); }
74  float getVolume() const { return resultWithReadLock<float>([&] { return _options.volume; }); }
75  bool isPositionSet() const { return resultWithReadLock<bool>([&] { return _options.positionSet; }); }
76  glm::vec3 getPosition() const { return resultWithReadLock<glm::vec3>([&] { return _options.position; }); }
77  glm::quat getOrientation() const { return resultWithReadLock<glm::quat>([&] { return _options.orientation; }); }
78  bool isStereo() const { return resultWithReadLock<bool>([&] { return _options.stereo; }); }
79  bool isAmbisonic() const { return resultWithReadLock<bool>([&] { return _options.ambisonic; }); }
80 
81  AudioInjectorOptions getOptions() const { return resultWithReadLock<AudioInjectorOptions>([&] { return _options; }); }
82  void setOptions(const AudioInjectorOptions& options);
83 
84  bool stateHas(AudioInjectorState state) const ;
85  static void setLocalAudioInterface(AbstractAudioInterface* audioInterface) { _localAudioInterface = audioInterface; }
86 
87  void restart();
88  void finish();
89 
90  void finishNetworkInjection();
91 
92 public slots:
93  void finishLocalInjection();
94 
95 signals:
96  void finished();
97  void restarting();
98 
99 private:
100  int64_t injectNextFrame();
101  bool inject(bool(AudioInjectorManager::*injection)(const AudioInjectorPointer&));
102  bool injectLocally();
103  void sendStopInjectorPacket();
104 
105  static AbstractAudioInterface* _localAudioInterface;
106 
107  const SharedSoundPointer _sound;
108  AudioDataPointer _audioData;
109  AudioInjectorOptions _options;
110  AudioInjectorState _state { AudioInjectorState::NotFinished };
111  bool _hasSentFirstFrame { false };
112  float _loudness { 0.0f };
113  int _currentSendOffset { 0 };
114  std::unique_ptr<NLPacket> _currentPacket { nullptr };
115  QSharedPointer<AudioInjectorLocalBuffer> _localBuffer { nullptr };
116 
117  int64_t _nextFrame { 0 };
118  std::unique_ptr<QElapsedTimer> _frameTimer { nullptr };
119  quint16 _outgoingSequenceNumber { 0 };
120 
121  // when the injector is local, we need this
122  AudioHRTF _localHRTF;
123  AudioFOA _localFOA;
124 
125  QUuid _streamID { QUuid::createUuid() };
126 
127  friend class AudioInjectorManager;
128 };
129 
130 Q_DECLARE_METATYPE(AudioInjectorPointer)
131 
132 #endif // hifi_AudioInjector_h