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/criticalsection.h"
19 #include "rtc_base/platform_thread.h"
20 
21 #if defined(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 
29 namespace webrtc
30 {
31 class EventWrapper;
32 
33 class AudioDeviceLinuxALSA : public AudioDeviceGeneric
34 {
35 public:
36     AudioDeviceLinuxALSA();
37     virtual ~AudioDeviceLinuxALSA();
38 
39     // Retrieve the currently utilized audio layer
40     int32_t ActiveAudioLayer(
41         AudioDeviceModule::AudioLayer& audioLayer) const override;
42 
43     // Main initializaton and termination
44     InitStatus Init() override;
45     int32_t Terminate() override;
46     bool Initialized() const override;
47 
48     // Device enumeration
49     int16_t PlayoutDevices() override;
50     int16_t RecordingDevices() override;
51     int32_t PlayoutDeviceName(uint16_t index,
52                               char name[kAdmMaxDeviceNameSize],
53                               char guid[kAdmMaxGuidSize]) override;
54     int32_t RecordingDeviceName(uint16_t index,
55                                 char name[kAdmMaxDeviceNameSize],
56                                 char guid[kAdmMaxGuidSize]) override;
57 
58     // Device selection
59     int32_t SetPlayoutDevice(uint16_t index) override;
60     int32_t SetPlayoutDevice(
61         AudioDeviceModule::WindowsDeviceType device) override;
62     int32_t SetRecordingDevice(uint16_t index) override;
63     int32_t SetRecordingDevice(
64         AudioDeviceModule::WindowsDeviceType device) override;
65 
66     // Audio transport initialization
67     int32_t PlayoutIsAvailable(bool& available) override;
68     int32_t InitPlayout() override;
69     bool PlayoutIsInitialized() const override;
70     int32_t RecordingIsAvailable(bool& available) override;
71     int32_t InitRecording() override;
72     bool RecordingIsInitialized() const override;
73 
74     // Audio transport control
75     int32_t StartPlayout() override;
76     int32_t StopPlayout() override;
77     bool Playing() const override;
78     int32_t StartRecording() override;
79     int32_t StopRecording() override;
80     bool Recording() const override;
81 
82     // Microphone Automatic Gain Control (AGC)
83     int32_t SetAGC(bool enable) override;
84     bool AGC() const override;
85 
86     // Audio mixer initialization
87     int32_t InitSpeaker() override;
88     bool SpeakerIsInitialized() const override;
89     int32_t InitMicrophone() override;
90     bool MicrophoneIsInitialized() const override;
91 
92     // Speaker volume controls
93     int32_t SpeakerVolumeIsAvailable(bool& available) override;
94     int32_t SetSpeakerVolume(uint32_t volume) override;
95     int32_t SpeakerVolume(uint32_t& volume) const override;
96     int32_t MaxSpeakerVolume(uint32_t& maxVolume) const override;
97     int32_t MinSpeakerVolume(uint32_t& minVolume) const override;
98 
99     // Microphone volume controls
100     int32_t MicrophoneVolumeIsAvailable(bool& available) override;
101     int32_t SetMicrophoneVolume(uint32_t volume) override;
102     int32_t MicrophoneVolume(uint32_t& volume) const override;
103     int32_t MaxMicrophoneVolume(uint32_t& maxVolume) const override;
104     int32_t MinMicrophoneVolume(uint32_t& minVolume) const override;
105 
106     // Speaker mute control
107     int32_t SpeakerMuteIsAvailable(bool& available) override;
108     int32_t SetSpeakerMute(bool enable) override;
109     int32_t SpeakerMute(bool& enabled) const override;
110 
111     // Microphone mute control
112     int32_t MicrophoneMuteIsAvailable(bool& available) override;
113     int32_t SetMicrophoneMute(bool enable) override;
114     int32_t MicrophoneMute(bool& enabled) const override;
115 
116     // Stereo support
117     int32_t StereoPlayoutIsAvailable(bool& available) override;
118     int32_t SetStereoPlayout(bool enable) override;
119     int32_t StereoPlayout(bool& enabled) const override;
120     int32_t StereoRecordingIsAvailable(bool& available) override;
121     int32_t SetStereoRecording(bool enable) override;
122     int32_t StereoRecording(bool& enabled) const override;
123 
124     // Delay information and control
125     int32_t PlayoutDelay(uint16_t& delayMS) const override;
126 
127     void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer) override;
128 
129 private:
130     int32_t GetDevicesInfo(const int32_t function,
131                            const bool playback,
132                            const int32_t enumDeviceNo = 0,
133                            char* enumDeviceName = NULL,
134                            const int32_t ednLen = 0) const;
135     int32_t ErrorRecovery(int32_t error, snd_pcm_t* deviceHandle);
136 
137     bool KeyPressed() const;
138 
Lock()139     void Lock() RTC_EXCLUSIVE_LOCK_FUNCTION(_critSect) { _critSect.Enter(); };
UnLock()140     void UnLock() RTC_UNLOCK_FUNCTION(_critSect) { _critSect.Leave(); };
141 
142     inline int32_t InputSanityCheckAfterUnlockedPeriod() const;
143     inline int32_t OutputSanityCheckAfterUnlockedPeriod() const;
144 
145     static bool RecThreadFunc(void*);
146     static bool PlayThreadFunc(void*);
147     bool RecThreadProcess();
148     bool PlayThreadProcess();
149 
150     AudioDeviceBuffer* _ptrAudioBuffer;
151 
152     rtc::CriticalSection _critSect;
153 
154     // TODO(pbos): Make plain members and start/stop instead of resetting these
155     // pointers. A thread can be reused.
156     std::unique_ptr<rtc::PlatformThread> _ptrThreadRec;
157     std::unique_ptr<rtc::PlatformThread> _ptrThreadPlay;
158 
159     AudioMixerManagerLinuxALSA _mixerManager;
160 
161     uint16_t _inputDeviceIndex;
162     uint16_t _outputDeviceIndex;
163     bool _inputDeviceIsSpecified;
164     bool _outputDeviceIsSpecified;
165 
166     snd_pcm_t* _handleRecord;
167     snd_pcm_t* _handlePlayout;
168 
169     snd_pcm_uframes_t _recordingBuffersizeInFrame;
170     snd_pcm_uframes_t _recordingPeriodSizeInFrame;
171     snd_pcm_uframes_t _playoutBufferSizeInFrame;
172     snd_pcm_uframes_t _playoutPeriodSizeInFrame;
173 
174     ssize_t _recordingBufferSizeIn10MS;
175     ssize_t _playoutBufferSizeIn10MS;
176     uint32_t _recordingFramesIn10MS;
177     uint32_t _playoutFramesIn10MS;
178 
179     uint32_t _recordingFreq;
180     uint32_t _playoutFreq;
181     uint8_t _recChannels;
182     uint8_t _playChannels;
183 
184     int8_t* _recordingBuffer; // in byte
185     int8_t* _playoutBuffer; // in byte
186     uint32_t _recordingFramesLeft;
187     uint32_t _playoutFramesLeft;
188 
189     bool _initialized;
190     bool _recording;
191     bool _playing;
192     bool _recIsInitialized;
193     bool _playIsInitialized;
194     bool _AGC;
195 
196     snd_pcm_sframes_t _recordingDelay;
197     snd_pcm_sframes_t _playoutDelay;
198 
199     char _oldKeyState[32];
200 #if defined(USE_X11)
201     Display* _XDisplay;
202 #endif
203 };
204 
205 }
206 
207 #endif  // MODULES_AUDIO_DEVICE_MAIN_SOURCE_LINUX_AUDIO_DEVICE_ALSA_LINUX_H_
208