1 // This file is part of Desktop App Toolkit, 2 // a set of libraries for developing nice desktop applications. 3 // 4 // For license and copyright information please follow this link: 5 // https://github.com/desktop-app/legal/blob/master/LEGAL 6 // 7 #pragma once 8 9 #include "modules/audio_device/include/audio_device.h" 10 #include "modules/audio_device/audio_device_buffer.h" 11 12 #include <crl/crl_time.h> 13 #include <al.h> 14 #include <alc.h> 15 #include <atomic> 16 17 namespace rtc { 18 class Thread; 19 } // namespace rtc 20 21 namespace Webrtc::details { 22 23 class AudioDeviceOpenAL : public webrtc::AudioDeviceModule { 24 public: 25 explicit AudioDeviceOpenAL(webrtc::TaskQueueFactory *taskQueueFactory); 26 ~AudioDeviceOpenAL(); 27 28 int32_t ActiveAudioLayer(AudioLayer *audioLayer) const override; 29 int32_t RegisterAudioCallback( 30 webrtc::AudioTransport *audioCallback) override; 31 32 // Main initializaton and termination 33 int32_t Init() override; 34 int32_t Terminate() override; 35 bool Initialized() const override; 36 37 // Device enumeration 38 int16_t PlayoutDevices() override; 39 int16_t RecordingDevices() override; 40 int32_t PlayoutDeviceName(uint16_t index, 41 char name[webrtc::kAdmMaxDeviceNameSize], 42 char guid[webrtc::kAdmMaxGuidSize]) override; 43 int32_t RecordingDeviceName(uint16_t index, 44 char name[webrtc::kAdmMaxDeviceNameSize], 45 char guid[webrtc::kAdmMaxGuidSize]) override; 46 47 // Device selection 48 int32_t SetPlayoutDevice(uint16_t index) override; 49 int32_t SetPlayoutDevice(WindowsDeviceType device) override; 50 int32_t SetRecordingDevice(uint16_t index) override; 51 int32_t SetRecordingDevice(WindowsDeviceType device) override; 52 53 // Audio transport initialization 54 int32_t PlayoutIsAvailable(bool *available) override; 55 int32_t InitPlayout() override; 56 bool PlayoutIsInitialized() const override; 57 int32_t RecordingIsAvailable(bool *available) override; 58 int32_t InitRecording() override; 59 bool RecordingIsInitialized() const override; 60 61 // Audio transport control 62 int32_t StartPlayout() override; 63 int32_t StopPlayout() override; 64 bool Playing() const override; 65 int32_t StartRecording() override; 66 int32_t StopRecording() override; 67 bool Recording() const override; 68 69 // Audio mixer initialization 70 int32_t InitSpeaker() override; 71 bool SpeakerIsInitialized() const override; 72 int32_t InitMicrophone() override; 73 bool MicrophoneIsInitialized() const override; 74 75 // Speaker volume controls 76 int32_t SpeakerVolumeIsAvailable(bool *available) override; 77 int32_t SetSpeakerVolume(uint32_t volume) override; 78 int32_t SpeakerVolume(uint32_t *volume) const override; 79 int32_t MaxSpeakerVolume(uint32_t *maxVolume) const override; 80 int32_t MinSpeakerVolume(uint32_t *minVolume) const override; 81 82 // Microphone volume controls 83 int32_t MicrophoneVolumeIsAvailable(bool *available) override; 84 int32_t SetMicrophoneVolume(uint32_t volume) override; 85 int32_t MicrophoneVolume(uint32_t *volume) const override; 86 int32_t MaxMicrophoneVolume(uint32_t *maxVolume) const override; 87 int32_t MinMicrophoneVolume(uint32_t *minVolume) const override; 88 89 // Microphone mute control 90 int32_t MicrophoneMuteIsAvailable(bool *available) override; 91 int32_t SetMicrophoneMute(bool enable) override; 92 int32_t MicrophoneMute(bool *enabled) const override; 93 94 // Speaker mute control 95 int32_t SpeakerMuteIsAvailable(bool *available) override; 96 int32_t SetSpeakerMute(bool enable) override; 97 int32_t SpeakerMute(bool *enabled) const override; 98 99 // Stereo support 100 int32_t StereoPlayoutIsAvailable(bool *available) const override; 101 int32_t SetStereoPlayout(bool enable) override; 102 int32_t StereoPlayout(bool *enabled) const override; 103 int32_t StereoRecordingIsAvailable(bool *available) const override; 104 int32_t SetStereoRecording(bool enable) override; 105 int32_t StereoRecording(bool *enabled) const override; 106 107 // Delay information and control 108 int32_t PlayoutDelay(uint16_t *delayMS) const override; 109 110 // Only supported on Android. 111 bool BuiltInAECIsAvailable() const override; 112 bool BuiltInAGCIsAvailable() const override; 113 bool BuiltInNSIsAvailable() const override; 114 115 // Enables the built-in audio effects. Only supported on Android. 116 int32_t EnableBuiltInAEC(bool enable) override; 117 int32_t EnableBuiltInAGC(bool enable) override; 118 int32_t EnableBuiltInNS(bool enable) override; 119 120 private: 121 struct Data; 122 struct ExactQueuedTime { 123 crl::time now = 0; 124 crl::time queued = 0; 125 }; 126 127 template <typename Callback> 128 std::invoke_result_t<Callback> sync(Callback &&callback); 129 130 void openRecordingDevice(); 131 void openPlayoutDevice(); 132 void closeRecordingDevice(); 133 134 // NB! stopPlayingOnThread should be called before this, 135 // to clear the thread local context and event callback. 136 void closePlayoutDevice(); 137 138 int restartPlayout(); 139 int restartRecording(); 140 void restartRecordingQueued(); 141 void restartPlayoutQueued(); 142 bool validateRecordingDeviceId(); 143 bool validatePlayoutDeviceId(); 144 145 void ensureThreadStarted(); 146 void startCaptureOnThread(); 147 void stopCaptureOnThread(); 148 void startPlayingOnThread(); 149 150 // NB! closePlayoutDevice should be called after this, so that next time 151 // we start playing, we set the thread local context and event callback. 152 void stopPlayingOnThread(); 153 154 void processData(); 155 void processRecordingData(); 156 void processPlayoutData(); 157 bool processRecordedPart(bool firstInCycle); 158 159 void clearProcessedBuffers(); 160 bool clearProcessedBuffer(); 161 void unqueueAllBuffers(); 162 163 void handleEvent( 164 ALenum eventType, 165 ALuint object, 166 ALuint param, 167 ALsizei length, 168 const ALchar *message); 169 170 [[nodiscard]] crl::time countExactQueuedMsForLatency( 171 crl::time now, 172 bool playing); 173 [[nodiscard]] crl::time queryRecordingLatencyMs(); 174 175 rtc::Thread *_thread = nullptr; 176 webrtc::AudioDeviceBuffer _audioDeviceBuffer; 177 std::unique_ptr<Data> _data; 178 179 ALCdevice *_playoutDevice = nullptr; 180 ALCcontext *_playoutContext = nullptr; 181 std::string _playoutDeviceId; 182 crl::time _playoutLatency = 0; 183 int _playoutChannels = 2; 184 bool _playoutInitialized = false; 185 bool _playoutFailed = false; 186 187 ALCdevice *_recordingDevice = nullptr; 188 std::string _recordingDeviceId; 189 crl::time _recordingLatency = 0; 190 bool _recordingInitialized = false; 191 bool _recordingFailed = false; 192 193 bool _speakerInitialized = false; 194 bool _microphoneInitialized = false; 195 bool _initialized = false; 196 197 }; 198 199 } // namespace Webrtc::details 200