OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #include <assert.h> | 11 #include <assert.h> |
12 | 12 |
13 #include "webrtc/modules/audio_device/linux/audio_mixer_manager_alsa_linux.h" | 13 #include "webrtc/modules/audio_device/linux/audio_mixer_manager_alsa_linux.h" |
14 #include "webrtc/system_wrappers/include/trace.h" | 14 #include "webrtc/system_wrappers/include/trace.h" |
15 | 15 |
16 extern webrtc_adm_linux_alsa::AlsaSymbolTable AlsaSymbolTable; | 16 extern webrtc_adm_linux_alsa::AlsaSymbolTable AlsaSymbolTable; |
17 | 17 |
18 // Accesses ALSA functions through our late-binding symbol table instead of | 18 // Accesses ALSA functions through our late-binding symbol table instead of |
19 // directly. This way we don't have to link to libalsa, which means our binary | 19 // directly. This way we don't have to link to libalsa, which means our binary |
20 // will work on systems that don't have it. | 20 // will work on systems that don't have it. |
21 #define LATE(sym) \ | 21 #define LATE(sym) \ |
22 LATESYM_GET(webrtc_adm_linux_alsa::AlsaSymbolTable, &AlsaSymbolTable, sym) | 22 LATESYM_GET(webrtc_adm_linux_alsa::AlsaSymbolTable, &AlsaSymbolTable, sym) |
23 | 23 |
24 namespace webrtc | 24 namespace webrtc |
25 { | 25 { |
26 | 26 |
27 AudioMixerManagerLinuxALSA::AudioMixerManagerLinuxALSA(const int32_t id) : | 27 AudioMixerManagerLinuxALSA::AudioMixerManagerLinuxALSA(const int32_t id) : |
28 _critSect(*CriticalSectionWrapper::CreateCriticalSection()), | |
29 _id(id), | 28 _id(id), |
30 _outputMixerHandle(NULL), | 29 _outputMixerHandle(NULL), |
31 _inputMixerHandle(NULL), | 30 _inputMixerHandle(NULL), |
32 _outputMixerElement(NULL), | 31 _outputMixerElement(NULL), |
33 _inputMixerElement(NULL) | 32 _inputMixerElement(NULL) |
34 { | 33 { |
35 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, | 34 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, |
36 "%s constructed", __FUNCTION__); | 35 "%s constructed", __FUNCTION__); |
37 | 36 |
38 memset(_outputMixerStr, 0, kAdmMaxDeviceNameSize); | 37 memset(_outputMixerStr, 0, kAdmMaxDeviceNameSize); |
39 memset(_inputMixerStr, 0, kAdmMaxDeviceNameSize); | 38 memset(_inputMixerStr, 0, kAdmMaxDeviceNameSize); |
40 } | 39 } |
41 | 40 |
42 AudioMixerManagerLinuxALSA::~AudioMixerManagerLinuxALSA() | 41 AudioMixerManagerLinuxALSA::~AudioMixerManagerLinuxALSA() |
43 { | 42 { |
44 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, | 43 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, |
45 "%s destructed", __FUNCTION__); | 44 "%s destructed", __FUNCTION__); |
46 | |
47 Close(); | 45 Close(); |
48 | |
49 delete &_critSect; | |
50 } | 46 } |
51 | 47 |
52 // ============================================================================ | 48 // ============================================================================ |
53 // PUBLIC METHODS | 49 // PUBLIC METHODS |
54 // ============================================================================ | 50 // ============================================================================ |
55 | 51 |
56 int32_t AudioMixerManagerLinuxALSA::Close() | 52 int32_t AudioMixerManagerLinuxALSA::Close() |
57 { | 53 { |
58 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "%s", | 54 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "%s", |
59 __FUNCTION__); | 55 __FUNCTION__); |
60 | 56 |
61 CriticalSectionScoped lock(&_critSect); | 57 rtc::CritScope lock(&_critSect); |
62 | 58 |
63 CloseSpeaker(); | 59 CloseSpeaker(); |
64 CloseMicrophone(); | 60 CloseMicrophone(); |
65 | 61 |
66 return 0; | 62 return 0; |
67 | 63 |
68 } | 64 } |
69 | 65 |
70 int32_t AudioMixerManagerLinuxALSA::CloseSpeaker() | 66 int32_t AudioMixerManagerLinuxALSA::CloseSpeaker() |
71 { | 67 { |
72 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "%s", | 68 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "%s", |
73 __FUNCTION__); | 69 __FUNCTION__); |
74 | 70 |
75 CriticalSectionScoped lock(&_critSect); | 71 rtc::CritScope lock(&_critSect); |
76 | 72 |
77 int errVal = 0; | 73 int errVal = 0; |
78 | 74 |
79 if (_outputMixerHandle != NULL) | 75 if (_outputMixerHandle != NULL) |
80 { | 76 { |
81 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 77 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, |
82 "Closing playout mixer"); | 78 "Closing playout mixer"); |
83 LATE(snd_mixer_free)(_outputMixerHandle); | 79 LATE(snd_mixer_free)(_outputMixerHandle); |
84 if (errVal < 0) | 80 if (errVal < 0) |
85 { | 81 { |
(...skipping 20 matching lines...) Expand all Loading... |
106 } | 102 } |
107 memset(_outputMixerStr, 0, kAdmMaxDeviceNameSize); | 103 memset(_outputMixerStr, 0, kAdmMaxDeviceNameSize); |
108 | 104 |
109 return 0; | 105 return 0; |
110 } | 106 } |
111 | 107 |
112 int32_t AudioMixerManagerLinuxALSA::CloseMicrophone() | 108 int32_t AudioMixerManagerLinuxALSA::CloseMicrophone() |
113 { | 109 { |
114 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "%s", __FUNCTION__); | 110 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "%s", __FUNCTION__); |
115 | 111 |
116 CriticalSectionScoped lock(&_critSect); | 112 rtc::CritScope lock(&_critSect); |
117 | 113 |
118 int errVal = 0; | 114 int errVal = 0; |
119 | 115 |
120 if (_inputMixerHandle != NULL) | 116 if (_inputMixerHandle != NULL) |
121 { | 117 { |
122 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 118 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, |
123 "Closing record mixer"); | 119 "Closing record mixer"); |
124 | 120 |
125 LATE(snd_mixer_free)(_inputMixerHandle); | 121 LATE(snd_mixer_free)(_inputMixerHandle); |
126 if (errVal < 0) | 122 if (errVal < 0) |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
158 memset(_inputMixerStr, 0, kAdmMaxDeviceNameSize); | 154 memset(_inputMixerStr, 0, kAdmMaxDeviceNameSize); |
159 | 155 |
160 return 0; | 156 return 0; |
161 } | 157 } |
162 | 158 |
163 int32_t AudioMixerManagerLinuxALSA::OpenSpeaker(char* deviceName) | 159 int32_t AudioMixerManagerLinuxALSA::OpenSpeaker(char* deviceName) |
164 { | 160 { |
165 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 161 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, |
166 "AudioMixerManagerLinuxALSA::OpenSpeaker(name=%s)", deviceName)
; | 162 "AudioMixerManagerLinuxALSA::OpenSpeaker(name=%s)", deviceName)
; |
167 | 163 |
168 CriticalSectionScoped lock(&_critSect); | 164 rtc::CritScope lock(&_critSect); |
169 | 165 |
170 int errVal = 0; | 166 int errVal = 0; |
171 | 167 |
172 // Close any existing output mixer handle | 168 // Close any existing output mixer handle |
173 // | 169 // |
174 if (_outputMixerHandle != NULL) | 170 if (_outputMixerHandle != NULL) |
175 { | 171 { |
176 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 172 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, |
177 "Closing playout mixer"); | 173 "Closing playout mixer"); |
178 | 174 |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
252 | 248 |
253 return 0; | 249 return 0; |
254 } | 250 } |
255 | 251 |
256 int32_t AudioMixerManagerLinuxALSA::OpenMicrophone(char *deviceName) | 252 int32_t AudioMixerManagerLinuxALSA::OpenMicrophone(char *deviceName) |
257 { | 253 { |
258 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 254 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, |
259 "AudioMixerManagerLinuxALSA::OpenMicrophone(name=%s)", | 255 "AudioMixerManagerLinuxALSA::OpenMicrophone(name=%s)", |
260 deviceName); | 256 deviceName); |
261 | 257 |
262 CriticalSectionScoped lock(&_critSect); | 258 rtc::CritScope lock(&_critSect); |
263 | 259 |
264 int errVal = 0; | 260 int errVal = 0; |
265 | 261 |
266 // Close any existing input mixer handle | 262 // Close any existing input mixer handle |
267 // | 263 // |
268 if (_inputMixerHandle != NULL) | 264 if (_inputMixerHandle != NULL) |
269 { | 265 { |
270 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 266 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, |
271 "Closing record mixer"); | 267 "Closing record mixer"); |
272 | 268 |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
371 return (_inputMixerHandle != NULL); | 367 return (_inputMixerHandle != NULL); |
372 } | 368 } |
373 | 369 |
374 int32_t AudioMixerManagerLinuxALSA::SetSpeakerVolume( | 370 int32_t AudioMixerManagerLinuxALSA::SetSpeakerVolume( |
375 uint32_t volume) | 371 uint32_t volume) |
376 { | 372 { |
377 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 373 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, |
378 "AudioMixerManagerLinuxALSA::SetSpeakerVolume(volume=%u)", | 374 "AudioMixerManagerLinuxALSA::SetSpeakerVolume(volume=%u)", |
379 volume); | 375 volume); |
380 | 376 |
381 CriticalSectionScoped lock(&_critSect); | 377 rtc::CritScope lock(&_critSect); |
382 | 378 |
383 if (_outputMixerElement == NULL) | 379 if (_outputMixerElement == NULL) |
384 { | 380 { |
385 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 381 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, |
386 " no avaliable output mixer element exists"); | 382 " no avaliable output mixer element exists"); |
387 return -1; | 383 return -1; |
388 } | 384 } |
389 | 385 |
390 int errVal = | 386 int errVal = |
391 LATE(snd_mixer_selem_set_playback_volume_all)(_outputMixerElement, | 387 LATE(snd_mixer_selem_set_playback_volume_all)(_outputMixerElement, |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
635 | 631 |
636 return 0; | 632 return 0; |
637 } | 633 } |
638 | 634 |
639 int32_t AudioMixerManagerLinuxALSA::SetSpeakerMute(bool enable) | 635 int32_t AudioMixerManagerLinuxALSA::SetSpeakerMute(bool enable) |
640 { | 636 { |
641 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 637 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, |
642 "AudioMixerManagerLinuxALSA::SetSpeakerMute(enable=%u)", | 638 "AudioMixerManagerLinuxALSA::SetSpeakerMute(enable=%u)", |
643 enable); | 639 enable); |
644 | 640 |
645 CriticalSectionScoped lock(&_critSect); | 641 rtc::CritScope lock(&_critSect); |
646 | 642 |
647 if (_outputMixerElement == NULL) | 643 if (_outputMixerElement == NULL) |
648 { | 644 { |
649 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 645 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, |
650 " no avaliable output mixer element exists"); | 646 " no avaliable output mixer element exists"); |
651 return -1; | 647 return -1; |
652 } | 648 } |
653 | 649 |
654 // Ensure that the selected speaker destination has a valid mute control. | 650 // Ensure that the selected speaker destination has a valid mute control. |
655 bool available(false); | 651 bool available(false); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
732 available = LATE(snd_mixer_selem_has_capture_switch)(_inputMixerElement); | 728 available = LATE(snd_mixer_selem_has_capture_switch)(_inputMixerElement); |
733 return 0; | 729 return 0; |
734 } | 730 } |
735 | 731 |
736 int32_t AudioMixerManagerLinuxALSA::SetMicrophoneMute(bool enable) | 732 int32_t AudioMixerManagerLinuxALSA::SetMicrophoneMute(bool enable) |
737 { | 733 { |
738 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 734 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, |
739 "AudioMixerManagerLinuxALSA::SetMicrophoneMute(enable=%u)", | 735 "AudioMixerManagerLinuxALSA::SetMicrophoneMute(enable=%u)", |
740 enable); | 736 enable); |
741 | 737 |
742 CriticalSectionScoped lock(&_critSect); | 738 rtc::CritScope lock(&_critSect); |
743 | 739 |
744 if (_inputMixerElement == NULL) | 740 if (_inputMixerElement == NULL) |
745 { | 741 { |
746 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 742 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, |
747 " no avaliable input mixer element exists"); | 743 " no avaliable input mixer element exists"); |
748 return -1; | 744 return -1; |
749 } | 745 } |
750 | 746 |
751 // Ensure that the selected microphone destination has a valid mute control. | 747 // Ensure that the selected microphone destination has a valid mute control. |
752 bool available(false); | 748 bool available(false); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
831 | 827 |
832 return 0; | 828 return 0; |
833 } | 829 } |
834 | 830 |
835 int32_t AudioMixerManagerLinuxALSA::SetMicrophoneBoost(bool enable) | 831 int32_t AudioMixerManagerLinuxALSA::SetMicrophoneBoost(bool enable) |
836 { | 832 { |
837 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 833 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, |
838 "AudioMixerManagerLinuxALSA::SetMicrophoneBoost(enable=%u)", | 834 "AudioMixerManagerLinuxALSA::SetMicrophoneBoost(enable=%u)", |
839 enable); | 835 enable); |
840 | 836 |
841 CriticalSectionScoped lock(&_critSect); | 837 rtc::CritScope lock(&_critSect); |
842 | 838 |
843 if (_inputMixerHandle == NULL) | 839 if (_inputMixerHandle == NULL) |
844 { | 840 { |
845 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 841 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, |
846 " no avaliable input mixer exists"); | 842 " no avaliable input mixer exists"); |
847 return -1; | 843 return -1; |
848 } | 844 } |
849 | 845 |
850 // Ensure that the selected microphone destination has a valid mute control. | 846 // Ensure that the selected microphone destination has a valid mute control. |
851 bool available(false); | 847 bool available(false); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
893 return 0; | 889 return 0; |
894 } | 890 } |
895 | 891 |
896 int32_t AudioMixerManagerLinuxALSA::SetMicrophoneVolume( | 892 int32_t AudioMixerManagerLinuxALSA::SetMicrophoneVolume( |
897 uint32_t volume) | 893 uint32_t volume) |
898 { | 894 { |
899 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 895 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, |
900 "AudioMixerManagerLinuxALSA::SetMicrophoneVolume(volume=%u)", | 896 "AudioMixerManagerLinuxALSA::SetMicrophoneVolume(volume=%u)", |
901 volume); | 897 volume); |
902 | 898 |
903 CriticalSectionScoped lock(&_critSect); | 899 rtc::CritScope lock(&_critSect); |
904 | 900 |
905 if (_inputMixerElement == NULL) | 901 if (_inputMixerElement == NULL) |
906 { | 902 { |
907 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 903 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, |
908 " no avaliable input mixer element exists"); | 904 " no avaliable input mixer element exists"); |
909 return -1; | 905 return -1; |
910 } | 906 } |
911 | 907 |
912 int | 908 int |
913 errVal = | 909 errVal = |
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1289 } | 1285 } |
1290 | 1286 |
1291 void AudioMixerManagerLinuxALSA::GetControlName(char* controlName, | 1287 void AudioMixerManagerLinuxALSA::GetControlName(char* controlName, |
1292 char* deviceName) const | 1288 char* deviceName) const |
1293 { | 1289 { |
1294 // Example | 1290 // Example |
1295 // deviceName: "front:CARD=Intel,DEV=0" | 1291 // deviceName: "front:CARD=Intel,DEV=0" |
1296 // controlName: "hw:CARD=Intel" | 1292 // controlName: "hw:CARD=Intel" |
1297 char* pos1 = strchr(deviceName, ':'); | 1293 char* pos1 = strchr(deviceName, ':'); |
1298 char* pos2 = strchr(deviceName, ','); | 1294 char* pos2 = strchr(deviceName, ','); |
1299 if (!pos2) | 1295 if (!pos2) { |
1300 { | |
1301 // Can also be default:CARD=Intel | 1296 // Can also be default:CARD=Intel |
1302 pos2 = &deviceName[strlen(deviceName)]; | 1297 pos2 = &deviceName[strlen(deviceName)]; |
1303 } | 1298 } |
1304 if (pos1 && pos2) | 1299 if (pos1 && pos2) { |
1305 { | |
1306 strcpy(controlName, "hw"); | 1300 strcpy(controlName, "hw"); |
1307 int nChar = (int) (pos2 - pos1); | 1301 int nChar = (int) (pos2 - pos1); |
1308 strncpy(&controlName[2], pos1, nChar); | 1302 strncpy(&controlName[2], pos1, nChar); |
1309 controlName[2 + nChar] = '\0'; | 1303 controlName[2 + nChar] = '\0'; |
1310 } else | 1304 } else { |
1311 { | |
1312 strcpy(controlName, deviceName); | 1305 strcpy(controlName, deviceName); |
1313 } | 1306 } |
1314 | 1307 |
1315 } | 1308 } |
1316 | 1309 |
1317 } | 1310 } |
OLD | NEW |