| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 #include <assert.h> | 11 #include <assert.h> |
| 12 | 12 |
| 13 #include "webrtc/modules/audio_device/linux/audio_mixer_manager_pulse_linux.h" | 13 #include "webrtc/modules/audio_device/linux/audio_mixer_manager_pulse_linux.h" |
| 14 #include "webrtc/rtc_base/checks.h" | 14 #include "webrtc/rtc_base/checks.h" |
| 15 #include "webrtc/system_wrappers/include/trace.h" | 15 #include "webrtc/rtc_base/logging.h" |
| 16 | 16 |
| 17 extern webrtc::adm_linux_pulse::PulseAudioSymbolTable PaSymbolTable; | 17 extern webrtc::adm_linux_pulse::PulseAudioSymbolTable PaSymbolTable; |
| 18 | 18 |
| 19 // Accesses Pulse functions through our late-binding symbol table instead of | 19 // Accesses Pulse functions through our late-binding symbol table instead of |
| 20 // directly. This way we don't have to link to libpulse, which means our | 20 // directly. This way we don't have to link to libpulse, which means our |
| 21 // binary will work on systems that don't have it. | 21 // binary will work on systems that don't have it. |
| 22 #define LATE(sym) \ | 22 #define LATE(sym) \ |
| 23 LATESYM_GET(webrtc::adm_linux_pulse::PulseAudioSymbolTable, &PaSymbolTable, \ | 23 LATESYM_GET(webrtc::adm_linux_pulse::PulseAudioSymbolTable, &PaSymbolTable, \ |
| 24 sym) | 24 sym) |
| 25 | 25 |
| 26 namespace webrtc | 26 namespace webrtc |
| 27 { | 27 { |
| 28 | 28 |
| 29 class AutoPulseLock { | 29 class AutoPulseLock { |
| 30 public: | 30 public: |
| 31 explicit AutoPulseLock(pa_threaded_mainloop* pa_mainloop) | 31 explicit AutoPulseLock(pa_threaded_mainloop* pa_mainloop) |
| 32 : pa_mainloop_(pa_mainloop) { | 32 : pa_mainloop_(pa_mainloop) { |
| 33 LATE(pa_threaded_mainloop_lock)(pa_mainloop_); | 33 LATE(pa_threaded_mainloop_lock)(pa_mainloop_); |
| 34 } | 34 } |
| 35 | 35 |
| 36 ~AutoPulseLock() { | 36 ~AutoPulseLock() { |
| 37 LATE(pa_threaded_mainloop_unlock)(pa_mainloop_); | 37 LATE(pa_threaded_mainloop_unlock)(pa_mainloop_); |
| 38 } | 38 } |
| 39 | 39 |
| 40 private: | 40 private: |
| 41 pa_threaded_mainloop* const pa_mainloop_; | 41 pa_threaded_mainloop* const pa_mainloop_; |
| 42 }; | 42 }; |
| 43 | 43 |
| 44 AudioMixerManagerLinuxPulse::AudioMixerManagerLinuxPulse(const int32_t id) : | 44 AudioMixerManagerLinuxPulse::AudioMixerManagerLinuxPulse() : |
| 45 _id(id), | |
| 46 _paOutputDeviceIndex(-1), | 45 _paOutputDeviceIndex(-1), |
| 47 _paInputDeviceIndex(-1), | 46 _paInputDeviceIndex(-1), |
| 48 _paPlayStream(NULL), | 47 _paPlayStream(NULL), |
| 49 _paRecStream(NULL), | 48 _paRecStream(NULL), |
| 50 _paMainloop(NULL), | 49 _paMainloop(NULL), |
| 51 _paContext(NULL), | 50 _paContext(NULL), |
| 52 _paVolume(0), | 51 _paVolume(0), |
| 53 _paMute(0), | 52 _paMute(0), |
| 54 _paVolSteps(0), | 53 _paVolSteps(0), |
| 55 _paSpeakerMute(false), | 54 _paSpeakerMute(false), |
| 56 _paSpeakerVolume(PA_VOLUME_NORM), | 55 _paSpeakerVolume(PA_VOLUME_NORM), |
| 57 _paChannels(0), | 56 _paChannels(0), |
| 58 _paObjectsSet(false) | 57 _paObjectsSet(false) |
| 59 { | 58 { |
| 60 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, | 59 LOG(LS_INFO) << __FUNCTION__ << " created"; |
| 61 "%s constructed", __FUNCTION__); | |
| 62 } | 60 } |
| 63 | 61 |
| 64 AudioMixerManagerLinuxPulse::~AudioMixerManagerLinuxPulse() | 62 AudioMixerManagerLinuxPulse::~AudioMixerManagerLinuxPulse() |
| 65 { | 63 { |
| 66 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 64 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 67 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, | 65 LOG(LS_INFO) << __FUNCTION__ << " destroyed"; |
| 68 "%s destructed", __FUNCTION__); | |
| 69 | 66 |
| 70 Close(); | 67 Close(); |
| 71 } | 68 } |
| 72 | 69 |
| 73 // =========================================================================== | 70 // =========================================================================== |
| 74 // PUBLIC METHODS | 71 // PUBLIC METHODS |
| 75 // =========================================================================== | 72 // =========================================================================== |
| 76 | 73 |
| 77 int32_t AudioMixerManagerLinuxPulse::SetPulseAudioObjects( | 74 int32_t AudioMixerManagerLinuxPulse::SetPulseAudioObjects( |
| 78 pa_threaded_mainloop* mainloop, | 75 pa_threaded_mainloop* mainloop, |
| 79 pa_context* context) | 76 pa_context* context) |
| 80 { | 77 { |
| 81 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 78 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 82 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "%s", | 79 LOG(LS_VERBOSE) << __FUNCTION__; |
| 83 __FUNCTION__); | |
| 84 | 80 |
| 85 if (!mainloop || !context) | 81 if (!mainloop || !context) |
| 86 { | 82 { |
| 87 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 83 LOG(LS_ERROR) << "could not set PulseAudio objects for mixer"; |
| 88 " could not set PulseAudio objects for mixer"); | |
| 89 return -1; | 84 return -1; |
| 90 } | 85 } |
| 91 | 86 |
| 92 _paMainloop = mainloop; | 87 _paMainloop = mainloop; |
| 93 _paContext = context; | 88 _paContext = context; |
| 94 _paObjectsSet = true; | 89 _paObjectsSet = true; |
| 95 | 90 |
| 96 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 91 LOG(LS_VERBOSE) << "the PulseAudio objects for the mixer has been set"; |
| 97 " the PulseAudio objects for the mixer has been set"); | |
| 98 | 92 |
| 99 return 0; | 93 return 0; |
| 100 } | 94 } |
| 101 | 95 |
| 102 int32_t AudioMixerManagerLinuxPulse::Close() | 96 int32_t AudioMixerManagerLinuxPulse::Close() |
| 103 { | 97 { |
| 104 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 98 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 105 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "%s", | 99 LOG(LS_VERBOSE) << __FUNCTION__; |
| 106 __FUNCTION__); | |
| 107 | 100 |
| 108 CloseSpeaker(); | 101 CloseSpeaker(); |
| 109 CloseMicrophone(); | 102 CloseMicrophone(); |
| 110 | 103 |
| 111 _paMainloop = NULL; | 104 _paMainloop = NULL; |
| 112 _paContext = NULL; | 105 _paContext = NULL; |
| 113 _paObjectsSet = false; | 106 _paObjectsSet = false; |
| 114 | 107 |
| 115 return 0; | 108 return 0; |
| 116 | 109 |
| 117 } | 110 } |
| 118 | 111 |
| 119 int32_t AudioMixerManagerLinuxPulse::CloseSpeaker() | 112 int32_t AudioMixerManagerLinuxPulse::CloseSpeaker() |
| 120 { | 113 { |
| 121 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 114 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 122 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "%s", | 115 LOG(LS_VERBOSE) << __FUNCTION__; |
| 123 __FUNCTION__); | |
| 124 | 116 |
| 125 // Reset the index to -1 | 117 // Reset the index to -1 |
| 126 _paOutputDeviceIndex = -1; | 118 _paOutputDeviceIndex = -1; |
| 127 _paPlayStream = NULL; | 119 _paPlayStream = NULL; |
| 128 | 120 |
| 129 return 0; | 121 return 0; |
| 130 } | 122 } |
| 131 | 123 |
| 132 int32_t AudioMixerManagerLinuxPulse::CloseMicrophone() | 124 int32_t AudioMixerManagerLinuxPulse::CloseMicrophone() |
| 133 { | 125 { |
| 134 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 126 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 135 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "%s", | 127 LOG(LS_VERBOSE) << __FUNCTION__; |
| 136 __FUNCTION__); | |
| 137 | 128 |
| 138 // Reset the index to -1 | 129 // Reset the index to -1 |
| 139 _paInputDeviceIndex = -1; | 130 _paInputDeviceIndex = -1; |
| 140 _paRecStream = NULL; | 131 _paRecStream = NULL; |
| 141 | 132 |
| 142 return 0; | 133 return 0; |
| 143 } | 134 } |
| 144 | 135 |
| 145 int32_t AudioMixerManagerLinuxPulse::SetPlayStream(pa_stream* playStream) | 136 int32_t AudioMixerManagerLinuxPulse::SetPlayStream(pa_stream* playStream) |
| 146 { | 137 { |
| 147 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 138 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 148 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 139 LOG(LS_VERBOSE) << "AudioMixerManagerLinuxPulse::SetPlayStream(playStream)"; |
| 149 "AudioMixerManagerLinuxPulse::SetPlayStream(playStream)"); | |
| 150 | 140 |
| 151 _paPlayStream = playStream; | 141 _paPlayStream = playStream; |
| 152 return 0; | 142 return 0; |
| 153 } | 143 } |
| 154 | 144 |
| 155 int32_t AudioMixerManagerLinuxPulse::SetRecStream(pa_stream* recStream) | 145 int32_t AudioMixerManagerLinuxPulse::SetRecStream(pa_stream* recStream) |
| 156 { | 146 { |
| 157 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 147 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 158 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 148 LOG(LS_VERBOSE) << "AudioMixerManagerLinuxPulse::SetRecStream(recStream)"; |
| 159 "AudioMixerManagerLinuxPulse::SetRecStream(recStream)"); | |
| 160 | 149 |
| 161 _paRecStream = recStream; | 150 _paRecStream = recStream; |
| 162 return 0; | 151 return 0; |
| 163 } | 152 } |
| 164 | 153 |
| 165 int32_t AudioMixerManagerLinuxPulse::OpenSpeaker( | 154 int32_t AudioMixerManagerLinuxPulse::OpenSpeaker( |
| 166 uint16_t deviceIndex) | 155 uint16_t deviceIndex) |
| 167 { | 156 { |
| 168 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 157 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 169 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 158 LOG(LS_VERBOSE) << "AudioMixerManagerLinuxPulse::OpenSpeaker(deviceIndex=" |
| 170 "AudioMixerManagerLinuxPulse::OpenSpeaker(deviceIndex=%d)", | 159 << deviceIndex << ")"; |
| 171 deviceIndex); | |
| 172 | 160 |
| 173 // No point in opening the speaker | 161 // No point in opening the speaker |
| 174 // if PA objects have not been set | 162 // if PA objects have not been set |
| 175 if (!_paObjectsSet) | 163 if (!_paObjectsSet) |
| 176 { | 164 { |
| 177 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 165 LOG(LS_ERROR) << "PulseAudio objects has not been set"; |
| 178 " PulseAudio objects has not been set"); | |
| 179 return -1; | 166 return -1; |
| 180 } | 167 } |
| 181 | 168 |
| 182 // Set the index for the PulseAudio | 169 // Set the index for the PulseAudio |
| 183 // output device to control | 170 // output device to control |
| 184 _paOutputDeviceIndex = deviceIndex; | 171 _paOutputDeviceIndex = deviceIndex; |
| 185 | 172 |
| 186 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 173 LOG(LS_VERBOSE) << "the output mixer device is now open"; |
| 187 " the output mixer device is now open"); | |
| 188 | 174 |
| 189 return 0; | 175 return 0; |
| 190 } | 176 } |
| 191 | 177 |
| 192 int32_t AudioMixerManagerLinuxPulse::OpenMicrophone( | 178 int32_t AudioMixerManagerLinuxPulse::OpenMicrophone( |
| 193 uint16_t deviceIndex) | 179 uint16_t deviceIndex) |
| 194 { | 180 { |
| 195 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 181 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 196 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 182 LOG(LS_VERBOSE) |
| 197 "AudioMixerManagerLinuxPulse::OpenMicrophone" | 183 << "AudioMixerManagerLinuxPulse::OpenMicrophone(deviceIndex=" |
| 198 "(deviceIndex=%d)", deviceIndex); | 184 << deviceIndex << ")"; |
| 199 | 185 |
| 200 // No point in opening the microphone | 186 // No point in opening the microphone |
| 201 // if PA objects have not been set | 187 // if PA objects have not been set |
| 202 if (!_paObjectsSet) | 188 if (!_paObjectsSet) |
| 203 { | 189 { |
| 204 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 190 LOG(LS_ERROR) << "PulseAudio objects have not been set"; |
| 205 " PulseAudio objects have not been set"); | |
| 206 return -1; | 191 return -1; |
| 207 } | 192 } |
| 208 | 193 |
| 209 // Set the index for the PulseAudio | 194 // Set the index for the PulseAudio |
| 210 // input device to control | 195 // input device to control |
| 211 _paInputDeviceIndex = deviceIndex; | 196 _paInputDeviceIndex = deviceIndex; |
| 212 | 197 |
| 213 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 198 LOG(LS_VERBOSE) << "the input mixer device is now open"; |
| 214 " the input mixer device is now open"); | |
| 215 | 199 |
| 216 return 0; | 200 return 0; |
| 217 } | 201 } |
| 218 | 202 |
| 219 bool AudioMixerManagerLinuxPulse::SpeakerIsInitialized() const | 203 bool AudioMixerManagerLinuxPulse::SpeakerIsInitialized() const |
| 220 { | 204 { |
| 221 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 205 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 222 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "%s", | 206 LOG(LS_INFO) << __FUNCTION__; |
| 223 __FUNCTION__); | |
| 224 | 207 |
| 225 return (_paOutputDeviceIndex != -1); | 208 return (_paOutputDeviceIndex != -1); |
| 226 } | 209 } |
| 227 | 210 |
| 228 bool AudioMixerManagerLinuxPulse::MicrophoneIsInitialized() const | 211 bool AudioMixerManagerLinuxPulse::MicrophoneIsInitialized() const |
| 229 { | 212 { |
| 230 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 213 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 231 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "%s", | 214 LOG(LS_INFO) << __FUNCTION__; |
| 232 __FUNCTION__); | |
| 233 | 215 |
| 234 return (_paInputDeviceIndex != -1); | 216 return (_paInputDeviceIndex != -1); |
| 235 } | 217 } |
| 236 | 218 |
| 237 int32_t AudioMixerManagerLinuxPulse::SetSpeakerVolume( | 219 int32_t AudioMixerManagerLinuxPulse::SetSpeakerVolume( |
| 238 uint32_t volume) | 220 uint32_t volume) |
| 239 { | 221 { |
| 240 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 222 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 241 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 223 LOG(LS_VERBOSE) << "AudioMixerManagerLinuxPulse::SetSpeakerVolume(volume=" |
| 242 "AudioMixerManagerLinuxPulse::SetSpeakerVolume(volume=%u)", | 224 << volume << ")"; |
| 243 volume); | |
| 244 | 225 |
| 245 if (_paOutputDeviceIndex == -1) | 226 if (_paOutputDeviceIndex == -1) |
| 246 { | 227 { |
| 247 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 228 LOG(LS_WARNING) << "output device index has not been set"; |
| 248 " output device index has not been set"); | |
| 249 return -1; | 229 return -1; |
| 250 } | 230 } |
| 251 | 231 |
| 252 bool setFailed(false); | 232 bool setFailed(false); |
| 253 | 233 |
| 254 if (_paPlayStream && (LATE(pa_stream_get_state)(_paPlayStream) | 234 if (_paPlayStream && (LATE(pa_stream_get_state)(_paPlayStream) |
| 255 != PA_STREAM_UNCONNECTED)) | 235 != PA_STREAM_UNCONNECTED)) |
| 256 { | 236 { |
| 257 // We can only really set the volume if we have a connected stream | 237 // We can only really set the volume if we have a connected stream |
| 258 AutoPulseLock auto_lock(_paMainloop); | 238 AutoPulseLock auto_lock(_paMainloop); |
| 259 | 239 |
| 260 // Get the number of channels from the sample specification | 240 // Get the number of channels from the sample specification |
| 261 const pa_sample_spec *spec = | 241 const pa_sample_spec *spec = |
| 262 LATE(pa_stream_get_sample_spec)(_paPlayStream); | 242 LATE(pa_stream_get_sample_spec)(_paPlayStream); |
| 263 if (!spec) | 243 if (!spec) |
| 264 { | 244 { |
| 265 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 245 LOG(LS_ERROR) << "could not get sample specification"; |
| 266 " could not get sample specification"); | |
| 267 return -1; | 246 return -1; |
| 268 } | 247 } |
| 269 | 248 |
| 270 // Set the same volume for all channels | 249 // Set the same volume for all channels |
| 271 pa_cvolume cVolumes; | 250 pa_cvolume cVolumes; |
| 272 LATE(pa_cvolume_set)(&cVolumes, spec->channels, volume); | 251 LATE(pa_cvolume_set)(&cVolumes, spec->channels, volume); |
| 273 | 252 |
| 274 pa_operation* paOperation = NULL; | 253 pa_operation* paOperation = NULL; |
| 275 paOperation = LATE(pa_context_set_sink_input_volume)( | 254 paOperation = LATE(pa_context_set_sink_input_volume)( |
| 276 _paContext, | 255 _paContext, |
| 277 LATE(pa_stream_get_index)(_paPlayStream), | 256 LATE(pa_stream_get_index)(_paPlayStream), |
| 278 &cVolumes, | 257 &cVolumes, |
| 279 PaSetVolumeCallback, NULL); | 258 PaSetVolumeCallback, NULL); |
| 280 if (!paOperation) | 259 if (!paOperation) |
| 281 { | 260 { |
| 282 setFailed = true; | 261 setFailed = true; |
| 283 } | 262 } |
| 284 | 263 |
| 285 // Don't need to wait for the completion | 264 // Don't need to wait for the completion |
| 286 LATE(pa_operation_unref)(paOperation); | 265 LATE(pa_operation_unref)(paOperation); |
| 287 } else | 266 } else |
| 288 { | 267 { |
| 289 // We have not created a stream or it's not connected to the sink | 268 // We have not created a stream or it's not connected to the sink |
| 290 // Save the volume to be set at connection | 269 // Save the volume to be set at connection |
| 291 _paSpeakerVolume = volume; | 270 _paSpeakerVolume = volume; |
| 292 } | 271 } |
| 293 | 272 |
| 294 if (setFailed) | 273 if (setFailed) |
| 295 { | 274 { |
| 296 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 275 LOG(LS_WARNING) << "could not set speaker volume, error=" |
| 297 " could not set speaker volume, error%d", | 276 << LATE(pa_context_errno)(_paContext); |
| 298 LATE(pa_context_errno)(_paContext)); | |
| 299 | 277 |
| 300 return -1; | 278 return -1; |
| 301 } | 279 } |
| 302 | 280 |
| 303 return 0; | 281 return 0; |
| 304 } | 282 } |
| 305 | 283 |
| 306 int32_t | 284 int32_t |
| 307 AudioMixerManagerLinuxPulse::SpeakerVolume(uint32_t& volume) const | 285 AudioMixerManagerLinuxPulse::SpeakerVolume(uint32_t& volume) const |
| 308 { | 286 { |
| 309 if (_paOutputDeviceIndex == -1) | 287 if (_paOutputDeviceIndex == -1) |
| 310 { | 288 { |
| 311 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 289 LOG(LS_WARNING) << "output device index has not been set"; |
| 312 " output device index has not been set"); | |
| 313 return -1; | 290 return -1; |
| 314 } | 291 } |
| 315 | 292 |
| 316 if (_paPlayStream && (LATE(pa_stream_get_state)(_paPlayStream) | 293 if (_paPlayStream && (LATE(pa_stream_get_state)(_paPlayStream) |
| 317 != PA_STREAM_UNCONNECTED)) | 294 != PA_STREAM_UNCONNECTED)) |
| 318 { | 295 { |
| 319 // We can only get the volume if we have a connected stream | 296 // We can only get the volume if we have a connected stream |
| 320 if (!GetSinkInputInfo()) | 297 if (!GetSinkInputInfo()) |
| 321 return -1; | 298 return -1; |
| 322 | 299 |
| 323 AutoPulseLock auto_lock(_paMainloop); | 300 AutoPulseLock auto_lock(_paMainloop); |
| 324 volume = static_cast<uint32_t> (_paVolume); | 301 volume = static_cast<uint32_t> (_paVolume); |
| 325 } else | 302 } else |
| 326 { | 303 { |
| 327 AutoPulseLock auto_lock(_paMainloop); | 304 AutoPulseLock auto_lock(_paMainloop); |
| 328 volume = _paSpeakerVolume; | 305 volume = _paSpeakerVolume; |
| 329 } | 306 } |
| 330 | 307 |
| 331 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 308 LOG(LS_VERBOSE) << "AudioMixerManagerLinuxPulse::SpeakerVolume() => vol=" |
| 332 "\tAudioMixerManagerLinuxPulse::SpeakerVolume() => vol=%i", | 309 << volume; |
| 333 volume); | |
| 334 | 310 |
| 335 return 0; | 311 return 0; |
| 336 } | 312 } |
| 337 | 313 |
| 338 int32_t | 314 int32_t |
| 339 AudioMixerManagerLinuxPulse::MaxSpeakerVolume(uint32_t& maxVolume) const | 315 AudioMixerManagerLinuxPulse::MaxSpeakerVolume(uint32_t& maxVolume) const |
| 340 { | 316 { |
| 341 | 317 |
| 342 if (_paOutputDeviceIndex == -1) | 318 if (_paOutputDeviceIndex == -1) |
| 343 { | 319 { |
| 344 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 320 LOG(LS_WARNING) << "output device index has not been set"; |
| 345 " output device index has not been set"); | |
| 346 return -1; | 321 return -1; |
| 347 } | 322 } |
| 348 | 323 |
| 349 // PA_VOLUME_NORM corresponds to 100% (0db) | 324 // PA_VOLUME_NORM corresponds to 100% (0db) |
| 350 // but PA allows up to 150 db amplification | 325 // but PA allows up to 150 db amplification |
| 351 maxVolume = static_cast<uint32_t> (PA_VOLUME_NORM); | 326 maxVolume = static_cast<uint32_t> (PA_VOLUME_NORM); |
| 352 | 327 |
| 353 return 0; | 328 return 0; |
| 354 } | 329 } |
| 355 | 330 |
| 356 int32_t | 331 int32_t |
| 357 AudioMixerManagerLinuxPulse::MinSpeakerVolume(uint32_t& minVolume) const | 332 AudioMixerManagerLinuxPulse::MinSpeakerVolume(uint32_t& minVolume) const |
| 358 { | 333 { |
| 359 | 334 |
| 360 if (_paOutputDeviceIndex == -1) | 335 if (_paOutputDeviceIndex == -1) |
| 361 { | 336 { |
| 362 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 337 LOG(LS_WARNING) << "output device index has not been set"; |
| 363 " output device index has not been set"); | |
| 364 return -1; | 338 return -1; |
| 365 } | 339 } |
| 366 | 340 |
| 367 minVolume = static_cast<uint32_t> (PA_VOLUME_MUTED); | 341 minVolume = static_cast<uint32_t> (PA_VOLUME_MUTED); |
| 368 | 342 |
| 369 return 0; | 343 return 0; |
| 370 } | 344 } |
| 371 | 345 |
| 372 int32_t | 346 int32_t |
| 373 AudioMixerManagerLinuxPulse::SpeakerVolumeStepSize(uint16_t& stepSize) const | 347 AudioMixerManagerLinuxPulse::SpeakerVolumeStepSize(uint16_t& stepSize) const |
| 374 { | 348 { |
| 375 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 349 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 376 if (_paOutputDeviceIndex == -1) | 350 if (_paOutputDeviceIndex == -1) |
| 377 { | 351 { |
| 378 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 352 LOG(LS_WARNING) << "output device index has not been set"; |
| 379 " output device index has not been set"); | |
| 380 return -1; | 353 return -1; |
| 381 } | 354 } |
| 382 | 355 |
| 383 // The sink input (stream) will always have step size = 1 | 356 // The sink input (stream) will always have step size = 1 |
| 384 // There are PA_VOLUME_NORM+1 steps | 357 // There are PA_VOLUME_NORM+1 steps |
| 385 stepSize = 1; | 358 stepSize = 1; |
| 386 | 359 |
| 387 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 360 LOG(LS_VERBOSE) |
| 388 "\tAudioMixerManagerLinuxPulse::SpeakerVolumeStepSize() => " | 361 << "AudioMixerManagerLinuxPulse::SpeakerVolumeStepSize() => size=" |
| 389 "size=%i", stepSize); | 362 << stepSize; |
| 390 | 363 |
| 391 return 0; | 364 return 0; |
| 392 } | 365 } |
| 393 | 366 |
| 394 int32_t | 367 int32_t |
| 395 AudioMixerManagerLinuxPulse::SpeakerVolumeIsAvailable(bool& available) | 368 AudioMixerManagerLinuxPulse::SpeakerVolumeIsAvailable(bool& available) |
| 396 { | 369 { |
| 397 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 370 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 398 if (_paOutputDeviceIndex == -1) | 371 if (_paOutputDeviceIndex == -1) |
| 399 { | 372 { |
| 400 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 373 LOG(LS_WARNING) << "output device index has not been set"; |
| 401 " output device index has not been set"); | |
| 402 return -1; | 374 return -1; |
| 403 } | 375 } |
| 404 | 376 |
| 405 // Always available in Pulse Audio | 377 // Always available in Pulse Audio |
| 406 available = true; | 378 available = true; |
| 407 | 379 |
| 408 return 0; | 380 return 0; |
| 409 } | 381 } |
| 410 | 382 |
| 411 int32_t | 383 int32_t |
| 412 AudioMixerManagerLinuxPulse::SpeakerMuteIsAvailable(bool& available) | 384 AudioMixerManagerLinuxPulse::SpeakerMuteIsAvailable(bool& available) |
| 413 { | 385 { |
| 414 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 386 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 415 if (_paOutputDeviceIndex == -1) | 387 if (_paOutputDeviceIndex == -1) |
| 416 { | 388 { |
| 417 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 389 LOG(LS_WARNING) << "output device index has not been set"; |
| 418 " output device index has not been set"); | |
| 419 return -1; | 390 return -1; |
| 420 } | 391 } |
| 421 | 392 |
| 422 // Always available in Pulse Audio | 393 // Always available in Pulse Audio |
| 423 available = true; | 394 available = true; |
| 424 | 395 |
| 425 return 0; | 396 return 0; |
| 426 } | 397 } |
| 427 | 398 |
| 428 int32_t AudioMixerManagerLinuxPulse::SetSpeakerMute(bool enable) | 399 int32_t AudioMixerManagerLinuxPulse::SetSpeakerMute(bool enable) |
| 429 { | 400 { |
| 430 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 401 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 431 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 402 LOG(LS_VERBOSE) << "AudioMixerManagerLinuxPulse::SetSpeakerMute(enable=" |
| 432 "AudioMixerManagerLinuxPulse::SetSpeakerMute(enable=%u)", | 403 << enable << ")"; |
| 433 enable); | |
| 434 | 404 |
| 435 if (_paOutputDeviceIndex == -1) | 405 if (_paOutputDeviceIndex == -1) |
| 436 { | 406 { |
| 437 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 407 LOG(LS_WARNING) << "output device index has not been set"; |
| 438 " output device index has not been set"); | |
| 439 return -1; | 408 return -1; |
| 440 } | 409 } |
| 441 | 410 |
| 442 bool setFailed(false); | 411 bool setFailed(false); |
| 443 | 412 |
| 444 if (_paPlayStream && (LATE(pa_stream_get_state)(_paPlayStream) | 413 if (_paPlayStream && (LATE(pa_stream_get_state)(_paPlayStream) |
| 445 != PA_STREAM_UNCONNECTED)) | 414 != PA_STREAM_UNCONNECTED)) |
| 446 { | 415 { |
| 447 // We can only really mute if we have a connected stream | 416 // We can only really mute if we have a connected stream |
| 448 AutoPulseLock auto_lock(_paMainloop); | 417 AutoPulseLock auto_lock(_paMainloop); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 463 LATE(pa_operation_unref)(paOperation); | 432 LATE(pa_operation_unref)(paOperation); |
| 464 } else | 433 } else |
| 465 { | 434 { |
| 466 // We have not created a stream or it's not connected to the sink | 435 // We have not created a stream or it's not connected to the sink |
| 467 // Save the mute status to be set at connection | 436 // Save the mute status to be set at connection |
| 468 _paSpeakerMute = enable; | 437 _paSpeakerMute = enable; |
| 469 } | 438 } |
| 470 | 439 |
| 471 if (setFailed) | 440 if (setFailed) |
| 472 { | 441 { |
| 473 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 442 LOG(LS_WARNING) << "could not mute speaker, error=" |
| 474 " could not mute speaker, error%d", | 443 << LATE(pa_context_errno)(_paContext); |
| 475 LATE(pa_context_errno)(_paContext)); | |
| 476 return -1; | 444 return -1; |
| 477 } | 445 } |
| 478 | 446 |
| 479 return 0; | 447 return 0; |
| 480 } | 448 } |
| 481 | 449 |
| 482 int32_t AudioMixerManagerLinuxPulse::SpeakerMute(bool& enabled) const | 450 int32_t AudioMixerManagerLinuxPulse::SpeakerMute(bool& enabled) const |
| 483 { | 451 { |
| 484 | 452 |
| 485 if (_paOutputDeviceIndex == -1) | 453 if (_paOutputDeviceIndex == -1) |
| 486 { | 454 { |
| 487 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 455 LOG(LS_WARNING) << "output device index has not been set"; |
| 488 " output device index has not been set"); | |
| 489 return -1; | 456 return -1; |
| 490 } | 457 } |
| 491 | 458 |
| 492 if (_paPlayStream && (LATE(pa_stream_get_state)(_paPlayStream) | 459 if (_paPlayStream && (LATE(pa_stream_get_state)(_paPlayStream) |
| 493 != PA_STREAM_UNCONNECTED)) | 460 != PA_STREAM_UNCONNECTED)) |
| 494 { | 461 { |
| 495 // We can only get the mute status if we have a connected stream | 462 // We can only get the mute status if we have a connected stream |
| 496 if (!GetSinkInputInfo()) | 463 if (!GetSinkInputInfo()) |
| 497 return -1; | 464 return -1; |
| 498 | 465 |
| 499 enabled = static_cast<bool> (_paMute); | 466 enabled = static_cast<bool> (_paMute); |
| 500 } else | 467 } else |
| 501 { | 468 { |
| 502 enabled = _paSpeakerMute; | 469 enabled = _paSpeakerMute; |
| 503 } | 470 } |
| 504 | 471 LOG(LS_VERBOSE) << "AudioMixerManagerLinuxPulse::SpeakerMute() => enabled=" |
| 505 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 472 << enabled; |
| 506 " AudioMixerManagerLinuxPulse::SpeakerMute() => " | |
| 507 "enabled=%i, enabled"); | |
| 508 | 473 |
| 509 return 0; | 474 return 0; |
| 510 } | 475 } |
| 511 | 476 |
| 512 int32_t | 477 int32_t |
| 513 AudioMixerManagerLinuxPulse::StereoPlayoutIsAvailable(bool& available) | 478 AudioMixerManagerLinuxPulse::StereoPlayoutIsAvailable(bool& available) |
| 514 { | 479 { |
| 515 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 480 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 516 if (_paOutputDeviceIndex == -1) | 481 if (_paOutputDeviceIndex == -1) |
| 517 { | 482 { |
| 518 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 483 LOG(LS_WARNING) << "output device index has not been set"; |
| 519 " output device index has not been set"); | |
| 520 return -1; | 484 return -1; |
| 521 } | 485 } |
| 522 | 486 |
| 523 uint32_t deviceIndex = (uint32_t) _paOutputDeviceIndex; | 487 uint32_t deviceIndex = (uint32_t) _paOutputDeviceIndex; |
| 524 | 488 |
| 525 { | 489 { |
| 526 AutoPulseLock auto_lock(_paMainloop); | 490 AutoPulseLock auto_lock(_paMainloop); |
| 527 | 491 |
| 528 // Get the actual stream device index if we have a connected stream | 492 // Get the actual stream device index if we have a connected stream |
| 529 // The device used by the stream can be changed | 493 // The device used by the stream can be changed |
| (...skipping 12 matching lines...) Expand all Loading... |
| 542 | 506 |
| 543 return 0; | 507 return 0; |
| 544 } | 508 } |
| 545 | 509 |
| 546 int32_t | 510 int32_t |
| 547 AudioMixerManagerLinuxPulse::StereoRecordingIsAvailable(bool& available) | 511 AudioMixerManagerLinuxPulse::StereoRecordingIsAvailable(bool& available) |
| 548 { | 512 { |
| 549 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 513 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 550 if (_paInputDeviceIndex == -1) | 514 if (_paInputDeviceIndex == -1) |
| 551 { | 515 { |
| 552 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 516 LOG(LS_WARNING) << "input device index has not been set"; |
| 553 " input device index has not been set"); | |
| 554 return -1; | 517 return -1; |
| 555 } | 518 } |
| 556 | 519 |
| 557 uint32_t deviceIndex = (uint32_t) _paInputDeviceIndex; | 520 uint32_t deviceIndex = (uint32_t) _paInputDeviceIndex; |
| 558 | 521 |
| 559 AutoPulseLock auto_lock(_paMainloop); | 522 AutoPulseLock auto_lock(_paMainloop); |
| 560 | 523 |
| 561 // Get the actual stream device index if we have a connected stream | 524 // Get the actual stream device index if we have a connected stream |
| 562 // The device used by the stream can be changed | 525 // The device used by the stream can be changed |
| 563 // during the call | 526 // during the call |
| 564 if (_paRecStream && (LATE(pa_stream_get_state)(_paRecStream) | 527 if (_paRecStream && (LATE(pa_stream_get_state)(_paRecStream) |
| 565 != PA_STREAM_UNCONNECTED)) | 528 != PA_STREAM_UNCONNECTED)) |
| 566 { | 529 { |
| 567 deviceIndex = LATE(pa_stream_get_device_index)(_paRecStream); | 530 deviceIndex = LATE(pa_stream_get_device_index)(_paRecStream); |
| 568 } | 531 } |
| 569 | 532 |
| 570 pa_operation* paOperation = NULL; | 533 pa_operation* paOperation = NULL; |
| 571 | 534 |
| 572 // Get info for this source | 535 // Get info for this source |
| 573 // We want to know if the actual device can record in stereo | 536 // We want to know if the actual device can record in stereo |
| 574 paOperation = LATE(pa_context_get_source_info_by_index)( | 537 paOperation = LATE(pa_context_get_source_info_by_index)( |
| 575 _paContext, deviceIndex, | 538 _paContext, deviceIndex, |
| 576 PaSourceInfoCallback, | 539 PaSourceInfoCallback, |
| 577 (void*) this); | 540 (void*) this); |
| 578 | 541 |
| 579 WaitForOperationCompletion(paOperation); | 542 WaitForOperationCompletion(paOperation); |
| 580 | 543 |
| 581 available = static_cast<bool> (_paChannels == 2); | 544 available = static_cast<bool> (_paChannels == 2); |
| 582 | 545 |
| 583 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 546 LOG(LS_VERBOSE) |
| 584 " AudioMixerManagerLinuxPulse::StereoRecordingIsAvailable()" | 547 << "AudioMixerManagerLinuxPulse::StereoRecordingIsAvailable()" |
| 585 " => available=%i, available"); | 548 << " => available=" << available; |
| 586 | 549 |
| 587 return 0; | 550 return 0; |
| 588 } | 551 } |
| 589 | 552 |
| 590 int32_t AudioMixerManagerLinuxPulse::MicrophoneMuteIsAvailable( | 553 int32_t AudioMixerManagerLinuxPulse::MicrophoneMuteIsAvailable( |
| 591 bool& available) | 554 bool& available) |
| 592 { | 555 { |
| 593 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 556 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 594 if (_paInputDeviceIndex == -1) | 557 if (_paInputDeviceIndex == -1) |
| 595 { | 558 { |
| 596 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 559 LOG(LS_WARNING) << "input device index has not been set"; |
| 597 " input device index has not been set"); | |
| 598 return -1; | 560 return -1; |
| 599 } | 561 } |
| 600 | 562 |
| 601 // Always available in Pulse Audio | 563 // Always available in Pulse Audio |
| 602 available = true; | 564 available = true; |
| 603 | 565 |
| 604 return 0; | 566 return 0; |
| 605 } | 567 } |
| 606 | 568 |
| 607 int32_t AudioMixerManagerLinuxPulse::SetMicrophoneMute(bool enable) | 569 int32_t AudioMixerManagerLinuxPulse::SetMicrophoneMute(bool enable) |
| 608 { | 570 { |
| 609 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 571 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 610 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 572 LOG(LS_VERBOSE) << "AudioMixerManagerLinuxPulse::SetMicrophoneMute(enable=" |
| 611 "AudioMixerManagerLinuxPulse::SetMicrophoneMute(enable=%u)", | 573 << enable << ")"; |
| 612 enable); | |
| 613 | 574 |
| 614 if (_paInputDeviceIndex == -1) | 575 if (_paInputDeviceIndex == -1) |
| 615 { | 576 { |
| 616 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 577 LOG(LS_WARNING) << "input device index has not been set"; |
| 617 " input device index has not been set"); | |
| 618 return -1; | 578 return -1; |
| 619 } | 579 } |
| 620 | 580 |
| 621 bool setFailed(false); | 581 bool setFailed(false); |
| 622 pa_operation* paOperation = NULL; | 582 pa_operation* paOperation = NULL; |
| 623 | 583 |
| 624 uint32_t deviceIndex = (uint32_t) _paInputDeviceIndex; | 584 uint32_t deviceIndex = (uint32_t) _paInputDeviceIndex; |
| 625 | 585 |
| 626 AutoPulseLock auto_lock(_paMainloop); | 586 AutoPulseLock auto_lock(_paMainloop); |
| 627 | 587 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 643 if (!paOperation) | 603 if (!paOperation) |
| 644 { | 604 { |
| 645 setFailed = true; | 605 setFailed = true; |
| 646 } | 606 } |
| 647 | 607 |
| 648 // Don't need to wait for this to complete. | 608 // Don't need to wait for this to complete. |
| 649 LATE(pa_operation_unref)(paOperation); | 609 LATE(pa_operation_unref)(paOperation); |
| 650 | 610 |
| 651 if (setFailed) | 611 if (setFailed) |
| 652 { | 612 { |
| 653 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 613 LOG(LS_WARNING) << "could not mute microphone, error=" |
| 654 " could not mute microphone, error%d", | 614 << LATE(pa_context_errno)(_paContext); |
| 655 LATE(pa_context_errno)(_paContext)); | |
| 656 return -1; | 615 return -1; |
| 657 } | 616 } |
| 658 | 617 |
| 659 return 0; | 618 return 0; |
| 660 } | 619 } |
| 661 | 620 |
| 662 int32_t AudioMixerManagerLinuxPulse::MicrophoneMute(bool& enabled) const | 621 int32_t AudioMixerManagerLinuxPulse::MicrophoneMute(bool& enabled) const |
| 663 { | 622 { |
| 664 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 623 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 665 if (_paInputDeviceIndex == -1) | 624 if (_paInputDeviceIndex == -1) |
| 666 { | 625 { |
| 667 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 626 LOG(LS_WARNING) << "input device index has not been set"; |
| 668 " input device index has not been set"); | |
| 669 return -1; | 627 return -1; |
| 670 } | 628 } |
| 671 | 629 |
| 672 uint32_t deviceIndex = (uint32_t) _paInputDeviceIndex; | 630 uint32_t deviceIndex = (uint32_t) _paInputDeviceIndex; |
| 673 | 631 |
| 674 { | 632 { |
| 675 AutoPulseLock auto_lock(_paMainloop); | 633 AutoPulseLock auto_lock(_paMainloop); |
| 676 // Get the actual stream device index if we have a connected stream | 634 // Get the actual stream device index if we have a connected stream |
| 677 // The device used by the stream can be changed | 635 // The device used by the stream can be changed |
| 678 // during the call | 636 // during the call |
| 679 if (_paRecStream && (LATE(pa_stream_get_state)(_paRecStream) | 637 if (_paRecStream && (LATE(pa_stream_get_state)(_paRecStream) |
| 680 != PA_STREAM_UNCONNECTED)) | 638 != PA_STREAM_UNCONNECTED)) |
| 681 { | 639 { |
| 682 deviceIndex = LATE(pa_stream_get_device_index)(_paRecStream); | 640 deviceIndex = LATE(pa_stream_get_device_index)(_paRecStream); |
| 683 } | 641 } |
| 684 } | 642 } |
| 685 | 643 |
| 686 if (!GetSourceInfoByIndex(deviceIndex)) | 644 if (!GetSourceInfoByIndex(deviceIndex)) |
| 687 return -1; | 645 return -1; |
| 688 | 646 |
| 689 enabled = static_cast<bool> (_paMute); | 647 enabled = static_cast<bool> (_paMute); |
| 690 | 648 |
| 691 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 649 LOG(LS_VERBOSE) |
| 692 "\tAudioMixerManagerLinuxPulse::MicrophoneMute() =>" | 650 << "AudioMixerManagerLinuxPulse::MicrophoneMute() => enabled=" |
| 693 " enabled=%i", enabled); | 651 << enabled; |
| 694 | 652 |
| 695 return 0; | 653 return 0; |
| 696 } | 654 } |
| 697 | 655 |
| 698 int32_t | 656 int32_t |
| 699 AudioMixerManagerLinuxPulse::MicrophoneBoostIsAvailable(bool& available) | 657 AudioMixerManagerLinuxPulse::MicrophoneBoostIsAvailable(bool& available) |
| 700 { | 658 { |
| 701 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 659 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 702 if (_paInputDeviceIndex == -1) | 660 if (_paInputDeviceIndex == -1) |
| 703 { | 661 { |
| 704 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 662 LOG(LS_WARNING) << "input device index has not been set"; |
| 705 " input device index has not been set"); | |
| 706 return -1; | 663 return -1; |
| 707 } | 664 } |
| 708 | 665 |
| 709 // Always unavailable in Pulse Audio | 666 // Always unavailable in Pulse Audio |
| 710 // Could make it possible to use PA_VOLUME_MAX | 667 // Could make it possible to use PA_VOLUME_MAX |
| 711 // but that gives bad audio with some sound cards | 668 // but that gives bad audio with some sound cards |
| 712 available = false; | 669 available = false; |
| 713 | 670 |
| 714 return 0; | 671 return 0; |
| 715 } | 672 } |
| 716 | 673 |
| 717 int32_t AudioMixerManagerLinuxPulse::SetMicrophoneBoost(bool enable) | 674 int32_t AudioMixerManagerLinuxPulse::SetMicrophoneBoost(bool enable) |
| 718 { | 675 { |
| 719 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 676 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 720 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 677 LOG(LS_VERBOSE) << "AudioMixerManagerLinuxPulse::SetMicrophoneBoost(enable=" |
| 721 "AudioMixerManagerLinuxPulse::SetMicrophoneBoost(enable=%u)", | 678 << enable << ")"; |
| 722 enable); | |
| 723 | 679 |
| 724 if (_paInputDeviceIndex == -1) | 680 if (_paInputDeviceIndex == -1) |
| 725 { | 681 { |
| 726 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 682 LOG(LS_WARNING) << "input device index has not been set"; |
| 727 " input device index has not been set"); | |
| 728 return -1; | 683 return -1; |
| 729 } | 684 } |
| 730 | 685 |
| 731 // Ensure the selected microphone destination has a valid boost control | 686 // Ensure the selected microphone destination has a valid boost control |
| 732 bool available(false); | 687 bool available(false); |
| 733 MicrophoneBoostIsAvailable(available); | 688 MicrophoneBoostIsAvailable(available); |
| 734 if (!available) | 689 if (!available) |
| 735 { | 690 { |
| 736 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 691 LOG(LS_WARNING) << "it is not possible to enable microphone boost"; |
| 737 " it is not possible to enable microphone boost"); | |
| 738 return -1; | 692 return -1; |
| 739 } | 693 } |
| 740 | 694 |
| 741 // It is assumed that the call above fails! | 695 // It is assumed that the call above fails! |
| 742 | 696 |
| 743 return 0; | 697 return 0; |
| 744 } | 698 } |
| 745 | 699 |
| 746 int32_t AudioMixerManagerLinuxPulse::MicrophoneBoost(bool& enabled) const | 700 int32_t AudioMixerManagerLinuxPulse::MicrophoneBoost(bool& enabled) const |
| 747 { | 701 { |
| 748 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 702 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 749 if (_paInputDeviceIndex == -1) | 703 if (_paInputDeviceIndex == -1) |
| 750 { | 704 { |
| 751 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 705 LOG(LS_WARNING) << "input device index has not been set"; |
| 752 " input device index has not been set"); | |
| 753 return -1; | 706 return -1; |
| 754 } | 707 } |
| 755 | 708 |
| 756 // Microphone boost cannot be enabled on this platform! | 709 // Microphone boost cannot be enabled on this platform! |
| 757 enabled = false; | 710 enabled = false; |
| 758 | 711 |
| 759 return 0; | 712 return 0; |
| 760 } | 713 } |
| 761 | 714 |
| 762 int32_t AudioMixerManagerLinuxPulse::MicrophoneVolumeIsAvailable( | 715 int32_t AudioMixerManagerLinuxPulse::MicrophoneVolumeIsAvailable( |
| 763 bool& available) | 716 bool& available) |
| 764 { | 717 { |
| 765 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 718 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 766 if (_paInputDeviceIndex == -1) | 719 if (_paInputDeviceIndex == -1) |
| 767 { | 720 { |
| 768 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 721 LOG(LS_WARNING) << "input device index has not been set"; |
| 769 " input device index has not been set"); | |
| 770 return -1; | 722 return -1; |
| 771 } | 723 } |
| 772 | 724 |
| 773 // Always available in Pulse Audio | 725 // Always available in Pulse Audio |
| 774 available = true; | 726 available = true; |
| 775 | 727 |
| 776 return 0; | 728 return 0; |
| 777 } | 729 } |
| 778 | 730 |
| 779 int32_t | 731 int32_t |
| 780 AudioMixerManagerLinuxPulse::SetMicrophoneVolume(uint32_t volume) | 732 AudioMixerManagerLinuxPulse::SetMicrophoneVolume(uint32_t volume) |
| 781 { | 733 { |
| 782 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 734 LOG(LS_VERBOSE) |
| 783 "AudioMixerManagerLinuxPulse::SetMicrophoneVolume" | 735 << "AudioMixerManagerLinuxPulse::SetMicrophoneVolume(volume=" << volume |
| 784 "(volume=%u)", volume); | 736 << ")"; |
| 785 | 737 |
| 786 if (_paInputDeviceIndex == -1) | 738 if (_paInputDeviceIndex == -1) |
| 787 { | 739 { |
| 788 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 740 LOG(LS_WARNING) << "input device index has not been set"; |
| 789 " input device index has not been set"); | |
| 790 return -1; | 741 return -1; |
| 791 } | 742 } |
| 792 | 743 |
| 793 // Unlike output streams, input streams have no concept of a stream | 744 // Unlike output streams, input streams have no concept of a stream |
| 794 // volume, only a device volume. So we have to change the volume of the | 745 // volume, only a device volume. So we have to change the volume of the |
| 795 // device itself. | 746 // device itself. |
| 796 | 747 |
| 797 // The device may have a different number of channels than the stream and | 748 // The device may have a different number of channels than the stream and |
| 798 // their mapping may be different, so we don't want to use the channel | 749 // their mapping may be different, so we don't want to use the channel |
| 799 // count from our sample spec. We could use PA_CHANNELS_MAX to cover our | 750 // count from our sample spec. We could use PA_CHANNELS_MAX to cover our |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 838 if (!paOperation) | 789 if (!paOperation) |
| 839 { | 790 { |
| 840 setFailed = true; | 791 setFailed = true; |
| 841 } | 792 } |
| 842 | 793 |
| 843 // Don't need to wait for this to complete. | 794 // Don't need to wait for this to complete. |
| 844 LATE(pa_operation_unref)(paOperation); | 795 LATE(pa_operation_unref)(paOperation); |
| 845 | 796 |
| 846 if (setFailed) | 797 if (setFailed) |
| 847 { | 798 { |
| 848 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 799 LOG(LS_WARNING) << "could not set microphone volume, error=" |
| 849 " could not set microphone volume, error%d", | 800 << LATE(pa_context_errno)(_paContext); |
| 850 LATE(pa_context_errno)(_paContext)); | |
| 851 return -1; | 801 return -1; |
| 852 } | 802 } |
| 853 | 803 |
| 854 return 0; | 804 return 0; |
| 855 } | 805 } |
| 856 | 806 |
| 857 int32_t | 807 int32_t |
| 858 AudioMixerManagerLinuxPulse::MicrophoneVolume(uint32_t& volume) const | 808 AudioMixerManagerLinuxPulse::MicrophoneVolume(uint32_t& volume) const |
| 859 { | 809 { |
| 860 | 810 |
| 861 if (_paInputDeviceIndex == -1) | 811 if (_paInputDeviceIndex == -1) |
| 862 { | 812 { |
| 863 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 813 LOG(LS_WARNING) << "input device index has not been set"; |
| 864 " input device index has not been set"); | |
| 865 return -1; | 814 return -1; |
| 866 } | 815 } |
| 867 | 816 |
| 868 uint32_t deviceIndex = (uint32_t) _paInputDeviceIndex; | 817 uint32_t deviceIndex = (uint32_t) _paInputDeviceIndex; |
| 869 | 818 |
| 870 { | 819 { |
| 871 AutoPulseLock auto_lock(_paMainloop); | 820 AutoPulseLock auto_lock(_paMainloop); |
| 872 // Get the actual stream device index if we have a connected stream. | 821 // Get the actual stream device index if we have a connected stream. |
| 873 // The device used by the stream can be changed during the call. | 822 // The device used by the stream can be changed during the call. |
| 874 if (_paRecStream && (LATE(pa_stream_get_state)(_paRecStream) | 823 if (_paRecStream && (LATE(pa_stream_get_state)(_paRecStream) |
| 875 != PA_STREAM_UNCONNECTED)) | 824 != PA_STREAM_UNCONNECTED)) |
| 876 { | 825 { |
| 877 deviceIndex = LATE(pa_stream_get_device_index)(_paRecStream); | 826 deviceIndex = LATE(pa_stream_get_device_index)(_paRecStream); |
| 878 } | 827 } |
| 879 } | 828 } |
| 880 | 829 |
| 881 if (!GetSourceInfoByIndex(deviceIndex)) | 830 if (!GetSourceInfoByIndex(deviceIndex)) |
| 882 return -1; | 831 return -1; |
| 883 | 832 |
| 884 { | 833 { |
| 885 AutoPulseLock auto_lock(_paMainloop); | 834 AutoPulseLock auto_lock(_paMainloop); |
| 886 volume = static_cast<uint32_t> (_paVolume); | 835 volume = static_cast<uint32_t> (_paVolume); |
| 887 } | 836 } |
| 888 | 837 |
| 889 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 838 LOG(LS_VERBOSE) |
| 890 " AudioMixerManagerLinuxPulse::MicrophoneVolume()" | 839 << "AudioMixerManagerLinuxPulse::MicrophoneVolume() => vol=" |
| 891 " => vol=%i, volume"); | 840 << volume; |
| 892 | 841 |
| 893 return 0; | 842 return 0; |
| 894 } | 843 } |
| 895 | 844 |
| 896 int32_t | 845 int32_t |
| 897 AudioMixerManagerLinuxPulse::MaxMicrophoneVolume(uint32_t& maxVolume) const | 846 AudioMixerManagerLinuxPulse::MaxMicrophoneVolume(uint32_t& maxVolume) const |
| 898 { | 847 { |
| 899 | 848 |
| 900 if (_paInputDeviceIndex == -1) | 849 if (_paInputDeviceIndex == -1) |
| 901 { | 850 { |
| 902 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 851 LOG(LS_WARNING) << "input device index has not been set"; |
| 903 " input device index has not been set"); | |
| 904 return -1; | 852 return -1; |
| 905 } | 853 } |
| 906 | 854 |
| 907 // PA_VOLUME_NORM corresponds to 100% (0db) | 855 // PA_VOLUME_NORM corresponds to 100% (0db) |
| 908 // PA allows up to 150 db amplification (PA_VOLUME_MAX) | 856 // PA allows up to 150 db amplification (PA_VOLUME_MAX) |
| 909 // but that doesn't work well for all sound cards | 857 // but that doesn't work well for all sound cards |
| 910 maxVolume = static_cast<uint32_t> (PA_VOLUME_NORM); | 858 maxVolume = static_cast<uint32_t> (PA_VOLUME_NORM); |
| 911 | 859 |
| 912 return 0; | 860 return 0; |
| 913 } | 861 } |
| 914 | 862 |
| 915 int32_t | 863 int32_t |
| 916 AudioMixerManagerLinuxPulse::MinMicrophoneVolume(uint32_t& minVolume) const | 864 AudioMixerManagerLinuxPulse::MinMicrophoneVolume(uint32_t& minVolume) const |
| 917 { | 865 { |
| 918 | 866 |
| 919 if (_paInputDeviceIndex == -1) | 867 if (_paInputDeviceIndex == -1) |
| 920 { | 868 { |
| 921 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 869 LOG(LS_WARNING) << "input device index has not been set"; |
| 922 " input device index has not been set"); | |
| 923 return -1; | 870 return -1; |
| 924 } | 871 } |
| 925 | 872 |
| 926 minVolume = static_cast<uint32_t> (PA_VOLUME_MUTED); | 873 minVolume = static_cast<uint32_t> (PA_VOLUME_MUTED); |
| 927 | 874 |
| 928 return 0; | 875 return 0; |
| 929 } | 876 } |
| 930 | 877 |
| 931 int32_t AudioMixerManagerLinuxPulse::MicrophoneVolumeStepSize( | 878 int32_t AudioMixerManagerLinuxPulse::MicrophoneVolumeStepSize( |
| 932 uint16_t& stepSize) const | 879 uint16_t& stepSize) const |
| 933 { | 880 { |
| 934 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 881 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 935 if (_paInputDeviceIndex == -1) | 882 if (_paInputDeviceIndex == -1) |
| 936 { | 883 { |
| 937 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 884 LOG(LS_WARNING) << "input device index has not been set"; |
| 938 " input device index has not been set"); | |
| 939 return -1; | 885 return -1; |
| 940 } | 886 } |
| 941 | 887 |
| 942 uint32_t deviceIndex = (uint32_t) _paInputDeviceIndex; | 888 uint32_t deviceIndex = (uint32_t) _paInputDeviceIndex; |
| 943 | 889 |
| 944 AutoPulseLock auto_lock(_paMainloop); | 890 AutoPulseLock auto_lock(_paMainloop); |
| 945 | 891 |
| 946 // Get the actual stream device index if we have a connected stream | 892 // Get the actual stream device index if we have a connected stream |
| 947 // The device used by the stream can be changed | 893 // The device used by the stream can be changed |
| 948 // during the call | 894 // during the call |
| 949 if (_paRecStream && (LATE(pa_stream_get_state)(_paRecStream) | 895 if (_paRecStream && (LATE(pa_stream_get_state)(_paRecStream) |
| 950 != PA_STREAM_UNCONNECTED)) | 896 != PA_STREAM_UNCONNECTED)) |
| 951 { | 897 { |
| 952 deviceIndex = LATE(pa_stream_get_device_index)(_paRecStream); | 898 deviceIndex = LATE(pa_stream_get_device_index)(_paRecStream); |
| 953 } | 899 } |
| 954 | 900 |
| 955 pa_operation* paOperation = NULL; | 901 pa_operation* paOperation = NULL; |
| 956 | 902 |
| 957 // Get info for this source | 903 // Get info for this source |
| 958 paOperation | 904 paOperation |
| 959 = LATE(pa_context_get_source_info_by_index)(_paContext, deviceIndex, | 905 = LATE(pa_context_get_source_info_by_index)(_paContext, deviceIndex, |
| 960 PaSourceInfoCallback, | 906 PaSourceInfoCallback, |
| 961 (void*) this); | 907 (void*) this); |
| 962 | 908 |
| 963 WaitForOperationCompletion(paOperation); | 909 WaitForOperationCompletion(paOperation); |
| 964 | 910 |
| 965 stepSize = static_cast<uint16_t> ((PA_VOLUME_NORM + 1) / _paVolSteps); | 911 stepSize = static_cast<uint16_t> ((PA_VOLUME_NORM + 1) / _paVolSteps); |
| 966 | 912 |
| 967 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 913 LOG(LS_VERBOSE) |
| 968 "\tAudioMixerManagerLinuxPulse::MicrophoneVolumeStepSize()" | 914 << "AudioMixerManagerLinuxPulse::MicrophoneVolumeStepSize() => size=" |
| 969 " => size=%i", stepSize); | 915 << stepSize; |
| 970 | 916 |
| 971 return 0; | 917 return 0; |
| 972 } | 918 } |
| 973 | 919 |
| 974 // =========================================================================== | 920 // =========================================================================== |
| 975 // Private Methods | 921 // Private Methods |
| 976 // =========================================================================== | 922 // =========================================================================== |
| 977 | 923 |
| 978 void | 924 void |
| 979 AudioMixerManagerLinuxPulse::PaSinkInfoCallback(pa_context */*c*/, | 925 AudioMixerManagerLinuxPulse::PaSinkInfoCallback(pa_context */*c*/, |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1007 PaSourceInfoCallbackHandler(i, eol); | 953 PaSourceInfoCallbackHandler(i, eol); |
| 1008 } | 954 } |
| 1009 | 955 |
| 1010 void | 956 void |
| 1011 AudioMixerManagerLinuxPulse::PaSetVolumeCallback(pa_context * c, | 957 AudioMixerManagerLinuxPulse::PaSetVolumeCallback(pa_context * c, |
| 1012 int success, | 958 int success, |
| 1013 void */*pThis*/) | 959 void */*pThis*/) |
| 1014 { | 960 { |
| 1015 if (!success) | 961 if (!success) |
| 1016 { | 962 { |
| 1017 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, -1, | 963 LOG(LS_ERROR) << "failed to set volume"; |
| 1018 " failed to set volume"); | |
| 1019 } | 964 } |
| 1020 } | 965 } |
| 1021 | 966 |
| 1022 void AudioMixerManagerLinuxPulse::PaSinkInfoCallbackHandler( | 967 void AudioMixerManagerLinuxPulse::PaSinkInfoCallbackHandler( |
| 1023 const pa_sink_info *i, | 968 const pa_sink_info *i, |
| 1024 int eol) | 969 int eol) |
| 1025 { | 970 { |
| 1026 if (eol) | 971 if (eol) |
| 1027 { | 972 { |
| 1028 // Signal that we are done | 973 // Signal that we are done |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1145 | 1090 |
| 1146 AutoPulseLock auto_lock(_paMainloop); | 1091 AutoPulseLock auto_lock(_paMainloop); |
| 1147 paOperation = LATE(pa_context_get_source_info_by_index)( | 1092 paOperation = LATE(pa_context_get_source_info_by_index)( |
| 1148 _paContext, device_index, PaSourceInfoCallback, (void*) this); | 1093 _paContext, device_index, PaSourceInfoCallback, (void*) this); |
| 1149 | 1094 |
| 1150 WaitForOperationCompletion(paOperation); | 1095 WaitForOperationCompletion(paOperation); |
| 1151 return true; | 1096 return true; |
| 1152 } | 1097 } |
| 1153 | 1098 |
| 1154 } | 1099 } |
| OLD | NEW |