1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*
2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Use of this source code is governed by a BSD-style license
5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  that can be found in the LICENSE file in the root of the source
6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  tree. An additional intellectual property rights grant can be found
7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  in the file PATENTS.  All contributing project authors may
8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */
10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
11b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifndef WEBRTC_AUDIO_DEVICE_AUDIO_DEVICE_PULSE_LINUX_H
12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#define WEBRTC_AUDIO_DEVICE_AUDIO_DEVICE_PULSE_LINUX_H
13b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
14bc669ace8f09d73e95f923253ecdadd366f9b7f1pbos@webrtc.org#include "webrtc/modules/audio_device/audio_device_generic.h"
15bc669ace8f09d73e95f923253ecdadd366f9b7f1pbos@webrtc.org#include "webrtc/modules/audio_device/linux/audio_mixer_manager_pulse_linux.h"
16bc669ace8f09d73e95f923253ecdadd366f9b7f1pbos@webrtc.org#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
17b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1832b4e2f2d38cb8fe7ca95ea0ab65ba4769ffa230niklas.enbom@webrtc.org#include <X11/Xlib.h>
19bc669ace8f09d73e95f923253ecdadd366f9b7f1pbos@webrtc.org#include <pulse/pulseaudio.h>
20b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// We define this flag if it's missing from our headers, because we want to be
22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// able to compile against old headers but still use PA_STREAM_ADJUST_LATENCY
23b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// if run against a recent version of the library.
24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifndef PA_STREAM_ADJUST_LATENCY
25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#define PA_STREAM_ADJUST_LATENCY 0x2000U
26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifndef PA_STREAM_START_MUTED
28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#define PA_STREAM_START_MUTED 0x1000U
29b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
31b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Set this constant to 0 to disable latency reading
3264a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgconst uint32_t WEBRTC_PA_REPORT_LATENCY = 1;
33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Constants from implementation by Tristan Schmelcher [tschmelcher@google.com]
35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// First PulseAudio protocol version that supports PA_STREAM_ADJUST_LATENCY.
3764a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgconst uint32_t WEBRTC_PA_ADJUST_LATENCY_PROTOCOL_VERSION = 13;
38b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
39b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Some timing constants for optimal operation. See
40b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// https://tango.0pointer.de/pipermail/pulseaudio-discuss/2008-January/001170.html
41b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// for a good explanation of some of the factors that go into this.
42b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Playback.
44b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
45b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// For playback, there is a round-trip delay to fill the server-side playback
46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// buffer, so setting too low of a latency is a buffer underflow risk. We will
47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// automatically increase the latency if a buffer underflow does occur, but we
48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// also enforce a sane minimum at start-up time. Anything lower would be
49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// virtually guaranteed to underflow at least once, so there's no point in
50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// allowing lower latencies.
5164a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgconst uint32_t WEBRTC_PA_PLAYBACK_LATENCY_MINIMUM_MSECS = 20;
52b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
53b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Every time a playback stream underflows, we will reconfigure it with target
54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// latency that is greater by this amount.
5564a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgconst uint32_t WEBRTC_PA_PLAYBACK_LATENCY_INCREMENT_MSECS = 20;
56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
57b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// We also need to configure a suitable request size. Too small and we'd burn
58b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// CPU from the overhead of transfering small amounts of data at once. Too large
59b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// and the amount of data remaining in the buffer right before refilling it
60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// would be a buffer underflow risk. We set it to half of the buffer size.
6164a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgconst uint32_t WEBRTC_PA_PLAYBACK_REQUEST_FACTOR = 2;
62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Capture.
64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// For capture, low latency is not a buffer overflow risk, but it makes us burn
66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// CPU from the overhead of transfering small amounts of data at once, so we set
67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// a recommended value that we use for the kLowLatency constant (but if the user
68b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// explicitly requests something lower then we will honour it).
69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// 1ms takes about 6-7% CPU. 5ms takes about 5%. 10ms takes about 4.x%.
7064a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgconst uint32_t WEBRTC_PA_LOW_CAPTURE_LATENCY_MSECS = 10;
71b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// There is a round-trip delay to ack the data to the server, so the
73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// server-side buffer needs extra space to prevent buffer overflow. 20ms is
74b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// sufficient, but there is no penalty to making it bigger, so we make it huge.
75b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// (750ms is libpulse's default value for the _total_ buffer size in the
76b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// kNoLatencyRequirements case.)
7764a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgconst uint32_t WEBRTC_PA_CAPTURE_BUFFER_EXTRA_MSECS = 750;
78b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
7964a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgconst uint32_t WEBRTC_PA_MSECS_PER_SEC = 1000;
80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Init _configuredLatencyRec/Play to this value to disable latency requirements
8264a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgconst int32_t WEBRTC_PA_NO_LATENCY_REQUIREMENTS = -1;
83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Set this const to 1 to account for peeked and used data in latency calculation
8564a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgconst uint32_t WEBRTC_PA_CAPTURE_BUFFER_LATENCY_ADJUSTMENT = 0;
86b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
87b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgnamespace webrtc
88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
89b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgclass EventWrapper;
90b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgclass ThreadWrapper;
91b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
92b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgclass AudioDeviceLinuxPulse: public AudioDeviceGeneric
93b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgpublic:
9564a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org    AudioDeviceLinuxPulse(const int32_t id);
96d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual ~AudioDeviceLinuxPulse();
97b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
98b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Retrieve the currently utilized audio layer
99d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int32_t ActiveAudioLayer(
100d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org        AudioDeviceModule::AudioLayer& audioLayer) const OVERRIDE;
101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Main initializaton and termination
103d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int32_t Init() OVERRIDE;
104d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int32_t Terminate() OVERRIDE;
105d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual bool Initialized() const OVERRIDE;
106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Device enumeration
108d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int16_t PlayoutDevices() OVERRIDE;
109d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int16_t RecordingDevices() OVERRIDE;
11064a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org    virtual int32_t PlayoutDeviceName(
11164a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org        uint16_t index,
112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        char name[kAdmMaxDeviceNameSize],
113d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org        char guid[kAdmMaxGuidSize]) OVERRIDE;
11464a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org    virtual int32_t RecordingDeviceName(
11564a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org        uint16_t index,
116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        char name[kAdmMaxDeviceNameSize],
117d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org        char guid[kAdmMaxGuidSize]) OVERRIDE;
118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Device selection
120d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int32_t SetPlayoutDevice(uint16_t index) OVERRIDE;
12164a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org    virtual int32_t SetPlayoutDevice(
122d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org        AudioDeviceModule::WindowsDeviceType device) OVERRIDE;
123d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int32_t SetRecordingDevice(uint16_t index) OVERRIDE;
12464a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org    virtual int32_t SetRecordingDevice(
125d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org        AudioDeviceModule::WindowsDeviceType device) OVERRIDE;
126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Audio transport initialization
128d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int32_t PlayoutIsAvailable(bool& available) OVERRIDE;
129d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int32_t InitPlayout() OVERRIDE;
130d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual bool PlayoutIsInitialized() const OVERRIDE;
131d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int32_t RecordingIsAvailable(bool& available) OVERRIDE;
132d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int32_t InitRecording() OVERRIDE;
133d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual bool RecordingIsInitialized() const OVERRIDE;
134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Audio transport control
136d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int32_t StartPlayout() OVERRIDE;
137d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int32_t StopPlayout() OVERRIDE;
138d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual bool Playing() const OVERRIDE;
139d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int32_t StartRecording() OVERRIDE;
140d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int32_t StopRecording() OVERRIDE;
141d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual bool Recording() const OVERRIDE;
142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Microphone Automatic Gain Control (AGC)
144d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int32_t SetAGC(bool enable) OVERRIDE;
145d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual bool AGC() const OVERRIDE;
146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
147b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Volume control based on the Windows Wave API (Windows only)
148d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int32_t SetWaveOutVolume(uint16_t volumeLeft,
149d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org                                     uint16_t volumeRight) OVERRIDE;
15064a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org    virtual int32_t WaveOutVolume(uint16_t& volumeLeft,
151d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org                                  uint16_t& volumeRight) const OVERRIDE;
152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Audio mixer initialization
154d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int32_t InitSpeaker() OVERRIDE;
155d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual bool SpeakerIsInitialized() const OVERRIDE;
156d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int32_t InitMicrophone() OVERRIDE;
157d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual bool MicrophoneIsInitialized() const OVERRIDE;
158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Speaker volume controls
160d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int32_t SpeakerVolumeIsAvailable(bool& available) OVERRIDE;
161d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int32_t SetSpeakerVolume(uint32_t volume) OVERRIDE;
162d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int32_t SpeakerVolume(uint32_t& volume) const OVERRIDE;
163d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int32_t MaxSpeakerVolume(uint32_t& maxVolume) const OVERRIDE;
164d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int32_t MinSpeakerVolume(uint32_t& minVolume) const OVERRIDE;
165d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int32_t SpeakerVolumeStepSize(uint16_t& stepSize) const OVERRIDE;
166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Microphone volume controls
168d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int32_t MicrophoneVolumeIsAvailable(bool& available) OVERRIDE;
169d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int32_t SetMicrophoneVolume(uint32_t volume) OVERRIDE;
170d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int32_t MicrophoneVolume(uint32_t& volume) const OVERRIDE;
171d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int32_t MaxMicrophoneVolume(uint32_t& maxVolume) const OVERRIDE;
172d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int32_t MinMicrophoneVolume(uint32_t& minVolume) const OVERRIDE;
17364a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org    virtual int32_t MicrophoneVolumeStepSize(
174d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org        uint16_t& stepSize) const OVERRIDE;
175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Speaker mute control
177d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int32_t SpeakerMuteIsAvailable(bool& available) OVERRIDE;
178d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int32_t SetSpeakerMute(bool enable) OVERRIDE;
179d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int32_t SpeakerMute(bool& enabled) const OVERRIDE;
180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Microphone mute control
182d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int32_t MicrophoneMuteIsAvailable(bool& available) OVERRIDE;
183d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int32_t SetMicrophoneMute(bool enable) OVERRIDE;
184d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int32_t MicrophoneMute(bool& enabled) const OVERRIDE;
185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Microphone boost control
187d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int32_t MicrophoneBoostIsAvailable(bool& available) OVERRIDE;
188d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int32_t SetMicrophoneBoost(bool enable) OVERRIDE;
189d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int32_t MicrophoneBoost(bool& enabled) const OVERRIDE;
190b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Stereo support
192d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int32_t StereoPlayoutIsAvailable(bool& available) OVERRIDE;
193d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int32_t SetStereoPlayout(bool enable) OVERRIDE;
194d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int32_t StereoPlayout(bool& enabled) const OVERRIDE;
195d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int32_t StereoRecordingIsAvailable(bool& available) OVERRIDE;
196d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int32_t SetStereoRecording(bool enable) OVERRIDE;
197d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int32_t StereoRecording(bool& enabled) const OVERRIDE;
198b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Delay information and control
20064a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org    virtual int32_t
201b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        SetPlayoutBuffer(const AudioDeviceModule::BufferType type,
202d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org                         uint16_t sizeMS) OVERRIDE;
20364a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org    virtual int32_t PlayoutBuffer(AudioDeviceModule::BufferType& type,
204d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org                                  uint16_t& sizeMS) const OVERRIDE;
205d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int32_t PlayoutDelay(uint16_t& delayMS) const OVERRIDE;
206d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int32_t RecordingDelay(uint16_t& delayMS) const OVERRIDE;
207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
208b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // CPU load
209d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual int32_t CPULoad(uint16_t& load) const OVERRIDE;
210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
211b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgpublic:
212d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual bool PlayoutWarning() const OVERRIDE;
213d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual bool PlayoutError() const OVERRIDE;
214d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual bool RecordingWarning() const OVERRIDE;
215d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual bool RecordingError() const OVERRIDE;
216d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual void ClearPlayoutWarning() OVERRIDE;
217d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual void ClearPlayoutError() OVERRIDE;
218d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual void ClearRecordingWarning() OVERRIDE;
219d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual void ClearRecordingError() OVERRIDE;
220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
221b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgpublic:
222d8daa60f740d99ef279d176f0ed2ab9ed2803d53pbos@webrtc.org    virtual void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer) OVERRIDE;
223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
224b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgprivate:
225c9faf10f99da606e2d58b0b4a79c03c232b7c50fandresp@webrtc.org    void Lock() EXCLUSIVE_LOCK_FUNCTION(_critSect) {
226b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _critSect.Enter();
227b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
228c9faf10f99da606e2d58b0b4a79c03c232b7c50fandresp@webrtc.org    void UnLock() UNLOCK_FUNCTION(_critSect) {
229b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _critSect.Leave();
230b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
231b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    void WaitForOperationCompletion(pa_operation* paOperation) const;
232b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    void WaitForSuccess(pa_operation* paOperation) const;
233b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
234b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgprivate:
23532b4e2f2d38cb8fe7ca95ea0ab65ba4769ffa230niklas.enbom@webrtc.org    bool KeyPressed() const;
23632b4e2f2d38cb8fe7ca95ea0ab65ba4769ffa230niklas.enbom@webrtc.org
23732b4e2f2d38cb8fe7ca95ea0ab65ba4769ffa230niklas.enbom@webrtc.orgprivate:
238b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    static void PaContextStateCallback(pa_context *c, void *pThis);
239b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    static void PaSinkInfoCallback(pa_context *c, const pa_sink_info *i,
240b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                   int eol, void *pThis);
241b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    static void PaSourceInfoCallback(pa_context *c, const pa_source_info *i,
242b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                     int eol, void *pThis);
243b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    static void PaServerInfoCallback(pa_context *c, const pa_server_info *i,
244b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                     void *pThis);
245b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    static void PaStreamStateCallback(pa_stream *p, void *pThis);
246b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    void PaContextStateCallbackHandler(pa_context *c);
247b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    void PaSinkInfoCallbackHandler(const pa_sink_info *i, int eol);
248b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    void PaSourceInfoCallbackHandler(const pa_source_info *i, int eol);
249b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    void PaServerInfoCallbackHandler(const pa_server_info *i);
250b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    void PaStreamStateCallbackHandler(pa_stream *p);
251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
252b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    void EnableWriteCallback();
253b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    void DisableWriteCallback();
254b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    static void PaStreamWriteCallback(pa_stream *unused, size_t buffer_space,
255b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                      void *pThis);
256b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    void PaStreamWriteCallbackHandler(size_t buffer_space);
257b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    static void PaStreamUnderflowCallback(pa_stream *unused, void *pThis);
258b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    void PaStreamUnderflowCallbackHandler();
259b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    void EnableReadCallback();
260b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    void DisableReadCallback();
261b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    static void PaStreamReadCallback(pa_stream *unused1, size_t unused2,
262b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                     void *pThis);
263b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    void PaStreamReadCallbackHandler();
264b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    static void PaStreamOverflowCallback(pa_stream *unused, void *pThis);
265b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    void PaStreamOverflowCallbackHandler();
26664a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org    int32_t LatencyUsecs(pa_stream *stream);
26764a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org    int32_t ReadRecordedData(const void* bufferData, size_t bufferSize);
26864a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org    int32_t ProcessRecordedData(int8_t *bufferData,
26964a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org                                uint32_t bufferSizeInSamples,
27064a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org                                uint32_t recDelay);
27164a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org
27264a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org    int32_t CheckPulseAudioVersion();
27364a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org    int32_t InitSamplingFrequency();
27464a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org    int32_t GetDefaultDeviceInfo(bool recDevice, char* name, uint16_t& index);
27564a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org    int32_t InitPulseAudio();
27664a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org    int32_t TerminatePulseAudio();
277b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
278b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    void PaLock();
279b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    void PaUnLock();
280b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
281b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    static bool RecThreadFunc(void*);
282b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    static bool PlayThreadFunc(void*);
283b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    bool RecThreadProcess();
284b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    bool PlayThreadProcess();
285b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
286b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgprivate:
287b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    AudioDeviceBuffer* _ptrAudioBuffer;
288b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
289b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionWrapper& _critSect;
290b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    EventWrapper& _timeEventRec;
291b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    EventWrapper& _timeEventPlay;
292b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    EventWrapper& _recStartEvent;
293b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    EventWrapper& _playStartEvent;
294b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
295b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ThreadWrapper* _ptrThreadPlay;
296b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ThreadWrapper* _ptrThreadRec;
29764a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org    uint32_t _recThreadID;
29864a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org    uint32_t _playThreadID;
29964a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org    int32_t _id;
300b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
301b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    AudioMixerManagerLinuxPulse _mixerManager;
302b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
30364a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org    uint16_t _inputDeviceIndex;
30464a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org    uint16_t _outputDeviceIndex;
305b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    bool _inputDeviceIsSpecified;
306b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    bool _outputDeviceIsSpecified;
307b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
3089e4ad86dc143a3a36bbeeba48318982008117107andrew@webrtc.org    int sample_rate_hz_;
30964a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org    uint8_t _recChannels;
31064a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org    uint8_t _playChannels;
311b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
312b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    AudioDeviceModule::BufferType _playBufType;
313b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
314b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgprivate:
315b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    bool _initialized;
316b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    bool _recording;
317b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    bool _playing;
318b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    bool _recIsInitialized;
319b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    bool _playIsInitialized;
320b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    bool _startRec;
321b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    bool _stopRec;
322b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    bool _startPlay;
323b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    bool _stopPlay;
324b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    bool _AGC;
325b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    bool update_speaker_volume_at_startup_;
326b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
327b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgprivate:
32864a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org    uint16_t _playBufDelayFixed; // fixed playback delay
329b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
33064a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org    uint32_t _sndCardPlayDelay;
33164a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org    uint32_t _sndCardRecDelay;
332b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
33364a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org    int32_t _writeErrors;
33464a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org    uint16_t _playWarning;
33564a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org    uint16_t _playError;
33664a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org    uint16_t _recWarning;
33764a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org    uint16_t _recError;
338b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
33964a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org    uint16_t _deviceIndex;
34064a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org    int16_t _numPlayDevices;
34164a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org    int16_t _numRecDevices;
342b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    char* _playDeviceName;
343b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    char* _recDeviceName;
344b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    char* _playDisplayDeviceName;
345b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    char* _recDisplayDeviceName;
346b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    char _paServerVersion[32];
347b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
34864a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org    int8_t* _playBuffer;
349b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    size_t _playbackBufferSize;
350b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    size_t _playbackBufferUnused;
351b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    size_t _tempBufferSpace;
35264a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org    int8_t* _recBuffer;
353b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    size_t _recordBufferSize;
354b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    size_t _recordBufferUsed;
355b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    const void* _tempSampleData;
356b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    size_t _tempSampleDataSize;
35764a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org    int32_t _configuredLatencyPlay;
35864a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org    int32_t _configuredLatencyRec;
359b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
360b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // PulseAudio
36164a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org    uint16_t _paDeviceIndex;
362b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    bool _paStateChanged;
363b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
364b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    pa_threaded_mainloop* _paMainloop;
365b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    pa_mainloop_api* _paMainloopApi;
366b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    pa_context* _paContext;
367b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
368b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    pa_stream* _recStream;
369b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    pa_stream* _playStream;
37064a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org    uint32_t _recStreamFlags;
37164a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org    uint32_t _playStreamFlags;
372b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    pa_buffer_attr _playBufferAttr;
373b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    pa_buffer_attr _recBufferAttr;
37432b4e2f2d38cb8fe7ca95ea0ab65ba4769ffa230niklas.enbom@webrtc.org
37532b4e2f2d38cb8fe7ca95ea0ab65ba4769ffa230niklas.enbom@webrtc.org    char _oldKeyState[32];
37632b4e2f2d38cb8fe7ca95ea0ab65ba4769ffa230niklas.enbom@webrtc.org    Display* _XDisplay;
377b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org};
378b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
379b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
380b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
381b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif  // MODULES_AUDIO_DEVICE_MAIN_SOURCE_LINUX_AUDIO_DEVICE_PULSE_LINUX_H_
382