1 /* 2 * Copyright 2004 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_SOUND_PULSEAUDIOSOUNDSYSTEM_H_ 12 #define WEBRTC_SOUND_PULSEAUDIOSOUNDSYSTEM_H_ 13 14 #ifdef HAVE_LIBPULSE 15 16 #include "webrtc/sound/pulseaudiosymboltable.h" 17 #include "webrtc/sound/soundsysteminterface.h" 18 #include "webrtc/base/constructormagic.h" 19 20 namespace rtc { 21 22 class PulseAudioInputStream; 23 class PulseAudioOutputStream; 24 class PulseAudioStream; 25 26 // Sound system implementation for PulseAudio, a cross-platform sound server 27 // (but commonly used only on Linux, which is the only platform we support 28 // it on). 29 // Init(), Terminate(), and the destructor should never be invoked concurrently, 30 // but all other methods are thread-safe. 31 class PulseAudioSoundSystem : public SoundSystemInterface { 32 friend class PulseAudioInputStream; 33 friend class PulseAudioOutputStream; 34 friend class PulseAudioStream; 35 public: Create()36 static SoundSystemInterface *Create() { 37 return new PulseAudioSoundSystem(); 38 } 39 40 PulseAudioSoundSystem(); 41 42 virtual ~PulseAudioSoundSystem(); 43 44 virtual bool Init(); 45 virtual void Terminate(); 46 47 virtual bool EnumeratePlaybackDevices(SoundDeviceLocatorList *devices); 48 virtual bool EnumerateCaptureDevices(SoundDeviceLocatorList *devices); 49 50 virtual bool GetDefaultPlaybackDevice(SoundDeviceLocator **device); 51 virtual bool GetDefaultCaptureDevice(SoundDeviceLocator **device); 52 53 virtual SoundOutputStreamInterface *OpenPlaybackDevice( 54 const SoundDeviceLocator *device, 55 const OpenParams ¶ms); 56 virtual SoundInputStreamInterface *OpenCaptureDevice( 57 const SoundDeviceLocator *device, 58 const OpenParams ¶ms); 59 60 virtual const char *GetName() const; 61 62 private: 63 bool IsInitialized(); 64 65 static void ConnectToPulseCallbackThunk(pa_context *context, void *userdata); 66 67 void OnConnectToPulseCallback(pa_context *context, bool *connect_done); 68 69 bool ConnectToPulse(pa_context *context); 70 71 pa_context *CreateNewConnection(); 72 73 template <typename InfoStruct> 74 bool EnumerateDevices(SoundDeviceLocatorList *devices, 75 pa_operation *(*enumerate_fn)( 76 pa_context *c, 77 void (*callback_fn)( 78 pa_context *c, 79 const InfoStruct *i, 80 int eol, 81 void *userdata), 82 void *userdata), 83 void (*callback_fn)( 84 pa_context *c, 85 const InfoStruct *i, 86 int eol, 87 void *userdata)); 88 89 static void EnumeratePlaybackDevicesCallbackThunk(pa_context *unused, 90 const pa_sink_info *info, 91 int eol, 92 void *userdata); 93 94 static void EnumerateCaptureDevicesCallbackThunk(pa_context *unused, 95 const pa_source_info *info, 96 int eol, 97 void *userdata); 98 99 void OnEnumeratePlaybackDevicesCallback( 100 SoundDeviceLocatorList *devices, 101 const pa_sink_info *info, 102 int eol); 103 104 void OnEnumerateCaptureDevicesCallback( 105 SoundDeviceLocatorList *devices, 106 const pa_source_info *info, 107 int eol); 108 109 template <const char *(pa_server_info::*field)> 110 static void GetDefaultDeviceCallbackThunk( 111 pa_context *unused, 112 const pa_server_info *info, 113 void *userdata); 114 115 template <const char *(pa_server_info::*field)> 116 void OnGetDefaultDeviceCallback( 117 const pa_server_info *info, 118 SoundDeviceLocator **device); 119 120 template <const char *(pa_server_info::*field)> 121 bool GetDefaultDevice(SoundDeviceLocator **device); 122 123 static void StreamStateChangedCallbackThunk(pa_stream *stream, 124 void *userdata); 125 126 void OnStreamStateChangedCallback(pa_stream *stream); 127 128 template <typename StreamInterface> 129 StreamInterface *OpenDevice( 130 const SoundDeviceLocator *device, 131 const OpenParams ¶ms, 132 const char *stream_name, 133 StreamInterface *(PulseAudioSoundSystem::*connect_fn)( 134 pa_stream *stream, 135 const char *dev, 136 int flags, 137 pa_stream_flags_t pa_flags, 138 int latency, 139 const pa_sample_spec &spec)); 140 141 SoundOutputStreamInterface *ConnectOutputStream( 142 pa_stream *stream, 143 const char *dev, 144 int flags, 145 pa_stream_flags_t pa_flags, 146 int latency, 147 const pa_sample_spec &spec); 148 149 SoundInputStreamInterface *ConnectInputStream( 150 pa_stream *stream, 151 const char *dev, 152 int flags, 153 pa_stream_flags_t pa_flags, 154 int latency, 155 const pa_sample_spec &spec); 156 157 bool FinishOperation(pa_operation *op); 158 159 void Lock(); 160 void Unlock(); 161 void Wait(); 162 void Signal(); 163 164 const char *LastError(); 165 166 pa_threaded_mainloop *mainloop_; 167 pa_context *context_; 168 PulseAudioSymbolTable symbol_table_; 169 170 RTC_DISALLOW_COPY_AND_ASSIGN(PulseAudioSoundSystem); 171 }; 172 173 } // namespace rtc 174 175 #endif // HAVE_LIBPULSE 176 177 #endif // WEBRTC_SOUND_PULSEAUDIOSOUNDSYSTEM_H_ 178