1 /* 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #ifndef AUDIO_DEVICE_AUDIO_DEVICE_ALSA_LINUX_H_ 12 #define AUDIO_DEVICE_AUDIO_DEVICE_ALSA_LINUX_H_ 13 14 #include <memory> 15 16 #include "modules/audio_device/audio_device_generic.h" 17 #include "modules/audio_device/linux/audio_mixer_manager_alsa_linux.h" 18 #include "rtc_base/platform_thread.h" 19 #include "rtc_base/synchronization/mutex.h" 20 21 #if defined(WEBRTC_USE_X11) 22 #include <X11/Xlib.h> 23 #endif 24 #include <alsa/asoundlib.h> 25 #include <sys/ioctl.h> 26 #include <sys/soundcard.h> 27 28 typedef webrtc::adm_linux_alsa::AlsaSymbolTable WebRTCAlsaSymbolTable; 29 WebRTCAlsaSymbolTable* GetAlsaSymbolTable(); 30 31 namespace webrtc { 32 33 class AudioDeviceLinuxALSA : public AudioDeviceGeneric { 34 public: 35 AudioDeviceLinuxALSA(); 36 virtual ~AudioDeviceLinuxALSA(); 37 38 // Retrieve the currently utilized audio layer 39 int32_t ActiveAudioLayer( 40 AudioDeviceModule::AudioLayer& audioLayer) const override; 41 42 // Main initializaton and termination 43 InitStatus Init() RTC_LOCKS_EXCLUDED(mutex_) override; 44 int32_t Terminate() RTC_LOCKS_EXCLUDED(mutex_) override; 45 bool Initialized() const override; 46 47 // Device enumeration 48 int16_t PlayoutDevices() override; 49 int16_t RecordingDevices() override; 50 int32_t PlayoutDeviceName(uint16_t index, 51 char name[kAdmMaxDeviceNameSize], 52 char guid[kAdmMaxGuidSize]) override; 53 int32_t RecordingDeviceName(uint16_t index, 54 char name[kAdmMaxDeviceNameSize], 55 char guid[kAdmMaxGuidSize]) override; 56 57 // Device selection 58 int32_t SetPlayoutDevice(uint16_t index) override; 59 int32_t SetPlayoutDevice( 60 AudioDeviceModule::WindowsDeviceType device) override; 61 int32_t SetRecordingDevice(uint16_t index) override; 62 int32_t SetRecordingDevice( 63 AudioDeviceModule::WindowsDeviceType device) override; 64 65 // Audio transport initialization 66 int32_t PlayoutIsAvailable(bool& available) override; 67 int32_t InitPlayout() RTC_LOCKS_EXCLUDED(mutex_) override; 68 bool PlayoutIsInitialized() const override; 69 int32_t RecordingIsAvailable(bool& available) override; 70 int32_t InitRecording() RTC_LOCKS_EXCLUDED(mutex_) override; 71 bool RecordingIsInitialized() const override; 72 73 // Audio transport control 74 int32_t StartPlayout() override; 75 int32_t StopPlayout() RTC_LOCKS_EXCLUDED(mutex_) override; 76 bool Playing() const override; 77 int32_t StartRecording() override; 78 int32_t StopRecording() RTC_LOCKS_EXCLUDED(mutex_) override; 79 bool Recording() const override; 80 81 // Audio mixer initialization 82 int32_t InitSpeaker() RTC_LOCKS_EXCLUDED(mutex_) override; 83 bool SpeakerIsInitialized() const override; 84 int32_t InitMicrophone() RTC_LOCKS_EXCLUDED(mutex_) override; 85 bool MicrophoneIsInitialized() const override; 86 87 // Speaker volume controls 88 int32_t SpeakerVolumeIsAvailable(bool& available) override; 89 int32_t SetSpeakerVolume(uint32_t volume) override; 90 int32_t SpeakerVolume(uint32_t& volume) const override; 91 int32_t MaxSpeakerVolume(uint32_t& maxVolume) const override; 92 int32_t MinSpeakerVolume(uint32_t& minVolume) const override; 93 94 // Microphone volume controls 95 int32_t MicrophoneVolumeIsAvailable(bool& available) override; 96 int32_t SetMicrophoneVolume(uint32_t volume) override; 97 int32_t MicrophoneVolume(uint32_t& volume) const override; 98 int32_t MaxMicrophoneVolume(uint32_t& maxVolume) const override; 99 int32_t MinMicrophoneVolume(uint32_t& minVolume) const override; 100 101 // Speaker mute control 102 int32_t SpeakerMuteIsAvailable(bool& available) override; 103 int32_t SetSpeakerMute(bool enable) override; 104 int32_t SpeakerMute(bool& enabled) const override; 105 106 // Microphone mute control 107 int32_t MicrophoneMuteIsAvailable(bool& available) override; 108 int32_t SetMicrophoneMute(bool enable) override; 109 int32_t MicrophoneMute(bool& enabled) const override; 110 111 // Stereo support 112 int32_t StereoPlayoutIsAvailable(bool& available) 113 RTC_LOCKS_EXCLUDED(mutex_) override; 114 int32_t SetStereoPlayout(bool enable) override; 115 int32_t StereoPlayout(bool& enabled) const override; 116 int32_t StereoRecordingIsAvailable(bool& available) 117 RTC_LOCKS_EXCLUDED(mutex_) override; 118 int32_t SetStereoRecording(bool enable) override; 119 int32_t StereoRecording(bool& enabled) const override; 120 121 // Delay information and control 122 int32_t PlayoutDelay(uint16_t& delayMS) const override; 123 124 void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer) 125 RTC_LOCKS_EXCLUDED(mutex_) override; 126 127 private: 128 int32_t InitRecordingLocked() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); 129 int32_t StopRecordingLocked() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); 130 int32_t StopPlayoutLocked() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); 131 int32_t InitPlayoutLocked() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); 132 int32_t InitSpeakerLocked() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); 133 int32_t InitMicrophoneLocked() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); 134 int32_t GetDevicesInfo(const int32_t function, 135 const bool playback, 136 const int32_t enumDeviceNo = 0, 137 char* enumDeviceName = NULL, 138 const int32_t ednLen = 0) const; 139 int32_t ErrorRecovery(int32_t error, snd_pcm_t* deviceHandle); 140 141 bool KeyPressed() const; 142 Lock()143 void Lock() RTC_EXCLUSIVE_LOCK_FUNCTION(mutex_) { mutex_.Lock(); } UnLock()144 void UnLock() RTC_UNLOCK_FUNCTION(mutex_) { mutex_.Unlock(); } 145 146 inline int32_t InputSanityCheckAfterUnlockedPeriod() const; 147 inline int32_t OutputSanityCheckAfterUnlockedPeriod() const; 148 149 static void RecThreadFunc(void*); 150 static void PlayThreadFunc(void*); 151 bool RecThreadProcess(); 152 bool PlayThreadProcess(); 153 154 AudioDeviceBuffer* _ptrAudioBuffer; 155 156 Mutex mutex_; 157 158 // TODO(pbos): Make plain members and start/stop instead of resetting these 159 // pointers. A thread can be reused. 160 std::unique_ptr<rtc::PlatformThread> _ptrThreadRec; 161 std::unique_ptr<rtc::PlatformThread> _ptrThreadPlay; 162 163 AudioMixerManagerLinuxALSA _mixerManager; 164 165 uint16_t _inputDeviceIndex; 166 uint16_t _outputDeviceIndex; 167 bool _inputDeviceIsSpecified; 168 bool _outputDeviceIsSpecified; 169 170 snd_pcm_t* _handleRecord; 171 snd_pcm_t* _handlePlayout; 172 173 snd_pcm_uframes_t _recordingBuffersizeInFrame; 174 snd_pcm_uframes_t _recordingPeriodSizeInFrame; 175 snd_pcm_uframes_t _playoutBufferSizeInFrame; 176 snd_pcm_uframes_t _playoutPeriodSizeInFrame; 177 178 ssize_t _recordingBufferSizeIn10MS; 179 ssize_t _playoutBufferSizeIn10MS; 180 uint32_t _recordingFramesIn10MS; 181 uint32_t _playoutFramesIn10MS; 182 183 uint32_t _recordingFreq; 184 uint32_t _playoutFreq; 185 uint8_t _recChannels; 186 uint8_t _playChannels; 187 188 int8_t* _recordingBuffer; // in byte 189 int8_t* _playoutBuffer; // in byte 190 uint32_t _recordingFramesLeft; 191 uint32_t _playoutFramesLeft; 192 193 bool _initialized; 194 bool _recording; 195 bool _playing; 196 bool _recIsInitialized; 197 bool _playIsInitialized; 198 199 snd_pcm_sframes_t _recordingDelay; 200 snd_pcm_sframes_t _playoutDelay; 201 202 char _oldKeyState[32]; 203 #if defined(WEBRTC_USE_X11) 204 Display* _XDisplay; 205 #endif 206 }; 207 208 } // namespace webrtc 209 210 #endif // MODULES_AUDIO_DEVICE_MAIN_SOURCE_LINUX_AUDIO_DEVICE_ALSA_LINUX_H_ 211