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 WEBRTC_AUDIO_DEVICE_AUDIO_DEVICE_ALSA_LINUX_H
12#define WEBRTC_AUDIO_DEVICE_AUDIO_DEVICE_ALSA_LINUX_H
13
14#include "webrtc/base/platform_thread.h"
15#include "webrtc/modules/audio_device/audio_device_generic.h"
16#include "webrtc/modules/audio_device/linux/audio_mixer_manager_alsa_linux.h"
17#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
18
19#if defined(USE_X11)
20#include <X11/Xlib.h>
21#endif
22#include <alsa/asoundlib.h>
23#include <sys/ioctl.h>
24#include <sys/soundcard.h>
25
26
27namespace webrtc
28{
29class EventWrapper;
30
31class AudioDeviceLinuxALSA : public AudioDeviceGeneric
32{
33public:
34    AudioDeviceLinuxALSA(const int32_t id);
35    virtual ~AudioDeviceLinuxALSA();
36
37    // Retrieve the currently utilized audio layer
38    int32_t ActiveAudioLayer(
39        AudioDeviceModule::AudioLayer& audioLayer) const override;
40
41    // Main initializaton and termination
42    int32_t Init() override;
43    int32_t Terminate() override;
44    bool Initialized() const override;
45
46    // Device enumeration
47    int16_t PlayoutDevices() override;
48    int16_t RecordingDevices() override;
49    int32_t PlayoutDeviceName(uint16_t index,
50                              char name[kAdmMaxDeviceNameSize],
51                              char guid[kAdmMaxGuidSize]) override;
52    int32_t RecordingDeviceName(uint16_t index,
53                                char name[kAdmMaxDeviceNameSize],
54                                char guid[kAdmMaxGuidSize]) override;
55
56    // Device selection
57    int32_t SetPlayoutDevice(uint16_t index) override;
58    int32_t SetPlayoutDevice(
59        AudioDeviceModule::WindowsDeviceType device) override;
60    int32_t SetRecordingDevice(uint16_t index) override;
61    int32_t SetRecordingDevice(
62        AudioDeviceModule::WindowsDeviceType device) override;
63
64    // Audio transport initialization
65    int32_t PlayoutIsAvailable(bool& available) override;
66    int32_t InitPlayout() override;
67    bool PlayoutIsInitialized() const override;
68    int32_t RecordingIsAvailable(bool& available) override;
69    int32_t InitRecording() override;
70    bool RecordingIsInitialized() const override;
71
72    // Audio transport control
73    int32_t StartPlayout() override;
74    int32_t StopPlayout() override;
75    bool Playing() const override;
76    int32_t StartRecording() override;
77    int32_t StopRecording() override;
78    bool Recording() const override;
79
80    // Microphone Automatic Gain Control (AGC)
81    int32_t SetAGC(bool enable) override;
82    bool AGC() const override;
83
84    // Volume control based on the Windows Wave API (Windows only)
85    int32_t SetWaveOutVolume(uint16_t volumeLeft,
86                             uint16_t volumeRight) override;
87    int32_t WaveOutVolume(uint16_t& volumeLeft,
88                          uint16_t& volumeRight) const override;
89
90    // Audio mixer initialization
91    int32_t InitSpeaker() override;
92    bool SpeakerIsInitialized() const override;
93    int32_t InitMicrophone() override;
94    bool MicrophoneIsInitialized() const override;
95
96    // Speaker volume controls
97    int32_t SpeakerVolumeIsAvailable(bool& available) override;
98    int32_t SetSpeakerVolume(uint32_t volume) override;
99    int32_t SpeakerVolume(uint32_t& volume) const override;
100    int32_t MaxSpeakerVolume(uint32_t& maxVolume) const override;
101    int32_t MinSpeakerVolume(uint32_t& minVolume) const override;
102    int32_t SpeakerVolumeStepSize(uint16_t& stepSize) const override;
103
104    // Microphone volume controls
105    int32_t MicrophoneVolumeIsAvailable(bool& available) override;
106    int32_t SetMicrophoneVolume(uint32_t volume) override;
107    int32_t MicrophoneVolume(uint32_t& volume) const override;
108    int32_t MaxMicrophoneVolume(uint32_t& maxVolume) const override;
109    int32_t MinMicrophoneVolume(uint32_t& minVolume) const override;
110    int32_t MicrophoneVolumeStepSize(uint16_t& stepSize) const override;
111
112    // Speaker mute control
113    int32_t SpeakerMuteIsAvailable(bool& available) override;
114    int32_t SetSpeakerMute(bool enable) override;
115    int32_t SpeakerMute(bool& enabled) const override;
116
117    // Microphone mute control
118    int32_t MicrophoneMuteIsAvailable(bool& available) override;
119    int32_t SetMicrophoneMute(bool enable) override;
120    int32_t MicrophoneMute(bool& enabled) const override;
121
122    // Microphone boost control
123    int32_t MicrophoneBoostIsAvailable(bool& available) override;
124    int32_t SetMicrophoneBoost(bool enable) override;
125    int32_t MicrophoneBoost(bool& enabled) const override;
126
127    // Stereo support
128    int32_t StereoPlayoutIsAvailable(bool& available) override;
129    int32_t SetStereoPlayout(bool enable) override;
130    int32_t StereoPlayout(bool& enabled) const override;
131    int32_t StereoRecordingIsAvailable(bool& available) override;
132    int32_t SetStereoRecording(bool enable) override;
133    int32_t StereoRecording(bool& enabled) const override;
134
135    // Delay information and control
136    int32_t SetPlayoutBuffer(const AudioDeviceModule::BufferType type,
137                             uint16_t sizeMS) override;
138    int32_t PlayoutBuffer(AudioDeviceModule::BufferType& type,
139                          uint16_t& sizeMS) const override;
140    int32_t PlayoutDelay(uint16_t& delayMS) const override;
141    int32_t RecordingDelay(uint16_t& delayMS) const override;
142
143    // CPU load
144    int32_t CPULoad(uint16_t& load) const override;
145
146public:
147 bool PlayoutWarning() const override;
148 bool PlayoutError() const override;
149 bool RecordingWarning() const override;
150 bool RecordingError() const override;
151 void ClearPlayoutWarning() override;
152 void ClearPlayoutError() override;
153 void ClearRecordingWarning() override;
154 void ClearRecordingError() override;
155
156public:
157 void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer) override;
158
159private:
160    int32_t GetDevicesInfo(const int32_t function,
161                           const bool playback,
162                           const int32_t enumDeviceNo = 0,
163                           char* enumDeviceName = NULL,
164                           const int32_t ednLen = 0) const;
165    int32_t ErrorRecovery(int32_t error, snd_pcm_t* deviceHandle);
166
167private:
168    bool KeyPressed() const;
169
170private:
171    void Lock() EXCLUSIVE_LOCK_FUNCTION(_critSect) { _critSect.Enter(); };
172    void UnLock() UNLOCK_FUNCTION(_critSect) { _critSect.Leave(); };
173private:
174    inline int32_t InputSanityCheckAfterUnlockedPeriod() const;
175    inline int32_t OutputSanityCheckAfterUnlockedPeriod() const;
176
177private:
178    static bool RecThreadFunc(void*);
179    static bool PlayThreadFunc(void*);
180    bool RecThreadProcess();
181    bool PlayThreadProcess();
182
183private:
184    AudioDeviceBuffer* _ptrAudioBuffer;
185
186    CriticalSectionWrapper& _critSect;
187
188    // TODO(pbos): Make plain members and start/stop instead of resetting these
189    // pointers. A thread can be reused.
190    rtc::scoped_ptr<rtc::PlatformThread> _ptrThreadRec;
191    rtc::scoped_ptr<rtc::PlatformThread> _ptrThreadPlay;
192
193    int32_t _id;
194
195    AudioMixerManagerLinuxALSA _mixerManager;
196
197    uint16_t _inputDeviceIndex;
198    uint16_t _outputDeviceIndex;
199    bool _inputDeviceIsSpecified;
200    bool _outputDeviceIsSpecified;
201
202    snd_pcm_t* _handleRecord;
203    snd_pcm_t* _handlePlayout;
204
205    snd_pcm_uframes_t _recordingBuffersizeInFrame;
206    snd_pcm_uframes_t _recordingPeriodSizeInFrame;
207    snd_pcm_uframes_t _playoutBufferSizeInFrame;
208    snd_pcm_uframes_t _playoutPeriodSizeInFrame;
209
210    ssize_t _recordingBufferSizeIn10MS;
211    ssize_t _playoutBufferSizeIn10MS;
212    uint32_t _recordingFramesIn10MS;
213    uint32_t _playoutFramesIn10MS;
214
215    uint32_t _recordingFreq;
216    uint32_t _playoutFreq;
217    uint8_t _recChannels;
218    uint8_t _playChannels;
219
220    int8_t* _recordingBuffer; // in byte
221    int8_t* _playoutBuffer; // in byte
222    uint32_t _recordingFramesLeft;
223    uint32_t _playoutFramesLeft;
224
225    AudioDeviceModule::BufferType _playBufType;
226
227private:
228    bool _initialized;
229    bool _recording;
230    bool _playing;
231    bool _recIsInitialized;
232    bool _playIsInitialized;
233    bool _AGC;
234
235    snd_pcm_sframes_t _recordingDelay;
236    snd_pcm_sframes_t _playoutDelay;
237
238    uint16_t _playWarning;
239    uint16_t _playError;
240    uint16_t _recWarning;
241    uint16_t _recError;
242
243    uint16_t _playBufDelay;                 // playback delay
244    uint16_t _playBufDelayFixed;            // fixed playback delay
245
246    char _oldKeyState[32];
247#if defined(USE_X11)
248    Display* _XDisplay;
249#endif
250};
251
252}
253
254#endif  // MODULES_AUDIO_DEVICE_MAIN_SOURCE_LINUX_AUDIO_DEVICE_ALSA_LINUX_H_
255