13 #ifndef hifi_AudioClient_h
14 #define hifi_AudioClient_h
23 #include <QtCore/QtGlobal>
24 #include <QtCore/QByteArray>
25 #include <QtCore/QElapsedTimer>
26 #include <QtCore/QObject>
27 #include <QtCore/QSharedPointer>
28 #include <QtCore/QVector>
29 #include <QtMultimedia/QAudio>
30 #include <QtMultimedia/QAudioFormat>
31 #include <QtMultimedia/QAudioInput>
32 #include <AbstractAudioInterface.h>
33 #include <AudioEffectOptions.h>
34 #include <AudioStreamStats.h>
35 #include <shared/WebRTC.h>
37 #include <DependencyManager.h>
40 #include <MixedProcessedAudioStream.h>
41 #include <RingBufferHistory.h>
42 #include <SettingHandle.h>
45 #include <AudioHRTF.h>
47 #include <AudioInjector.h>
48 #include <AudioReverb.h>
49 #include <AudioLimiter.h>
50 #include <AudioConstants.h>
51 #include <AudioGate.h>
53 #include <shared/RateCounter.h>
55 #include <plugins/CodecPlugin.h>
57 #include "AudioIOStats.h"
58 #include "AudioFileWav.h"
59 #include "HifiAudioDeviceInfo.h"
61 #if defined(WEBRTC_AUDIO)
62 # define WEBRTC_APM_DEBUG_DUMP 0
63 # include <modules/audio_processing/include/audio_processing.h>
64 # include "modules/audio_processing/audio_processing_impl.h"
68 #pragma warning( push )
69 #pragma warning( disable : 4273 )
70 #pragma warning( disable : 4305 )
74 #pragma warning( pop )
77 #if defined (Q_OS_ANDROID)
78 #define VOICE_RECOGNITION "voicerecognition"
79 #define VOICE_COMMUNICATION "voicecommunication"
81 #define SETTING_AEC_KEY "Android/aec"
82 #define DEFAULT_AEC_ENABLED true
92 #define DEFAULT_STARVE_DETECTION_ENABLED true
93 #define DEFAULT_BUFFER_FRAMES 1
95 class AudioClient :
public AbstractAudioInterface,
public Dependency {
99 using LocalInjectorsStream = AudioMixRingBuffer;
101 static const int MIN_BUFFER_FRAMES;
102 static const int MAX_BUFFER_FRAMES;
104 using AudioPositionGetter = std::function<glm::vec3()>;
105 using AudioOrientationGetter = std::function<glm::quat()>;
107 using Mutex = std::mutex;
108 using Lock = std::unique_lock<Mutex>;
110 class AudioOutputIODevice :
public QIODevice {
112 AudioOutputIODevice(LocalInjectorsStream& localInjectorsStream, MixedProcessedAudioStream& receivedAudioStream,
113 AudioClient* audio) :
114 _localInjectorsStream(localInjectorsStream), _receivedAudioStream(receivedAudioStream),
115 _audio(audio), _unfulfilledReads(0) {}
117 void start() { open(QIODevice::ReadOnly | QIODevice::Unbuffered); }
118 qint64 readData(
char* data, qint64 maxSize)
override;
119 qint64 writeData(
const char* data, qint64 maxSize)
override {
return 0; }
120 int getRecentUnfulfilledReads() {
int unfulfilledReads = _unfulfilledReads; _unfulfilledReads = 0;
return unfulfilledReads; }
122 LocalInjectorsStream& _localInjectorsStream;
123 MixedProcessedAudioStream& _receivedAudioStream;
125 int _unfulfilledReads;
129 void negotiateAudioFormat();
130 void selectAudioFormat(
const QString& selectedCodecName);
132 Q_INVOKABLE QString getSelectedAudioFormat()
const {
return _selectedCodecName; }
133 Q_INVOKABLE
bool getNoiseGateOpen()
const {
return _audioGateOpen; }
134 Q_INVOKABLE
float getSilentInboundPPS()
const {
return _silentInbound.rate(); }
135 Q_INVOKABLE
float getAudioInboundPPS()
const {
return _audioInbound.rate(); }
136 Q_INVOKABLE
float getSilentOutboundPPS()
const {
return _silentOutbound.rate(); }
137 Q_INVOKABLE
float getAudioOutboundPPS()
const {
return _audioOutbound.rate(); }
139 const MixedProcessedAudioStream& getReceivedAudioStream()
const {
return _receivedAudioStream; }
140 MixedProcessedAudioStream& getReceivedAudioStream() {
return _receivedAudioStream; }
142 const QAudioFormat& getOutputFormat()
const {
return _outputFormat; }
144 float getLastInputLoudness()
const {
return _lastInputLoudness; }
146 float getTimeSinceLastClip()
const {
return _timeSinceLastClip; }
147 float getAudioAverageInputLoudness()
const {
return _lastInputLoudness; }
149 const AudioIOStats& getStats()
const {
return _stats; }
151 int getOutputBufferSize() {
return _outputBufferSizeFrames.get(); }
153 bool getOutputStarveDetectionEnabled() {
return _outputStarveDetectionEnabled.get(); }
154 void setOutputStarveDetectionEnabled(
bool enabled) { _outputStarveDetectionEnabled.set(enabled); }
156 bool isSimulatingJitter() {
return _gate.isSimulatingJitter(); }
157 void setIsSimulatingJitter(
bool enable) { _gate.setIsSimulatingJitter(enable); }
159 int getGateThreshold() {
return _gate.getThreshold(); }
160 void setGateThreshold(
int threshold) { _gate.setThreshold(threshold); }
162 void setPositionGetter(AudioPositionGetter positionGetter) { _positionGetter = positionGetter; }
163 void setOrientationGetter(AudioOrientationGetter orientationGetter) { _orientationGetter = orientationGetter; }
165 void setIsPlayingBackRecording(
bool isPlayingBackRecording) { _isPlayingBackRecording = isPlayingBackRecording; }
167 Q_INVOKABLE
void setAvatarBoundingBoxParameters(glm::vec3 corner, glm::vec3 scale);
169 bool outputLocalInjector(
const AudioInjectorPointer& injector)
override;
171 HifiAudioDeviceInfo getActiveAudioDevice(QAudio::Mode mode)
const;
172 QList<HifiAudioDeviceInfo> getAudioDevices(QAudio::Mode mode)
const;
174 void enablePeakValues(
bool enable) { _enablePeakValues = enable; }
175 bool peakValuesAvailable()
const;
177 static const float CALLBACK_ACCELERATOR_RATIO;
179 bool getNamedAudioDeviceForModeExists(QAudio::Mode mode,
const QString& deviceName);
181 void setRecording(
bool isRecording) { _isRecording = isRecording; };
182 bool getRecording() {
return _isRecording; };
184 bool startRecording(
const QString& filename);
185 void stopRecording();
186 void setAudioPaused(
bool pause);
188 AudioSolo& getAudioSolo()
override {
return _solo; }
191 static QString getWinDeviceName(
wchar_t* guid);
194 #if defined(Q_OS_ANDROID)
195 bool isHeadsetPluggedIn() {
return _isHeadsetPluggedIn; }
198 int getNumLocalInjectors();
204 void handleAudioEnvironmentDataPacket(QSharedPointer<ReceivedMessage> message);
205 void handleAudioDataPacket(QSharedPointer<ReceivedMessage> message);
206 void handleNoisyMutePacket(QSharedPointer<ReceivedMessage> message);
207 void handleMuteEnvironmentPacket(QSharedPointer<ReceivedMessage> message);
208 void handleSelectedAudioFormat(QSharedPointer<ReceivedMessage> message);
209 void handleMismatchAudioFormat(SharedNodePointer node,
const QString& currentCodec,
const QString& recievedCodec);
211 void sendDownstreamAudioStatsPacket() { _stats.publish(); }
212 void handleMicAudioInput();
213 void audioInputStateChanged(QAudio::State state);
214 void checkInputTimeout();
215 void handleDummyAudioInput();
216 void handleRecordedAudioInput(
const QByteArray& audio);
218 void audioMixerKilled();
220 void setMuted(
bool muted,
bool emitSignal =
true);
221 bool isMuted() {
return _isMuted; }
223 virtual bool setIsStereoInput(
bool stereo)
override;
224 virtual bool isStereoInput()
override {
return _isStereoInput; }
226 void setNoiseReduction(
bool isNoiseGateEnabled,
bool emitSignal =
true);
227 bool isNoiseReductionEnabled()
const {
return _isNoiseGateEnabled; }
229 void setNoiseReductionAutomatic(
bool isNoiseGateAutomatic,
bool emitSignal =
true);
230 bool isNoiseReductionAutomatic()
const {
return _isNoiseReductionAutomatic; }
232 void setNoiseReductionThreshold(
float noiseReductionThreshold,
bool emitSignal =
true);
233 float noiseReductionThreshold()
const {
return _noiseReductionThreshold; }
235 void setWarnWhenMuted(
bool isNoiseGateEnabled,
bool emitSignal =
true);
236 bool isWarnWhenMutedEnabled()
const {
return _warnWhenMuted; }
238 void setAcousticEchoCancellation(
bool isAECEnabled,
bool emitSignal =
true);
239 bool isAcousticEchoCancellationEnabled()
const {
return _isAECEnabled; }
241 virtual bool getLocalEcho()
override {
return _shouldEchoLocally; }
242 virtual void setLocalEcho(
bool localEcho)
override { _shouldEchoLocally = localEcho; }
243 virtual void toggleLocalEcho()
override { _shouldEchoLocally = !_shouldEchoLocally; }
245 virtual bool getServerEcho()
override {
return _shouldEchoToServer; }
246 virtual void setServerEcho(
bool serverEcho)
override { _shouldEchoToServer = serverEcho; }
247 virtual void toggleServerEcho()
override { _shouldEchoToServer = !_shouldEchoToServer; }
249 void processReceivedSamples(
const QByteArray& inputBuffer, QByteArray& outputBuffer);
250 void sendMuteEnvironmentPacket();
252 int setOutputBufferSize(
int numFrames,
bool persist =
true);
254 bool shouldLoopbackInjectors()
override {
return _shouldEchoToServer; }
257 bool switchAudioDevice(QAudio::Mode mode,
const HifiAudioDeviceInfo& deviceInfo = HifiAudioDeviceInfo());
258 bool switchAudioDevice(QAudio::Mode mode,
const QString& deviceName,
bool isHmd);
259 void setHmdAudioName(QAudio::Mode mode,
const QString& name);
261 void setHeadsetPluggedIn(
bool pluggedIn);
263 float getInputVolume()
const {
return (_audioInput) ? (float)_audioInput->volume() : 0.0f; }
264 void setInputVolume(
float volume,
bool emitSignal =
true);
265 void setReverb(
bool reverb);
266 void setReverbOptions(
const AudioEffectOptions* options);
268 void setLocalInjectorGain(
float gain) { _localInjectorGain = gain; };
269 void setSystemInjectorGain(
float gain) { _systemInjectorGain = gain; };
270 void setOutputGain(
float gain) { _outputGain = gain; };
273 void noteAwakening();
279 void inputVolumeChanged(
float volume);
280 void muteToggled(
bool muted);
281 void noiseReductionChanged(
bool noiseReductionEnabled);
282 void noiseReductionAutomaticChanged(
bool noiseReductionAutomatic);
283 void noiseReductionThresholdChanged(
bool noiseReductionThreshold);
284 void warnWhenMutedChanged(
bool warnWhenMutedEnabled);
285 void acousticEchoCancellationChanged(
bool acousticEchoCancellationEnabled);
287 void inputReceived(
const QByteArray& inputSamples);
288 void inputLoudnessChanged(
float loudness,
bool isClipping);
289 void outputBytesToNetwork(
int numBytes);
290 void inputBytesFromNetwork(
int numBytes);
291 void noiseGateOpened();
292 void noiseGateClosed();
294 void changeDevice(
const HifiAudioDeviceInfo& outputDeviceInfo);
296 void deviceChanged(QAudio::Mode mode,
const HifiAudioDeviceInfo& device);
297 void devicesChanged(QAudio::Mode mode,
const QList<HifiAudioDeviceInfo>& devices);
298 void peakValueListChanged(
const QList<float> peakValueList);
300 void receivedFirstPacket();
303 void audioFinished();
305 void muteEnvironmentRequested(glm::vec3 position,
float radius);
307 void outputBufferReceived(
const QByteArray _outputBuffer);
313 virtual void customDeleter()
override;
316 static const int RECEIVED_AUDIO_STREAM_CAPACITY_FRAMES{ 100 };
319 static const int OUTPUT_CHANNEL_COUNT{ 2 };
320 static const int STARVE_DETECTION_THRESHOLD{ 3 };
321 static const int STARVE_DETECTION_PERIOD{ 10 * 1000 };
323 static const AudioPositionGetter DEFAULT_POSITION_GETTER;
324 static const AudioOrientationGetter DEFAULT_ORIENTATION_GETTER;
326 friend class CheckDevicesThread;
327 friend class LocalInjectorsThread;
329 float loudnessToLevel(
float loudness);
333 void checkPeakValues();
335 void outputFormatChanged();
336 void handleAudioInput(QByteArray& audioBuffer);
337 void prepareLocalAudioInjectors(std::unique_ptr<Lock> localAudioLock =
nullptr);
338 bool mixLocalAudioInjectors(
float* mixBuffer);
339 float azimuthForSource(
const glm::vec3& relativePosition);
340 float gainForSource(
float distance,
float volume);
343 QTimer _checkInputTimer{
this };
344 long _inputReadsSinceLastCheck = 0l;
345 bool _isHeadsetPluggedIn {
false };
350 Gate(AudioClient* audioClient);
352 bool isSimulatingJitter() {
return _isSimulatingJitter; }
353 void setIsSimulatingJitter(
bool enable);
355 int getThreshold() {
return _threshold; }
356 void setThreshold(
int threshold);
358 void insert(QSharedPointer<ReceivedMessage> message);
363 AudioClient* _audioClient;
364 std::queue<QSharedPointer<ReceivedMessage>> _queue;
369 bool _isSimulatingJitter{
false };
374 Mutex _injectorsMutex;
375 QAudioInput* _audioInput{
nullptr };
376 QTimer* _dummyAudioInput{
nullptr };
377 QAudioFormat _desiredInputFormat;
378 QAudioFormat _inputFormat;
379 QIODevice* _inputDevice{
nullptr };
380 int _numInputCallbackBytes{ 0 };
381 QAudioOutput* _audioOutput{
nullptr };
382 std::atomic<bool> _audioOutputInitialized {
false };
383 QAudioFormat _desiredOutputFormat;
384 QAudioFormat _outputFormat;
385 int _outputFrameSize{ 0 };
386 int _numOutputCallbackBytes{ 0 };
387 QAudioOutput* _loopbackAudioOutput{
nullptr };
388 QIODevice* _loopbackOutputDevice{
nullptr };
389 AudioRingBuffer _inputRingBuffer{ 0 };
390 LocalInjectorsStream _localInjectorsStream{ 0 , 1 };
393 std::atomic<int> _localSamplesAvailable { 0 };
394 std::atomic<bool> _localInjectorsAvailable {
false };
395 MixedProcessedAudioStream _receivedAudioStream{ RECEIVED_AUDIO_STREAM_CAPACITY_FRAMES };
396 bool _isStereoInput{
false };
397 std::atomic<bool> _enablePeakValues {
false };
399 quint64 _outputStarveDetectionStartTimeMsec{ 0 };
400 int _outputStarveDetectionCount { 0 };
403 int _sessionOutputBufferSizeFrames{ _outputBufferSizeFrames.
get() };
404 Setting::Handle<bool> _outputStarveDetectionEnabled{
"audioOutputStarveDetectionEnabled", DEFAULT_STARVE_DETECTION_ENABLED};
407 QElapsedTimer _timeSinceLastReceived;
408 float _lastRawInputLoudness{ 0.0f };
409 float _lastSmoothedRawInputLoudness{ 0.0f };
410 float _lastInputLoudness{ 0.0f };
411 float _timeSinceLastClip{ -1.0f };
412 int _totalInputAudioSamples;
414 bool _isMuted{
false };
415 bool _shouldEchoLocally{
false };
416 bool _shouldEchoToServer{
false };
417 bool _isNoiseGateEnabled{
true };
418 bool _isNoiseReductionAutomatic{
true };
419 float _noiseReductionThreshold{ 0.1f };
421 bool _isAECEnabled{
true };
423 bool _reverb{
false };
424 AudioEffectOptions _scriptReverbOptions;
425 AudioEffectOptions _zoneReverbOptions;
426 AudioEffectOptions* _reverbOptions{ &_scriptReverbOptions };
427 AudioReverb _sourceReverb { AudioConstants::SAMPLE_RATE };
428 AudioReverb _listenerReverb { AudioConstants::SAMPLE_RATE };
429 AudioReverb _localReverb { AudioConstants::SAMPLE_RATE };
432 AudioSRC* _inputToNetworkResampler{
nullptr };
433 AudioSRC* _networkToOutputResampler{
nullptr };
434 AudioSRC* _localToOutputResampler{
nullptr };
435 AudioSRC* _loopbackResampler{
nullptr };
438 int16_t _networkScratchBuffer[AudioConstants::NETWORK_FRAME_SAMPLES_AMBISONIC];
441 int _outputPeriod { 0 };
442 float* _outputMixBuffer { NULL };
443 int16_t* _outputScratchBuffer { NULL };
444 std::atomic<float> _outputGain { 1.0f };
445 float _lastOutputGain { 1.0f };
448 std::atomic<float> _localInjectorGain { 1.0f };
449 std::atomic<float> _systemInjectorGain { 1.0f };
450 float _localMixBuffer[AudioConstants::NETWORK_FRAME_SAMPLES_STEREO];
451 int16_t _localScratchBuffer[AudioConstants::NETWORK_FRAME_SAMPLES_AMBISONIC];
452 float* _localOutputMixBuffer { NULL };
453 Mutex _localAudioMutex;
454 AudioLimiter _audioLimiter{ AudioConstants::SAMPLE_RATE, OUTPUT_CHANNEL_COUNT };
457 void configureReverb();
458 void updateReverbOptions();
459 void handleLocalEchoAndReverb(QByteArray& inputByteArray);
461 #if defined(WEBRTC_AUDIO)
462 static const int WEBRTC_SAMPLE_RATE_MAX = 96000;
463 static const int WEBRTC_CHANNELS_MAX = 2;
464 static const int WEBRTC_FRAMES_MAX = webrtc::AudioProcessing::kChunkSizeMs * WEBRTC_SAMPLE_RATE_MAX / 1000;
466 webrtc::AudioProcessing* _apm {
nullptr };
468 int16_t _fifoFarEnd[WEBRTC_CHANNELS_MAX * WEBRTC_FRAMES_MAX] {};
469 int _numFifoFarEnd = 0;
471 void configureWebrtc();
472 void processWebrtcFarEnd(
const int16_t* samples,
int numFrames,
int numChannels,
int sampleRate);
473 void processWebrtcNearEnd(int16_t* samples,
int numFrames,
int numChannels,
int sampleRate);
476 bool switchInputToAudioDevice(
const HifiAudioDeviceInfo inputDeviceInfo,
bool isShutdownRequest =
false);
477 bool switchOutputToAudioDevice(
const HifiAudioDeviceInfo outputDeviceInfo,
bool isShutdownRequest =
false);
480 int calculateNumberOfInputCallbackBytes(
const QAudioFormat& format)
const;
481 int calculateNumberOfFrameSamples(
int numBytes)
const;
483 quint16 _outgoingAvatarAudioSequenceNumber{ 0 };
485 AudioOutputIODevice _audioOutputIODevice{ _localInjectorsStream, _receivedAudioStream,
this };
487 AudioIOStats _stats{ &_receivedAudioStream };
489 AudioGate* _audioGate {
nullptr };
490 bool _audioGateOpen {
true };
492 AudioPositionGetter _positionGetter{ DEFAULT_POSITION_GETTER };
493 AudioOrientationGetter _orientationGetter{ DEFAULT_ORIENTATION_GETTER };
495 glm::vec3 avatarBoundingBoxCorner;
496 glm::vec3 avatarBoundingBoxScale;
498 HifiAudioDeviceInfo _inputDeviceInfo;
499 HifiAudioDeviceInfo _outputDeviceInfo;
501 QList<HifiAudioDeviceInfo> _inputDevices;
502 QList<HifiAudioDeviceInfo> _outputDevices;
504 QString _hmdInputName { QString() };
505 QString _hmdOutputName{ QString() };
507 AudioFileWav _audioFileWav;
509 bool _hasReceivedFirstPacket {
false };
511 QVector<AudioInjectorPointer> _activeLocalAudioInjectors;
513 bool _isPlayingBackRecording {
false };
514 bool _audioPaused {
false };
516 CodecPluginPointer _codec;
517 QString _selectedCodecName;
518 Encoder* _encoder {
nullptr };
520 RateCounter<> _silentOutbound;
521 RateCounter<> _audioOutbound;
522 RateCounter<> _silentInbound;
523 RateCounter<> _audioInbound;
525 #if defined(Q_OS_ANDROID)
526 bool _shouldRestartInputSetup {
true };
531 QFuture<void> _localPrepInjectorFuture;
532 QReadWriteLock _hmdNameLock;
533 Mutex _checkDevicesMutex;
534 QTimer* _checkDevicesTimer {
nullptr };
535 Mutex _checkPeakValuesMutex;
536 QTimer* _checkPeakValuesTimer {
nullptr };
538 bool _isRecording {
false };
T get() const
Returns the value of the setting, or the default value if not found.
Definition: SettingHandle.h:240