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 113f45c2e0ac4cb280f941efa3a3476895795e3dd6pbos@webrtc.org#include <assert.h> 12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 13bc669ace8f09d73e95f923253ecdadd366f9b7f1pbos@webrtc.org#include "webrtc/modules/audio_device/linux/audio_mixer_manager_pulse_linux.h" 14bc669ace8f09d73e95f923253ecdadd366f9b7f1pbos@webrtc.org#include "webrtc/system_wrappers/interface/trace.h" 15b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 16b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgextern webrtc_adm_linux_pulse::PulseAudioSymbolTable PaSymbolTable; 17b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 18b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Accesses Pulse functions through our late-binding symbol table instead of 19b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// directly. This way we don't have to link to libpulse, which means our binary 20b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// will work on systems that don't have it. 21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#define LATE(sym) \ 22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LATESYM_GET(webrtc_adm_linux_pulse::PulseAudioSymbolTable, &PaSymbolTable, sym) 23b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgnamespace webrtc 25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgenum { kMaxRetryOnFailure = 2 }; 28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2964a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgAudioMixerManagerLinuxPulse::AudioMixerManagerLinuxPulse(const int32_t id) : 30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _critSect(*CriticalSectionWrapper::CreateCriticalSection()), 31b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _id(id), 32b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paOutputDeviceIndex(-1), 33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paInputDeviceIndex(-1), 34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paPlayStream(NULL), 35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paRecStream(NULL), 36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paMainloop(NULL), 37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paContext(NULL), 38b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paVolume(0), 39b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paMute(0), 40b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paVolSteps(0), 41b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paSpeakerMute(false), 42b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paSpeakerVolume(PA_VOLUME_NORM), 43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paChannels(0), 44b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paObjectsSet(false), 45b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _callbackValues(false) 46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, 48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "%s constructed", __FUNCTION__); 49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgAudioMixerManagerLinuxPulse::~AudioMixerManagerLinuxPulse() 52b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 53b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, 54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "%s destructed", __FUNCTION__); 55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Close(); 57b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 58b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org delete &_critSect; 59b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// ============================================================================ 62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// PUBLIC METHODS 63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// ============================================================================ 64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 6564a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgint32_t AudioMixerManagerLinuxPulse::SetPulseAudioObjects( 66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pa_threaded_mainloop* mainloop, 67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pa_context* context) 68b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "%s", 70b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org __FUNCTION__); 71b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped lock(&_critSect); 73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 74b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!mainloop || !context) 75b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 76b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, 77b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " could not set PulseAudio objects for mixer"); 78b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 79b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paMainloop = mainloop; 82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paContext = context; 83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paObjectsSet = true; 84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, 86b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " the PulseAudio objects for the mixer has been set"); 87b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 89b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 90b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 9164a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgint32_t AudioMixerManagerLinuxPulse::Close() 92b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 93b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "%s", 94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org __FUNCTION__); 95b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 96b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped lock(&_critSect); 97b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 98b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CloseSpeaker(); 99b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CloseMicrophone(); 100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paMainloop = NULL; 102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paContext = NULL; 103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paObjectsSet = false; 104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 10964a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgint32_t AudioMixerManagerLinuxPulse::CloseSpeaker() 110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "%s", 112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org __FUNCTION__); 113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped lock(&_critSect); 115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Reset the index to -1 117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paOutputDeviceIndex = -1; 118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paPlayStream = NULL; 119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 12364a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgint32_t AudioMixerManagerLinuxPulse::CloseMicrophone() 124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "%s", 126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org __FUNCTION__); 127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped lock(&_critSect); 129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Reset the index to -1 131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paInputDeviceIndex = -1; 132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paRecStream = NULL; 133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 13764a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgint32_t AudioMixerManagerLinuxPulse::SetPlayStream(pa_stream* playStream) 138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 139b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, 140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "AudioMixerManagerLinuxPulse::SetPlayStream(playStream)"); 141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped lock(&_critSect); 143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paPlayStream = playStream; 144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 14764a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgint32_t AudioMixerManagerLinuxPulse::SetRecStream(pa_stream* recStream) 148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 149b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, 150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "AudioMixerManagerLinuxPulse::SetRecStream(recStream)"); 151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped lock(&_critSect); 153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paRecStream = recStream; 154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 155b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 15764a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgint32_t AudioMixerManagerLinuxPulse::OpenSpeaker( 15864a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org uint16_t deviceIndex) 159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, 161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "AudioMixerManagerLinuxPulse::OpenSpeaker(deviceIndex=%d)", 162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org deviceIndex); 163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped lock(&_critSect); 165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // No point in opening the speaker 167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // if PA objects have not been set 168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!_paObjectsSet) 169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, 171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " PulseAudio objects has not been set"); 172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 174b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Set the index for the PulseAudio 176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // output device to control 177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paOutputDeviceIndex = deviceIndex; 178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, 180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " the output mixer device is now open"); 181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 18564a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgint32_t AudioMixerManagerLinuxPulse::OpenMicrophone( 18664a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org uint16_t deviceIndex) 187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, 189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "AudioMixerManagerLinuxPulse::OpenMicrophone(deviceIndex=%d)", 190b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org deviceIndex); 191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped lock(&_critSect); 193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 194b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // No point in opening the microphone 195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // if PA objects have not been set 196b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!_paObjectsSet) 197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 198b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, 199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " PulseAudio objects have not been set"); 200b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 201b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 202b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 203b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Set the index for the PulseAudio 204b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // input device to control 205b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paInputDeviceIndex = deviceIndex; 206b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, 208b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " the input mixer device is now open"); 209b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 211b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 213b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool AudioMixerManagerLinuxPulse::SpeakerIsInitialized() const 214b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 215b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "%s", 216b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org __FUNCTION__); 217b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 218b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return (_paOutputDeviceIndex != -1); 219b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 221b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool AudioMixerManagerLinuxPulse::MicrophoneIsInitialized() const 222b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "%s", 224b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org __FUNCTION__); 225b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 226b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return (_paInputDeviceIndex != -1); 227b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 228b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 22964a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgint32_t AudioMixerManagerLinuxPulse::SetSpeakerVolume( 23064a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org uint32_t volume) 231b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 232b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, 233b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "AudioMixerManagerLinuxPulse::SetSpeakerVolume(volume=%u)", 234b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org volume); 235b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 236b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped lock(&_critSect); 237b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 238b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_paOutputDeviceIndex == -1) 239b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 240b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 241b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " output device index has not been set"); 242b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 243b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 244b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 245b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bool setFailed(false); 246b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 247b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_paPlayStream && (LATE(pa_stream_get_state)(_paPlayStream) 248b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org != PA_STREAM_UNCONNECTED)) 249b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 250b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // We can only really set the volume if we have a connected stream 251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PaLock(); 252b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 253b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Get the number of channels from the sample specification 254b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const pa_sample_spec *spec = 255b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LATE(pa_stream_get_sample_spec)(_paPlayStream); 256b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!spec) 257b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 258b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, 259b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " could not get sample specification"); 260b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PaUnLock(); 261b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 262b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 263b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 264b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Set the same volume for all channels 265b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pa_cvolume cVolumes; 266b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LATE(pa_cvolume_set)(&cVolumes, spec->channels, volume); 267b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 268b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pa_operation* paOperation = NULL; 269b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org paOperation = LATE(pa_context_set_sink_input_volume)( 270b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paContext, 271b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LATE(pa_stream_get_index)(_paPlayStream), 272b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &cVolumes, 273b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PaSetVolumeCallback, NULL); 274b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!paOperation) 275b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 276b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org setFailed = true; 277b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 278b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 279b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Don't need to wait for the completion 280b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LATE(pa_operation_unref)(paOperation); 281b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 282b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PaUnLock(); 283b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else 284b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 285b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // We have not created a stream or it's not connected to the sink 286b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Save the volume to be set at connection 287b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paSpeakerVolume = volume; 288b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 289b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 290b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (setFailed) 291b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 292b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 293b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " could not set speaker volume, error%d", 294b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LATE(pa_context_errno)(_paContext)); 295b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 296b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 297b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 298b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 299b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 300b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 301b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 30264a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgint32_t 30364a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgAudioMixerManagerLinuxPulse::SpeakerVolume(uint32_t& volume) const 304b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 305b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 306b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_paOutputDeviceIndex == -1) 307b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 308b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 309b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " output device index has not been set"); 310b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 311b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 312b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 313b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_paPlayStream && (LATE(pa_stream_get_state)(_paPlayStream) 314b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org != PA_STREAM_UNCONNECTED)) 315b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 316b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // We can only get the volume if we have a connected stream 317b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!GetSinkInputInfo()) 318b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 319b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 32064a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org volume = static_cast<uint32_t> (_paVolume); 321b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ResetCallbackVariables(); 322b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else 323b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 324b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org volume = _paSpeakerVolume; 325b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 326b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 327b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, 328b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " AudioMixerManagerLinuxPulse::SpeakerVolume() => vol=%i", 329b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org volume); 330b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 331b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 332b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 333b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 33464a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgint32_t 33564a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgAudioMixerManagerLinuxPulse::MaxSpeakerVolume(uint32_t& maxVolume) const 336b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 337b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 338b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_paOutputDeviceIndex == -1) 339b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 340b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 341b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " output device index has not been set"); 342b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 343b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 344b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 345b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // PA_VOLUME_NORM corresponds to 100% (0db) 346b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // but PA allows up to 150 db amplification 34764a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org maxVolume = static_cast<uint32_t> (PA_VOLUME_NORM); 348b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 349b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 350b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 351b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 35264a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgint32_t 35364a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgAudioMixerManagerLinuxPulse::MinSpeakerVolume(uint32_t& minVolume) const 354b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 355b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 356b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_paOutputDeviceIndex == -1) 357b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 358b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 359b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " output device index has not been set"); 360b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 361b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 362b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 36364a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org minVolume = static_cast<uint32_t> (PA_VOLUME_MUTED); 364b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 365b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 366b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 367b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 36864a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgint32_t 36964a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgAudioMixerManagerLinuxPulse::SpeakerVolumeStepSize(uint16_t& stepSize) const 370b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 371b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 372b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_paOutputDeviceIndex == -1) 373b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 374b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 375b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " output device index has not been set"); 376b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 377b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 378b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 379b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // The sink input (stream) will always have step size = 1 380b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // There are PA_VOLUME_NORM+1 steps 381b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org stepSize = 1; 382b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 383b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, 384b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " AudioMixerManagerLinuxPulse::SpeakerVolumeStepSize() => " 385b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "size=%i, stepSize"); 386b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 387b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Reset members modified by callback 388b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ResetCallbackVariables(); 389b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 390b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 391b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 392b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 39364a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgint32_t 394b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgAudioMixerManagerLinuxPulse::SpeakerVolumeIsAvailable(bool& available) 395b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 396b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_paOutputDeviceIndex == -1) 397b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 398b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 399b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " output device index has not been set"); 400b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 401b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 402b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 403b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Always available in Pulse Audio 404b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org available = true; 405b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 406b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 407b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 408b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 40964a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgint32_t 410b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgAudioMixerManagerLinuxPulse::SpeakerMuteIsAvailable(bool& available) 411b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 412b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_paOutputDeviceIndex == -1) 413b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 414b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 415b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " output device index has not been set"); 416b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 417b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 418b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 419b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Always available in Pulse Audio 420b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org available = true; 421b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 422b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 423b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 424b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 42564a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgint32_t AudioMixerManagerLinuxPulse::SetSpeakerMute(bool enable) 426b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 427b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, 428b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "AudioMixerManagerLinuxPulse::SetSpeakerMute(enable=%u)", 429b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org enable); 430b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 431b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped lock(&_critSect); 432b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 433b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_paOutputDeviceIndex == -1) 434b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 435b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 436b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " output device index has not been set"); 437b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 438b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 439b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 440b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bool setFailed(false); 441b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 442b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_paPlayStream && (LATE(pa_stream_get_state)(_paPlayStream) 443b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org != PA_STREAM_UNCONNECTED)) 444b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 445b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // We can only really mute if we have a connected stream 446b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PaLock(); 447b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 448b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pa_operation* paOperation = NULL; 449b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org paOperation = LATE(pa_context_set_sink_input_mute)( 450b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paContext, 451b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LATE(pa_stream_get_index)(_paPlayStream), 452b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (int) enable, 453b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PaSetVolumeCallback, 454b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org NULL); 455b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!paOperation) 456b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 457b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org setFailed = true; 458b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 459b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 460b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Don't need to wait for the completion 461b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LATE(pa_operation_unref)(paOperation); 462b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 463b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PaUnLock(); 464b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else 465b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 466b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // We have not created a stream or it's not connected to the sink 467b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Save the mute status to be set at connection 468b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paSpeakerMute = enable; 469b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 470b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 471b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (setFailed) 472b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 473b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 474b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " could not mute speaker, error%d", 475b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LATE(pa_context_errno)(_paContext)); 476b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 477b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 478b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 479b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 480b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 481b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 48264a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgint32_t AudioMixerManagerLinuxPulse::SpeakerMute(bool& enabled) const 483b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 484b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 485b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_paOutputDeviceIndex == -1) 486b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 487b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 488b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " output device index has not been set"); 489b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 490b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 491b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 492b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_paPlayStream && (LATE(pa_stream_get_state)(_paPlayStream) 493b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org != PA_STREAM_UNCONNECTED)) 494b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 495b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // We can only get the mute status if we have a connected stream 496b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!GetSinkInputInfo()) 497b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 498b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 499b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org enabled = static_cast<bool> (_paMute); 500b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ResetCallbackVariables(); 501b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else 502b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 503b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org enabled = _paSpeakerMute; 504b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 505b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 506b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, 507b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " AudioMixerManagerLinuxPulse::SpeakerMute() => " 508b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "enabled=%i, enabled"); 509b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 510b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 511b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 512b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 51364a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgint32_t 514b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgAudioMixerManagerLinuxPulse::StereoPlayoutIsAvailable(bool& available) 515b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 516b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_paOutputDeviceIndex == -1) 517b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 518b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 519b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " output device index has not been set"); 520b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 521b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 522b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 523b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint32_t deviceIndex = (uint32_t) _paOutputDeviceIndex; 524b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 525b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PaLock(); 526b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 527b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Get the actual stream device index if we have a connected stream 528b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // The device used by the stream can be changed 529b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // during the call 530b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_paPlayStream && (LATE(pa_stream_get_state)(_paPlayStream) 531b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org != PA_STREAM_UNCONNECTED)) 532b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 533b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org deviceIndex = LATE(pa_stream_get_device_index)(_paPlayStream); 534b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 535b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 536b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PaUnLock(); 537b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 538b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!GetSinkInfoByIndex(deviceIndex)) 539b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 540b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 541b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org available = static_cast<bool> (_paChannels == 2); 542b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 543b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Reset members modified by callback 544b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ResetCallbackVariables(); 545b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 546b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 547b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 548b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 54964a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgint32_t 550b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgAudioMixerManagerLinuxPulse::StereoRecordingIsAvailable(bool& available) 551b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 552b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_paInputDeviceIndex == -1) 553b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 554b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 555b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " input device index has not been set"); 556b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 557b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 558b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 559b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint32_t deviceIndex = (uint32_t) _paInputDeviceIndex; 560b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 561b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PaLock(); 562b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 563b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Get the actual stream device index if we have a connected stream 564b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // The device used by the stream can be changed 565b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // during the call 566b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_paRecStream && (LATE(pa_stream_get_state)(_paRecStream) 567b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org != PA_STREAM_UNCONNECTED)) 568b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 569b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org deviceIndex = LATE(pa_stream_get_device_index)(_paRecStream); 570b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 571b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 572b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pa_operation* paOperation = NULL; 573b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ResetCallbackVariables(); 574b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 575b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Get info for this source 576b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // We want to know if the actual device can record in stereo 577b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org paOperation = LATE(pa_context_get_source_info_by_index)( 578b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paContext, deviceIndex, 579b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PaSourceInfoCallback, 580b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (void*) this); 581b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 582b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WaitForOperationCompletion(paOperation); 583b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PaUnLock(); 584b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 585b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!_callbackValues) 586b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 587b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, 588b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "Error getting number of input channels: %d", 589b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LATE(pa_context_errno)(_paContext)); 590b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 591b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 592b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 593b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org available = static_cast<bool> (_paChannels == 2); 594b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 595b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, 596b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " AudioMixerManagerLinuxPulse::StereoRecordingIsAvailable()" 597b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " => available=%i, available"); 598b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 599b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Reset members modified by callback 600b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ResetCallbackVariables(); 601b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 602b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 603b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 604b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 60564a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgint32_t AudioMixerManagerLinuxPulse::MicrophoneMuteIsAvailable( 606b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bool& available) 607b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 608b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_paInputDeviceIndex == -1) 609b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 610b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 611b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " input device index has not been set"); 612b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 613b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 614b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 615b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Always available in Pulse Audio 616b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org available = true; 617b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 618b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 619b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 620b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 62164a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgint32_t AudioMixerManagerLinuxPulse::SetMicrophoneMute(bool enable) 622b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 623b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, 624b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "AudioMixerManagerLinuxPulse::SetMicrophoneMute(enable=%u)", 625b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org enable); 626b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 627b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped lock(&_critSect); 628b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 629b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_paInputDeviceIndex == -1) 630b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 631b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 632b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " input device index has not been set"); 633b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 634b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 635b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 636b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bool setFailed(false); 637b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pa_operation* paOperation = NULL; 638b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ResetCallbackVariables(); 639b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 640b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint32_t deviceIndex = (uint32_t) _paInputDeviceIndex; 641b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 642b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PaLock(); 643b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 644b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Get the actual stream device index if we have a connected stream 645b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // The device used by the stream can be changed 646b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // during the call 647b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_paRecStream && (LATE(pa_stream_get_state)(_paRecStream) 648b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org != PA_STREAM_UNCONNECTED)) 649b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 650b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org deviceIndex = LATE(pa_stream_get_device_index)(_paRecStream); 651b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 652b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 653b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Set mute switch for the source 654b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org paOperation = LATE(pa_context_set_source_mute_by_index)( 655b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paContext, deviceIndex, 656b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org enable, 657b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PaSetVolumeCallback, NULL); 658b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 659b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!paOperation) 660b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 661b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org setFailed = true; 662b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 663b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 664b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Don't need to wait for this to complete. 665b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LATE(pa_operation_unref)(paOperation); 666b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 667b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PaUnLock(); 668b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 669b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Reset variables altered by callback 670b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ResetCallbackVariables(); 671b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 672b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (setFailed) 673b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 674b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 675b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " could not mute microphone, error%d", 676b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LATE(pa_context_errno)(_paContext)); 677b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 678b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 679b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 680b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 681b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 682b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 68364a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgint32_t AudioMixerManagerLinuxPulse::MicrophoneMute(bool& enabled) const 684b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 685b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 686b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_paInputDeviceIndex == -1) 687b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 688b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 689b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " input device index has not been set"); 690b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 691b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 692b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 693b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint32_t deviceIndex = (uint32_t) _paInputDeviceIndex; 694b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 695b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PaLock(); 696b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 697b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Get the actual stream device index if we have a connected stream 698b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // The device used by the stream can be changed 699b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // during the call 700b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_paRecStream && (LATE(pa_stream_get_state)(_paRecStream) 701b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org != PA_STREAM_UNCONNECTED)) 702b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 703b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org deviceIndex = LATE(pa_stream_get_device_index)(_paRecStream); 704b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 705b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 706b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PaUnLock(); 707b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 708b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!GetSourceInfoByIndex(deviceIndex)) 709b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 710b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 711b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org enabled = static_cast<bool> (_paMute); 712b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 713b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, 714b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " AudioMixerManagerLinuxPulse::MicrophoneMute() =>" 715b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " enabled=%i, enabled"); 716b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 717b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Reset members modified by callback 718b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ResetCallbackVariables(); 719b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 720b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 721b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 722b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 72364a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgint32_t 724b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgAudioMixerManagerLinuxPulse::MicrophoneBoostIsAvailable(bool& available) 725b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 726b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_paInputDeviceIndex == -1) 727b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 728b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 729b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " input device index has not been set"); 730b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 731b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 732b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 733b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Always unavailable in Pulse Audio 734b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Could make it possible to use PA_VOLUME_MAX 735b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // but that gives bad audio with some sound cards 736b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org available = false; 737b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 738b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 739b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 740b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 74164a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgint32_t AudioMixerManagerLinuxPulse::SetMicrophoneBoost(bool enable) 742b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 743b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, 744b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "AudioMixerManagerLinuxPulse::SetMicrophoneBoost(enable=%u)", 745b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org enable); 746b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 747b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped lock(&_critSect); 748b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 749b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_paInputDeviceIndex == -1) 750b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 751b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 752b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " input device index has not been set"); 753b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 754b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 755b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 756b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Ensure that the selected microphone destination has a valid boost control 757b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bool available(false); 758b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org MicrophoneBoostIsAvailable(available); 759b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!available) 760b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 761b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 762b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " it is not possible to enable microphone boost"); 763b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 764b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 765b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 766b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // It is assumed that the call above fails! 767b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 768b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 769b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 770b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 77164a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgint32_t AudioMixerManagerLinuxPulse::MicrophoneBoost(bool& enabled) const 772b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 773b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 774b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_paInputDeviceIndex == -1) 775b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 776b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 777b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " input device index has not been set"); 778b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 779b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 780b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 781b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Microphone boost cannot be enabled on this platform! 782b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org enabled = false; 783b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 784b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 785b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 786b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 78764a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgint32_t AudioMixerManagerLinuxPulse::MicrophoneVolumeIsAvailable( 788b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bool& available) 789b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 790b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_paInputDeviceIndex == -1) 791b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 792b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 793b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " input device index has not been set"); 794b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 795b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 796b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 797b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Always available in Pulse Audio 798b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org available = true; 799b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 800b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 801b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 802b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 80364a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgint32_t 80464a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgAudioMixerManagerLinuxPulse::SetMicrophoneVolume(uint32_t volume) 805b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 806b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, 807b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "AudioMixerManagerLinuxPulse::SetMicrophoneVolume(volume=%u)", 808b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org volume); 809b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 810b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped lock(&_critSect); 811b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 812b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_paInputDeviceIndex == -1) 813b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 814b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 815b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " input device index has not been set"); 816b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 817b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 818b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 819b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Unlike output streams, input streams have no concept of a stream volume, 820b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // only a device volume. So we have to change the volume of the device 821b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // itself. 822b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 823b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // The device may have a different number of channels than the stream and 824b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // their mapping may be different, so we don't want to use the channel count 825b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // from our sample spec. We could use PA_CHANNELS_MAX to cover our bases, 826b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // and the server allows that even if the device's channel count is lower, 827b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // but some buggy PA clients don't like that (the pavucontrol on Hardy dies 828b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // in an assert if the channel count is different). So instead we look up 829b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // the actual number of channels that the device has. 830b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 831b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint32_t deviceIndex = (uint32_t) _paInputDeviceIndex; 832b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 833b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PaLock(); 834b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 835b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Get the actual stream device index if we have a connected stream 836b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // The device used by the stream can be changed 837b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // during the call 838b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_paRecStream && (LATE(pa_stream_get_state)(_paRecStream) 839b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org != PA_STREAM_UNCONNECTED)) 840b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 841b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org deviceIndex = LATE(pa_stream_get_device_index)(_paRecStream); 842b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 843b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 844b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bool setFailed(false); 845b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pa_operation* paOperation = NULL; 846b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ResetCallbackVariables(); 847b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 848b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Get the number of channels for this source 849b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org paOperation 850b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org = LATE(pa_context_get_source_info_by_index)(_paContext, deviceIndex, 851b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PaSourceInfoCallback, 852b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (void*) this); 853b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 854b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WaitForOperationCompletion(paOperation); 855b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 856b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!_callbackValues) 857b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 858b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, 859b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "Error getting input channels: %d", 860b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LATE(pa_context_errno)(_paContext)); 861b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PaUnLock(); 862b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 863b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 864b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 86564a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org uint8_t channels = _paChannels; 866b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ResetCallbackVariables(); 867b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 868b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pa_cvolume cVolumes; 869b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LATE(pa_cvolume_set)(&cVolumes, channels, volume); 870b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 871b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Set the volume for the source 872b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org paOperation 873b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org = LATE(pa_context_set_source_volume_by_index)(_paContext, deviceIndex, 874b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &cVolumes, 875b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PaSetVolumeCallback, NULL); 876b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 877b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!paOperation) 878b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 879b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org setFailed = true; 880b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 881b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 882b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Don't need to wait for this to complete. 883b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LATE(pa_operation_unref)(paOperation); 884b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 885b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PaUnLock(); 886b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 887b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Reset variables altered by callback 888b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ResetCallbackVariables(); 889b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 890b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (setFailed) 891b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 892b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 893b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " could not set microphone volume, error%d", 894b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LATE(pa_context_errno)(_paContext)); 895b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 896b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 897b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 898b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 899b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 900b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 90164a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgint32_t 90264a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgAudioMixerManagerLinuxPulse::MicrophoneVolume(uint32_t& volume) const 903b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 904b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 905b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_paInputDeviceIndex == -1) 906b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 907b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 908b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " input device index has not been set"); 909b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 910b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 911b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 912b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint32_t deviceIndex = (uint32_t) _paInputDeviceIndex; 913b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 914b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PaLock(); 915b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 916b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Get the actual stream device index if we have a connected stream 917b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // The device used by the stream can be changed 918b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // during the call 919b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_paRecStream && (LATE(pa_stream_get_state)(_paRecStream) 920b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org != PA_STREAM_UNCONNECTED)) 921b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 922b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org deviceIndex = LATE(pa_stream_get_device_index)(_paRecStream); 923b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 924b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 925b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PaUnLock(); 926b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 927b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!GetSourceInfoByIndex(deviceIndex)) 928b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 929b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 93064a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org volume = static_cast<uint32_t> (_paVolume); 931b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 932b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, 933b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " AudioMixerManagerLinuxPulse::MicrophoneVolume() => vol=%i, volume"); 934b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 935b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Reset members modified by callback 936b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ResetCallbackVariables(); 937b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 938b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 939b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 940b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 94164a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgint32_t 94264a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgAudioMixerManagerLinuxPulse::MaxMicrophoneVolume(uint32_t& maxVolume) const 943b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 944b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 945b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_paInputDeviceIndex == -1) 946b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 947b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 948b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " input device index has not been set"); 949b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 950b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 951b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 952b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // PA_VOLUME_NORM corresponds to 100% (0db) 953b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // PA allows up to 150 db amplification (PA_VOLUME_MAX) 954b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // but that doesn't work well for all sound cards 95564a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org maxVolume = static_cast<uint32_t> (PA_VOLUME_NORM); 956b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 957b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 958b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 959b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 96064a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgint32_t 96164a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgAudioMixerManagerLinuxPulse::MinMicrophoneVolume(uint32_t& minVolume) const 962b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 963b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 964b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_paInputDeviceIndex == -1) 965b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 966b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 967b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " input device index has not been set"); 968b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 969b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 970b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 97164a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org minVolume = static_cast<uint32_t> (PA_VOLUME_MUTED); 972b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 973b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 974b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 975b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 97664a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.orgint32_t AudioMixerManagerLinuxPulse::MicrophoneVolumeStepSize( 97764a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org uint16_t& stepSize) const 978b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 979b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 980b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_paInputDeviceIndex == -1) 981b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 982b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 983b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " input device index has not been set"); 984b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 985b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 986b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 987b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint32_t deviceIndex = (uint32_t) _paInputDeviceIndex; 988b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 989b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PaLock(); 990b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 991b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Get the actual stream device index if we have a connected stream 992b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // The device used by the stream can be changed 993b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // during the call 994b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_paRecStream && (LATE(pa_stream_get_state)(_paRecStream) 995b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org != PA_STREAM_UNCONNECTED)) 996b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 997b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org deviceIndex = LATE(pa_stream_get_device_index)(_paRecStream); 998b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 999b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1000b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pa_operation* paOperation = NULL; 1001b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ResetCallbackVariables(); 1002b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1003b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Get info for this source 1004b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org paOperation 1005b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org = LATE(pa_context_get_source_info_by_index)(_paContext, deviceIndex, 1006b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PaSourceInfoCallback, 1007b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (void*) this); 1008b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1009b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WaitForOperationCompletion(paOperation); 1010b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1011b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PaUnLock(); 1012b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1013b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!_callbackValues) 1014b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1015b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, 1016b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "Error getting step size: %d", 1017b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LATE(pa_context_errno)(_paContext)); 1018b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 1019b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1020b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 102164a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org stepSize = static_cast<uint16_t> ((PA_VOLUME_NORM + 1) / _paVolSteps); 1022b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1023b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, 1024b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " AudioMixerManagerLinuxPulse::MicrophoneVolumeStepSize()" 1025b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " => size=%i, stepSize"); 1026b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1027b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Reset members modified by callback 1028b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ResetCallbackVariables(); 1029b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1030b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 1031b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1032b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1033b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// ============================================================================ 1034b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Private Methods 1035b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// ============================================================================ 1036b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1037b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid AudioMixerManagerLinuxPulse::PaSinkInfoCallback(pa_context */*c*/, 1038b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const pa_sink_info *i, 1039b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int eol, void *pThis) 1040b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 1041b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org static_cast<AudioMixerManagerLinuxPulse*> (pThis)-> PaSinkInfoCallbackHandler( 1042b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org i, eol); 1043b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1044b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1045b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid AudioMixerManagerLinuxPulse::PaSinkInputInfoCallback( 1046b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pa_context */*c*/, 1047b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const pa_sink_input_info *i, 1048b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int eol, void *pThis) 1049b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 1050b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org static_cast<AudioMixerManagerLinuxPulse*> (pThis)-> 1051b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PaSinkInputInfoCallbackHandler(i, eol); 1052b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1053b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1054b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1055b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid AudioMixerManagerLinuxPulse::PaSourceInfoCallback(pa_context */*c*/, 1056b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const pa_source_info *i, 1057b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int eol, void *pThis) 1058b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 1059b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org static_cast<AudioMixerManagerLinuxPulse*> (pThis)-> 1060b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PaSourceInfoCallbackHandler(i, eol); 1061b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1062b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1063b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid AudioMixerManagerLinuxPulse::PaSetVolumeCallback(pa_context * c, 1064b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int success, void */*pThis*/) 1065b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 1066b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!success) 1067b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1068b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, -1, 1069b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " failed to set volume"); 1070b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1071b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1072b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1073b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid AudioMixerManagerLinuxPulse::PaSinkInfoCallbackHandler( 1074b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const pa_sink_info *i, 1075b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int eol) 1076b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 1077b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (eol) 1078b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1079b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Signal that we are done 1080b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LATE(pa_threaded_mainloop_signal)(_paMainloop, 0); 1081b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return; 1082b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1083b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1084b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _callbackValues = true; 1085b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paChannels = i->channel_map.channels; // Get number of channels 1086b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pa_volume_t paVolume = PA_VOLUME_MUTED; // Minimum possible value. 1087b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (int j = 0; j < _paChannels; ++j) 1088b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1089b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (paVolume < i->volume.values[j]) 1090b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1091b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org paVolume = i->volume.values[j]; 1092b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1093b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1094b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paVolume = paVolume; // get the max volume for any channel 1095b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paMute = i->mute; // get mute status 1096b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1097b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // supported since PA 0.9.15 1098b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org //_paVolSteps = i->n_volume_steps; // get the number of volume steps 1099b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // default value is PA_VOLUME_NORM+1 1100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paVolSteps = PA_VOLUME_NORM + 1; 1101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid AudioMixerManagerLinuxPulse::PaSinkInputInfoCallbackHandler( 1104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const pa_sink_input_info *i, 1105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int eol) 1106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 1107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (eol) 1108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Signal that we are done 1110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LATE(pa_threaded_mainloop_signal)(_paMainloop, 0); 1111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return; 1112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _callbackValues = true; 1115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paChannels = i->channel_map.channels; // Get number of channels 1116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pa_volume_t paVolume = PA_VOLUME_MUTED; // Minimum possible value. 1117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (int j = 0; j < _paChannels; ++j) 1118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (paVolume < i->volume.values[j]) 1120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org paVolume = i->volume.values[j]; 1122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paVolume = paVolume; // Get the max volume for any channel 1125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paMute = i->mute; // Get mute status 1126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid AudioMixerManagerLinuxPulse::PaSourceInfoCallbackHandler( 1129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const pa_source_info *i, 1130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int eol) 1131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 1132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (eol) 1133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Signal that we are done 1135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LATE(pa_threaded_mainloop_signal)(_paMainloop, 0); 1136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return; 1137b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1139b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _callbackValues = true; 1140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paChannels = i->channel_map.channels; // Get number of channels 1141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pa_volume_t paVolume = PA_VOLUME_MUTED; // Minimum possible value. 1142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (int j = 0; j < _paChannels; ++j) 1143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (paVolume < i->volume.values[j]) 1145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org paVolume = i->volume.values[j]; 1147b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1149b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paVolume = paVolume; // Get the max volume for any channel 1150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paMute = i->mute; // Get mute status 1151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // supported since PA 0.9.15 1153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org //_paVolSteps = i->n_volume_steps; // Get the number of volume steps 1154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // default value is PA_VOLUME_NORM+1 1155b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paVolSteps = PA_VOLUME_NORM + 1; 1156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1157b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid AudioMixerManagerLinuxPulse::ResetCallbackVariables() const 1159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 1160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paVolume = 0; 1161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paMute = 0; 1162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paVolSteps = 0; 1163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paChannels = 0; 1164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _callbackValues = false; 1165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid AudioMixerManagerLinuxPulse::WaitForOperationCompletion( 1168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pa_operation* paOperation) const 1169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 1170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org while (LATE(pa_operation_get_state)(paOperation) == PA_OPERATION_RUNNING) 1171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LATE(pa_threaded_mainloop_wait)(_paMainloop); 1173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1174b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LATE(pa_operation_unref)(paOperation); 1176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid AudioMixerManagerLinuxPulse::PaLock() const 1179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 1180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LATE(pa_threaded_mainloop_lock)(_paMainloop); 1181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid AudioMixerManagerLinuxPulse::PaUnLock() const 1184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 1185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LATE(pa_threaded_mainloop_unlock)(_paMainloop); 1186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool AudioMixerManagerLinuxPulse::GetSinkInputInfo() const { 1189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pa_operation* paOperation = NULL; 1190b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ResetCallbackVariables(); 1191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PaLock(); 1193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (int retries = 0; retries < kMaxRetryOnFailure && !_callbackValues; 1194b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org retries ++) { 1195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Get info for this stream (sink input). 1196b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org paOperation = LATE(pa_context_get_sink_input_info)( 1197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paContext, 1198b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LATE(pa_stream_get_index)(_paPlayStream), 1199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PaSinkInputInfoCallback, 1200b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (void*) this); 1201b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1202b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WaitForOperationCompletion(paOperation); 1203b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1204b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PaUnLock(); 1205b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1206b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!_callbackValues) { 1207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, 1208b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "GetSinkInputInfo failed to get volume info : %d", 1209b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LATE(pa_context_errno)(_paContext)); 1210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return false; 1211b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1213b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return true; 1214b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1215b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1216b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool AudioMixerManagerLinuxPulse::GetSinkInfoByIndex( 1217b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int device_index) const { 1218b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pa_operation* paOperation = NULL; 1219b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ResetCallbackVariables(); 1220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1221b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PaLock(); 1222b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (int retries = 0; retries < kMaxRetryOnFailure && !_callbackValues; 1223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org retries ++) { 1224b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org paOperation = LATE(pa_context_get_sink_info_by_index)(_paContext, 1225b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org device_index, PaSinkInfoCallback, (void*) this); 1226b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1227b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WaitForOperationCompletion(paOperation); 1228b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1229b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PaUnLock(); 1230b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1231b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!_callbackValues) { 1232b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, 1233b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "GetSinkInfoByIndex failed to get volume info: %d", 1234b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LATE(pa_context_errno)(_paContext)); 1235b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return false; 1236b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1237b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1238b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return true; 1239b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1240b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1241b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool AudioMixerManagerLinuxPulse::GetSourceInfoByIndex( 1242b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int device_index) const { 1243b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pa_operation* paOperation = NULL; 1244b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ResetCallbackVariables(); 1245b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1246b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PaLock(); 1247b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (int retries = 0; retries < kMaxRetryOnFailure && !_callbackValues; 1248b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org retries ++) { 1249b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org paOperation = LATE(pa_context_get_source_info_by_index)( 1250b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _paContext, device_index, PaSourceInfoCallback, (void*) this); 1251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1252b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WaitForOperationCompletion(paOperation); 1253b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1254b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1255b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PaUnLock(); 1256b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1257b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!_callbackValues) { 1258b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, 1259b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "GetSourceInfoByIndex error: %d", 1260b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LATE(pa_context_errno)(_paContext)); 1261b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return false; 1262b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1263b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1264b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return true; 1265b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1266b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1267b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1268