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