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/audio_device_config.h" | 13 #include "webrtc/modules/audio_device/audio_device_config.h" |
14 #include "webrtc/modules/audio_device/linux/audio_device_alsa_linux.h" | 14 #include "webrtc/modules/audio_device/linux/audio_device_alsa_linux.h" |
15 #include "webrtc/rtc_base/logging.h" | 15 #include "webrtc/rtc_base/logging.h" |
16 | 16 |
17 #include "webrtc/system_wrappers/include/event_wrapper.h" | 17 #include "webrtc/system_wrappers/include/event_wrapper.h" |
18 #include "webrtc/system_wrappers/include/sleep.h" | 18 #include "webrtc/system_wrappers/include/sleep.h" |
19 #include "webrtc/system_wrappers/include/trace.h" | |
20 | |
21 webrtc::adm_linux_alsa::AlsaSymbolTable AlsaSymbolTable; | 19 webrtc::adm_linux_alsa::AlsaSymbolTable AlsaSymbolTable; |
22 | 20 |
23 // Accesses ALSA functions through our late-binding symbol table instead of | 21 // Accesses ALSA functions through our late-binding symbol table instead of |
24 // directly. This way we don't have to link to libasound, which means our binary | 22 // directly. This way we don't have to link to libasound, which means our binary |
25 // will work on systems that don't have it. | 23 // will work on systems that don't have it. |
26 #define LATE(sym) \ | 24 #define LATE(sym) \ |
27 LATESYM_GET(webrtc::adm_linux_alsa::AlsaSymbolTable, &AlsaSymbolTable, sym) | 25 LATESYM_GET(webrtc::adm_linux_alsa::AlsaSymbolTable, &AlsaSymbolTable, sym) |
28 | 26 |
29 // Redefine these here to be able to do late-binding | 27 // Redefine these here to be able to do late-binding |
30 #undef snd_ctl_card_info_alloca | 28 #undef snd_ctl_card_info_alloca |
(...skipping 24 matching lines...) Expand all Loading... |
55 static const unsigned int ALSA_CAPTURE_CH = 2; | 53 static const unsigned int ALSA_CAPTURE_CH = 2; |
56 static const unsigned int ALSA_CAPTURE_LATENCY = 40*1000; // in us | 54 static const unsigned int ALSA_CAPTURE_LATENCY = 40*1000; // in us |
57 static const unsigned int ALSA_CAPTURE_WAIT_TIMEOUT = 5; // in ms | 55 static const unsigned int ALSA_CAPTURE_WAIT_TIMEOUT = 5; // in ms |
58 | 56 |
59 #define FUNC_GET_NUM_OF_DEVICE 0 | 57 #define FUNC_GET_NUM_OF_DEVICE 0 |
60 #define FUNC_GET_DEVICE_NAME 1 | 58 #define FUNC_GET_DEVICE_NAME 1 |
61 #define FUNC_GET_DEVICE_NAME_FOR_AN_ENUM 2 | 59 #define FUNC_GET_DEVICE_NAME_FOR_AN_ENUM 2 |
62 | 60 |
63 AudioDeviceLinuxALSA::AudioDeviceLinuxALSA(const int32_t id) : | 61 AudioDeviceLinuxALSA::AudioDeviceLinuxALSA(const int32_t id) : |
64 _ptrAudioBuffer(NULL), | 62 _ptrAudioBuffer(NULL), |
65 _id(id), | |
66 _mixerManager(id), | 63 _mixerManager(id), |
67 _inputDeviceIndex(0), | 64 _inputDeviceIndex(0), |
68 _outputDeviceIndex(0), | 65 _outputDeviceIndex(0), |
69 _inputDeviceIsSpecified(false), | 66 _inputDeviceIsSpecified(false), |
70 _outputDeviceIsSpecified(false), | 67 _outputDeviceIsSpecified(false), |
71 _handleRecord(NULL), | 68 _handleRecord(NULL), |
72 _handlePlayout(NULL), | 69 _handlePlayout(NULL), |
73 _recordingBuffersizeInFrame(0), | 70 _recordingBuffersizeInFrame(0), |
74 _recordingPeriodSizeInFrame(0), | 71 _recordingPeriodSizeInFrame(0), |
75 _playoutBufferSizeInFrame(0), | 72 _playoutBufferSizeInFrame(0), |
(...skipping 20 matching lines...) Expand all Loading... |
96 _recordingDelay(0), | 93 _recordingDelay(0), |
97 _playoutDelay(0), | 94 _playoutDelay(0), |
98 _playWarning(0), | 95 _playWarning(0), |
99 _playError(0), | 96 _playError(0), |
100 _recWarning(0), | 97 _recWarning(0), |
101 _recError(0), | 98 _recError(0), |
102 _playBufDelay(80), | 99 _playBufDelay(80), |
103 _playBufDelayFixed(80) | 100 _playBufDelayFixed(80) |
104 { | 101 { |
105 memset(_oldKeyState, 0, sizeof(_oldKeyState)); | 102 memset(_oldKeyState, 0, sizeof(_oldKeyState)); |
106 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, id, | 103 LOG(LS_INFO) << __FUNCTION__ << " created"; |
107 "%s created", __FUNCTION__); | |
108 } | 104 } |
109 | 105 |
110 // ---------------------------------------------------------------------------- | 106 // ---------------------------------------------------------------------------- |
111 // AudioDeviceLinuxALSA - dtor | 107 // AudioDeviceLinuxALSA - dtor |
112 // ---------------------------------------------------------------------------- | 108 // ---------------------------------------------------------------------------- |
113 | 109 |
114 AudioDeviceLinuxALSA::~AudioDeviceLinuxALSA() | 110 AudioDeviceLinuxALSA::~AudioDeviceLinuxALSA() |
115 { | 111 { |
116 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, | 112 LOG(LS_INFO) << __FUNCTION__ << " destroyed"; |
117 "%s destroyed", __FUNCTION__); | |
118 | 113 |
119 Terminate(); | 114 Terminate(); |
120 | 115 |
121 // Clean up the recording buffer and playout buffer. | 116 // Clean up the recording buffer and playout buffer. |
122 if (_recordingBuffer) | 117 if (_recordingBuffer) |
123 { | 118 { |
124 delete [] _recordingBuffer; | 119 delete [] _recordingBuffer; |
125 _recordingBuffer = NULL; | 120 _recordingBuffer = NULL; |
126 } | 121 } |
127 if (_playoutBuffer) | 122 if (_playoutBuffer) |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
325 volume = level; | 320 volume = level; |
326 | 321 |
327 return 0; | 322 return 0; |
328 } | 323 } |
329 | 324 |
330 | 325 |
331 int32_t AudioDeviceLinuxALSA::SetWaveOutVolume(uint16_t volumeLeft, | 326 int32_t AudioDeviceLinuxALSA::SetWaveOutVolume(uint16_t volumeLeft, |
332 uint16_t volumeRight) | 327 uint16_t volumeRight) |
333 { | 328 { |
334 | 329 |
335 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 330 LOG(LS_WARNING) << "API call not supported on this platform"; |
336 " API call not supported on this platform"); | |
337 return -1; | 331 return -1; |
338 } | 332 } |
339 | 333 |
340 int32_t AudioDeviceLinuxALSA::WaveOutVolume( | 334 int32_t AudioDeviceLinuxALSA::WaveOutVolume( |
341 uint16_t& /*volumeLeft*/, | 335 uint16_t& /*volumeLeft*/, |
342 uint16_t& /*volumeRight*/) const | 336 uint16_t& /*volumeRight*/) const |
343 { | 337 { |
344 | 338 |
345 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 339 LOG(LS_WARNING) << "API call not supported on this platform"; |
346 " API call not supported on this platform"); | |
347 return -1; | 340 return -1; |
348 } | 341 } |
349 | 342 |
350 int32_t AudioDeviceLinuxALSA::MaxSpeakerVolume( | 343 int32_t AudioDeviceLinuxALSA::MaxSpeakerVolume( |
351 uint32_t& maxVolume) const | 344 uint32_t& maxVolume) const |
352 { | 345 { |
353 | 346 |
354 uint32_t maxVol(0); | 347 uint32_t maxVol(0); |
355 | 348 |
356 if (_mixerManager.MaxSpeakerVolume(maxVol) == -1) | 349 if (_mixerManager.MaxSpeakerVolume(maxVol) == -1) |
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
747 return 0; | 740 return 0; |
748 } | 741 } |
749 | 742 |
750 int32_t AudioDeviceLinuxALSA::MicrophoneVolume(uint32_t& volume) const | 743 int32_t AudioDeviceLinuxALSA::MicrophoneVolume(uint32_t& volume) const |
751 { | 744 { |
752 | 745 |
753 uint32_t level(0); | 746 uint32_t level(0); |
754 | 747 |
755 if (_mixerManager.MicrophoneVolume(level) == -1) | 748 if (_mixerManager.MicrophoneVolume(level) == -1) |
756 { | 749 { |
757 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 750 LOG(LS_WARNING) << "failed to retrive current microphone level"; |
758 " failed to retrive current microphone level"); | |
759 return -1; | 751 return -1; |
760 } | 752 } |
761 | 753 |
762 volume = level; | 754 volume = level; |
763 | 755 |
764 return 0; | 756 return 0; |
765 } | 757 } |
766 | 758 |
767 int32_t AudioDeviceLinuxALSA::MaxMicrophoneVolume( | 759 int32_t AudioDeviceLinuxALSA::MaxMicrophoneVolume( |
768 uint32_t& maxVolume) const | 760 uint32_t& maxVolume) const |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
820 | 812 |
821 int32_t AudioDeviceLinuxALSA::SetPlayoutDevice(uint16_t index) | 813 int32_t AudioDeviceLinuxALSA::SetPlayoutDevice(uint16_t index) |
822 { | 814 { |
823 | 815 |
824 if (_playIsInitialized) | 816 if (_playIsInitialized) |
825 { | 817 { |
826 return -1; | 818 return -1; |
827 } | 819 } |
828 | 820 |
829 uint32_t nDevices = GetDevicesInfo(0, true); | 821 uint32_t nDevices = GetDevicesInfo(0, true); |
830 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 822 LOG(LS_VERBOSE) << "number of available audio output devices is " |
831 " number of availiable audio output devices is %u", nDevices); | 823 << nDevices; |
832 | 824 |
833 if (index > (nDevices-1)) | 825 if (index > (nDevices-1)) |
834 { | 826 { |
835 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 827 LOG(LS_ERROR) << "device index is out of range [0," << (nDevices-1) |
836 " device index is out of range [0,%u]", (nDevices-1)); | 828 << "]"; |
837 return -1; | 829 return -1; |
838 } | 830 } |
839 | 831 |
840 _outputDeviceIndex = index; | 832 _outputDeviceIndex = index; |
841 _outputDeviceIsSpecified = true; | 833 _outputDeviceIsSpecified = true; |
842 | 834 |
843 return 0; | 835 return 0; |
844 } | 836 } |
845 | 837 |
846 int32_t AudioDeviceLinuxALSA::SetPlayoutDevice( | 838 int32_t AudioDeviceLinuxALSA::SetPlayoutDevice( |
847 AudioDeviceModule::WindowsDeviceType /*device*/) | 839 AudioDeviceModule::WindowsDeviceType /*device*/) |
848 { | 840 { |
849 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 841 LOG(LS_ERROR) << "WindowsDeviceType not supported"; |
850 "WindowsDeviceType not supported"); | |
851 return -1; | 842 return -1; |
852 } | 843 } |
853 | 844 |
854 int32_t AudioDeviceLinuxALSA::PlayoutDeviceName( | 845 int32_t AudioDeviceLinuxALSA::PlayoutDeviceName( |
855 uint16_t index, | 846 uint16_t index, |
856 char name[kAdmMaxDeviceNameSize], | 847 char name[kAdmMaxDeviceNameSize], |
857 char guid[kAdmMaxGuidSize]) | 848 char guid[kAdmMaxGuidSize]) |
858 { | 849 { |
859 | 850 |
860 const uint16_t nDevices(PlayoutDevices()); | 851 const uint16_t nDevices(PlayoutDevices()); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
905 | 896 |
906 int32_t AudioDeviceLinuxALSA::SetRecordingDevice(uint16_t index) | 897 int32_t AudioDeviceLinuxALSA::SetRecordingDevice(uint16_t index) |
907 { | 898 { |
908 | 899 |
909 if (_recIsInitialized) | 900 if (_recIsInitialized) |
910 { | 901 { |
911 return -1; | 902 return -1; |
912 } | 903 } |
913 | 904 |
914 uint32_t nDevices = GetDevicesInfo(0, false); | 905 uint32_t nDevices = GetDevicesInfo(0, false); |
915 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 906 LOG(LS_VERBOSE) << "number of availiable audio input devices is " |
916 " number of availiable audio input devices is %u", nDevices); | 907 << nDevices; |
917 | 908 |
918 if (index > (nDevices-1)) | 909 if (index > (nDevices-1)) |
919 { | 910 { |
920 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 911 LOG(LS_ERROR) << "device index is out of range [0," << (nDevices-1) |
921 " device index is out of range [0,%u]", (nDevices-1)); | 912 << "]"; |
922 return -1; | 913 return -1; |
923 } | 914 } |
924 | 915 |
925 _inputDeviceIndex = index; | 916 _inputDeviceIndex = index; |
926 _inputDeviceIsSpecified = true; | 917 _inputDeviceIsSpecified = true; |
927 | 918 |
928 return 0; | 919 return 0; |
929 } | 920 } |
930 | 921 |
931 // ---------------------------------------------------------------------------- | 922 // ---------------------------------------------------------------------------- |
932 // SetRecordingDevice II (II) | 923 // SetRecordingDevice II (II) |
933 // ---------------------------------------------------------------------------- | 924 // ---------------------------------------------------------------------------- |
934 | 925 |
935 int32_t AudioDeviceLinuxALSA::SetRecordingDevice( | 926 int32_t AudioDeviceLinuxALSA::SetRecordingDevice( |
936 AudioDeviceModule::WindowsDeviceType /*device*/) | 927 AudioDeviceModule::WindowsDeviceType /*device*/) |
937 { | 928 { |
938 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 929 LOG(LS_ERROR) << "WindowsDeviceType not supported"; |
939 "WindowsDeviceType not supported"); | |
940 return -1; | 930 return -1; |
941 } | 931 } |
942 | 932 |
943 int32_t AudioDeviceLinuxALSA::PlayoutIsAvailable(bool& available) | 933 int32_t AudioDeviceLinuxALSA::PlayoutIsAvailable(bool& available) |
944 { | 934 { |
945 | 935 |
946 available = false; | 936 available = false; |
947 | 937 |
948 // Try to initialize the playout side with mono | 938 // Try to initialize the playout side with mono |
949 // Assumes that user set num channels after calling this function | 939 // Assumes that user set num channels after calling this function |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1018 return -1; | 1008 return -1; |
1019 } | 1009 } |
1020 | 1010 |
1021 if (_playIsInitialized) | 1011 if (_playIsInitialized) |
1022 { | 1012 { |
1023 return 0; | 1013 return 0; |
1024 } | 1014 } |
1025 // Initialize the speaker (devices might have been added or removed) | 1015 // Initialize the speaker (devices might have been added or removed) |
1026 if (InitSpeaker() == -1) | 1016 if (InitSpeaker() == -1) |
1027 { | 1017 { |
1028 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 1018 LOG(LS_WARNING) << "InitSpeaker() failed"; |
1029 " InitSpeaker() failed"); | |
1030 } | 1019 } |
1031 | 1020 |
1032 // Start by closing any existing wave-output devices | 1021 // Start by closing any existing wave-output devices |
1033 // | 1022 // |
1034 if (_handlePlayout != NULL) | 1023 if (_handlePlayout != NULL) |
1035 { | 1024 { |
1036 LATE(snd_pcm_close)(_handlePlayout); | 1025 LATE(snd_pcm_close)(_handlePlayout); |
1037 _handlePlayout = NULL; | 1026 _handlePlayout = NULL; |
1038 _playIsInitialized = false; | 1027 _playIsInitialized = false; |
1039 if (errVal < 0) | 1028 if (errVal < 0) |
1040 { | 1029 { |
1041 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 1030 LOG(LS_ERROR) |
1042 " Error closing current playout sound device, error:" | 1031 << "Error closing current playout sound device, error: " |
1043 " %s", LATE(snd_strerror)(errVal)); | 1032 << LATE(snd_strerror)(errVal); |
1044 } | 1033 } |
1045 } | 1034 } |
1046 | 1035 |
1047 // Open PCM device for playout | 1036 // Open PCM device for playout |
1048 char deviceName[kAdmMaxDeviceNameSize] = {0}; | 1037 char deviceName[kAdmMaxDeviceNameSize] = {0}; |
1049 GetDevicesInfo(2, true, _outputDeviceIndex, deviceName, | 1038 GetDevicesInfo(2, true, _outputDeviceIndex, deviceName, |
1050 kAdmMaxDeviceNameSize); | 1039 kAdmMaxDeviceNameSize); |
1051 | 1040 |
1052 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 1041 LOG(LS_VERBOSE) << "InitPlayout open (" << deviceName << ")"; |
1053 " InitPlayout open (%s)", deviceName); | |
1054 | 1042 |
1055 errVal = LATE(snd_pcm_open) | 1043 errVal = LATE(snd_pcm_open) |
1056 (&_handlePlayout, | 1044 (&_handlePlayout, |
1057 deviceName, | 1045 deviceName, |
1058 SND_PCM_STREAM_PLAYBACK, | 1046 SND_PCM_STREAM_PLAYBACK, |
1059 SND_PCM_NONBLOCK); | 1047 SND_PCM_NONBLOCK); |
1060 | 1048 |
1061 if (errVal == -EBUSY) // Device busy - try some more! | 1049 if (errVal == -EBUSY) // Device busy - try some more! |
1062 { | 1050 { |
1063 for (int i=0; i < 5; i++) | 1051 for (int i=0; i < 5; i++) |
1064 { | 1052 { |
1065 SleepMs(1000); | 1053 SleepMs(1000); |
1066 errVal = LATE(snd_pcm_open) | 1054 errVal = LATE(snd_pcm_open) |
1067 (&_handlePlayout, | 1055 (&_handlePlayout, |
1068 deviceName, | 1056 deviceName, |
1069 SND_PCM_STREAM_PLAYBACK, | 1057 SND_PCM_STREAM_PLAYBACK, |
1070 SND_PCM_NONBLOCK); | 1058 SND_PCM_NONBLOCK); |
1071 if (errVal == 0) | 1059 if (errVal == 0) |
1072 { | 1060 { |
1073 break; | 1061 break; |
1074 } | 1062 } |
1075 } | 1063 } |
1076 } | 1064 } |
1077 if (errVal < 0) | 1065 if (errVal < 0) |
1078 { | 1066 { |
1079 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 1067 LOG(LS_ERROR) << "unable to open playback device: " |
1080 " unable to open playback device: %s (%d)", | 1068 << LATE(snd_strerror)(errVal) << " (" << errVal << ")"; |
1081 LATE(snd_strerror)(errVal), | |
1082 errVal); | |
1083 _handlePlayout = NULL; | 1069 _handlePlayout = NULL; |
1084 return -1; | 1070 return -1; |
1085 } | 1071 } |
1086 | 1072 |
1087 _playoutFramesIn10MS = _playoutFreq/100; | 1073 _playoutFramesIn10MS = _playoutFreq/100; |
1088 if ((errVal = LATE(snd_pcm_set_params)( _handlePlayout, | 1074 if ((errVal = LATE(snd_pcm_set_params)( _handlePlayout, |
1089 #if defined(WEBRTC_ARCH_BIG_ENDIAN) | 1075 #if defined(WEBRTC_ARCH_BIG_ENDIAN) |
1090 SND_PCM_FORMAT_S16_BE, | 1076 SND_PCM_FORMAT_S16_BE, |
1091 #else | 1077 #else |
1092 SND_PCM_FORMAT_S16_LE, //format | 1078 SND_PCM_FORMAT_S16_LE, //format |
1093 #endif | 1079 #endif |
1094 SND_PCM_ACCESS_RW_INTERLEAVED, //access | 1080 SND_PCM_ACCESS_RW_INTERLEAVED, //access |
1095 _playChannels, //channels | 1081 _playChannels, //channels |
1096 _playoutFreq, //rate | 1082 _playoutFreq, //rate |
1097 1, //soft_resample | 1083 1, //soft_resample |
1098 ALSA_PLAYOUT_LATENCY //40*1000 //latency required overall latency in us | 1084 ALSA_PLAYOUT_LATENCY //40*1000 //latency required overall latency in us |
1099 )) < 0) | 1085 )) < 0) |
1100 { /* 0.5sec */ | 1086 { /* 0.5sec */ |
1101 _playoutFramesIn10MS = 0; | 1087 _playoutFramesIn10MS = 0; |
1102 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 1088 LOG(LS_ERROR) << "unable to set playback device: " |
1103 " unable to set playback device: %s (%d)", | 1089 << LATE(snd_strerror)(errVal) << " (" << errVal << ")"; |
1104 LATE(snd_strerror)(errVal), | |
1105 errVal); | |
1106 ErrorRecovery(errVal, _handlePlayout); | 1090 ErrorRecovery(errVal, _handlePlayout); |
1107 errVal = LATE(snd_pcm_close)(_handlePlayout); | 1091 errVal = LATE(snd_pcm_close)(_handlePlayout); |
1108 _handlePlayout = NULL; | 1092 _handlePlayout = NULL; |
1109 return -1; | 1093 return -1; |
1110 } | 1094 } |
1111 | 1095 |
1112 errVal = LATE(snd_pcm_get_params)(_handlePlayout, | 1096 errVal = LATE(snd_pcm_get_params)(_handlePlayout, |
1113 &_playoutBufferSizeInFrame, &_playoutPeriodSizeInFrame); | 1097 &_playoutBufferSizeInFrame, &_playoutPeriodSizeInFrame); |
1114 if (errVal < 0) | 1098 if (errVal < 0) |
1115 { | 1099 { |
1116 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 1100 LOG(LS_ERROR) << "snd_pcm_get_params: " << LATE(snd_strerror)(errVal) |
1117 " snd_pcm_get_params %s", | 1101 << " (" << errVal << ")"; |
1118 LATE(snd_strerror)(errVal), | |
1119 errVal); | |
1120 _playoutBufferSizeInFrame = 0; | 1102 _playoutBufferSizeInFrame = 0; |
1121 _playoutPeriodSizeInFrame = 0; | 1103 _playoutPeriodSizeInFrame = 0; |
1122 } | 1104 } |
1123 else { | 1105 else { |
1124 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 1106 LOG(LS_VERBOSE) << "playout snd_pcm_get_params buffer_size:" |
1125 " playout snd_pcm_get_params " | 1107 << _playoutBufferSizeInFrame << " period_size :" |
1126 "buffer_size:%d period_size :%d", | 1108 << _playoutPeriodSizeInFrame; |
1127 _playoutBufferSizeInFrame, _playoutPeriodSizeInFrame); | |
1128 } | 1109 } |
1129 | 1110 |
1130 if (_ptrAudioBuffer) | 1111 if (_ptrAudioBuffer) |
1131 { | 1112 { |
1132 // Update webrtc audio buffer with the selected parameters | 1113 // Update webrtc audio buffer with the selected parameters |
1133 _ptrAudioBuffer->SetPlayoutSampleRate(_playoutFreq); | 1114 _ptrAudioBuffer->SetPlayoutSampleRate(_playoutFreq); |
1134 _ptrAudioBuffer->SetPlayoutChannels(_playChannels); | 1115 _ptrAudioBuffer->SetPlayoutChannels(_playChannels); |
1135 } | 1116 } |
1136 | 1117 |
1137 // Set play buffer size | 1118 // Set play buffer size |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1173 } | 1154 } |
1174 | 1155 |
1175 if (_recIsInitialized) | 1156 if (_recIsInitialized) |
1176 { | 1157 { |
1177 return 0; | 1158 return 0; |
1178 } | 1159 } |
1179 | 1160 |
1180 // Initialize the microphone (devices might have been added or removed) | 1161 // Initialize the microphone (devices might have been added or removed) |
1181 if (InitMicrophone() == -1) | 1162 if (InitMicrophone() == -1) |
1182 { | 1163 { |
1183 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 1164 LOG(LS_WARNING) << "InitMicrophone() failed"; |
1184 " InitMicrophone() failed"); | |
1185 } | 1165 } |
1186 | 1166 |
1187 // Start by closing any existing pcm-input devices | 1167 // Start by closing any existing pcm-input devices |
1188 // | 1168 // |
1189 if (_handleRecord != NULL) | 1169 if (_handleRecord != NULL) |
1190 { | 1170 { |
1191 int errVal = LATE(snd_pcm_close)(_handleRecord); | 1171 int errVal = LATE(snd_pcm_close)(_handleRecord); |
1192 _handleRecord = NULL; | 1172 _handleRecord = NULL; |
1193 _recIsInitialized = false; | 1173 _recIsInitialized = false; |
1194 if (errVal < 0) | 1174 if (errVal < 0) |
1195 { | 1175 { |
1196 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 1176 LOG(LS_ERROR) |
1197 " Error closing current recording sound device," | 1177 << "Error closing current recording sound device, error: " |
1198 " error: %s", | 1178 << LATE(snd_strerror)(errVal); |
1199 LATE(snd_strerror)(errVal)); | |
1200 } | 1179 } |
1201 } | 1180 } |
1202 | 1181 |
1203 // Open PCM device for recording | 1182 // Open PCM device for recording |
1204 // The corresponding settings for playout are made after the record settings | 1183 // The corresponding settings for playout are made after the record settings |
1205 char deviceName[kAdmMaxDeviceNameSize] = {0}; | 1184 char deviceName[kAdmMaxDeviceNameSize] = {0}; |
1206 GetDevicesInfo(2, false, _inputDeviceIndex, deviceName, | 1185 GetDevicesInfo(2, false, _inputDeviceIndex, deviceName, |
1207 kAdmMaxDeviceNameSize); | 1186 kAdmMaxDeviceNameSize); |
1208 | 1187 |
1209 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 1188 LOG(LS_VERBOSE) << "InitRecording open (" << deviceName << ")"; |
1210 "InitRecording open (%s)", deviceName); | |
1211 errVal = LATE(snd_pcm_open) | 1189 errVal = LATE(snd_pcm_open) |
1212 (&_handleRecord, | 1190 (&_handleRecord, |
1213 deviceName, | 1191 deviceName, |
1214 SND_PCM_STREAM_CAPTURE, | 1192 SND_PCM_STREAM_CAPTURE, |
1215 SND_PCM_NONBLOCK); | 1193 SND_PCM_NONBLOCK); |
1216 | 1194 |
1217 // Available modes: 0 = blocking, SND_PCM_NONBLOCK, SND_PCM_ASYNC | 1195 // Available modes: 0 = blocking, SND_PCM_NONBLOCK, SND_PCM_ASYNC |
1218 if (errVal == -EBUSY) // Device busy - try some more! | 1196 if (errVal == -EBUSY) // Device busy - try some more! |
1219 { | 1197 { |
1220 for (int i=0; i < 5; i++) | 1198 for (int i=0; i < 5; i++) |
1221 { | 1199 { |
1222 SleepMs(1000); | 1200 SleepMs(1000); |
1223 errVal = LATE(snd_pcm_open) | 1201 errVal = LATE(snd_pcm_open) |
1224 (&_handleRecord, | 1202 (&_handleRecord, |
1225 deviceName, | 1203 deviceName, |
1226 SND_PCM_STREAM_CAPTURE, | 1204 SND_PCM_STREAM_CAPTURE, |
1227 SND_PCM_NONBLOCK); | 1205 SND_PCM_NONBLOCK); |
1228 if (errVal == 0) | 1206 if (errVal == 0) |
1229 { | 1207 { |
1230 break; | 1208 break; |
1231 } | 1209 } |
1232 } | 1210 } |
1233 } | 1211 } |
1234 if (errVal < 0) | 1212 if (errVal < 0) |
1235 { | 1213 { |
1236 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 1214 LOG(LS_ERROR) << "unable to open record device: " |
1237 " unable to open record device: %s", | 1215 << LATE(snd_strerror)(errVal); |
1238 LATE(snd_strerror)(errVal)); | |
1239 _handleRecord = NULL; | 1216 _handleRecord = NULL; |
1240 return -1; | 1217 return -1; |
1241 } | 1218 } |
1242 | 1219 |
1243 _recordingFramesIn10MS = _recordingFreq/100; | 1220 _recordingFramesIn10MS = _recordingFreq/100; |
1244 if ((errVal = LATE(snd_pcm_set_params)(_handleRecord, | 1221 if ((errVal = LATE(snd_pcm_set_params)(_handleRecord, |
1245 #if defined(WEBRTC_ARCH_BIG_ENDIAN) | 1222 #if defined(WEBRTC_ARCH_BIG_ENDIAN) |
1246 SND_PCM_FORMAT_S16_BE, //format | 1223 SND_PCM_FORMAT_S16_BE, //format |
1247 #else | 1224 #else |
1248 SND_PCM_FORMAT_S16_LE, //format | 1225 SND_PCM_FORMAT_S16_LE, //format |
(...skipping 18 matching lines...) Expand all Loading... |
1267 SND_PCM_FORMAT_S16_LE, //format | 1244 SND_PCM_FORMAT_S16_LE, //format |
1268 #endif | 1245 #endif |
1269 SND_PCM_ACCESS_RW_INTERLEAVED, //access | 1246 SND_PCM_ACCESS_RW_INTERLEAVED, //access |
1270 _recChannels, //channels | 1247 _recChannels, //channels |
1271 _recordingFreq, //rate | 1248 _recordingFreq, //rate |
1272 1, //soft_resample | 1249 1, //soft_resample |
1273 ALSA_CAPTURE_LATENCY //latency in us | 1250 ALSA_CAPTURE_LATENCY //latency in us |
1274 )) < 0) | 1251 )) < 0) |
1275 { | 1252 { |
1276 _recordingFramesIn10MS = 0; | 1253 _recordingFramesIn10MS = 0; |
1277 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 1254 LOG(LS_ERROR) << "unable to set record settings: " |
1278 " unable to set record settings: %s (%d)", | 1255 << LATE(snd_strerror)(errVal) << " (" << errVal |
1279 LATE(snd_strerror)(errVal), errVal); | 1256 << ")"; |
1280 ErrorRecovery(errVal, _handleRecord); | 1257 ErrorRecovery(errVal, _handleRecord); |
1281 errVal = LATE(snd_pcm_close)(_handleRecord); | 1258 errVal = LATE(snd_pcm_close)(_handleRecord); |
1282 _handleRecord = NULL; | 1259 _handleRecord = NULL; |
1283 return -1; | 1260 return -1; |
1284 } | 1261 } |
1285 } | 1262 } |
1286 | 1263 |
1287 errVal = LATE(snd_pcm_get_params)(_handleRecord, | 1264 errVal = LATE(snd_pcm_get_params)(_handleRecord, |
1288 &_recordingBuffersizeInFrame, &_recordingPeriodSizeInFrame); | 1265 &_recordingBuffersizeInFrame, &_recordingPeriodSizeInFrame); |
1289 if (errVal < 0) | 1266 if (errVal < 0) |
1290 { | 1267 { |
1291 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 1268 LOG(LS_ERROR) << "snd_pcm_get_params " << LATE(snd_strerror)(errVal) |
1292 " snd_pcm_get_params %s", | 1269 << " (" << errVal << ")"; |
1293 LATE(snd_strerror)(errVal), errVal); | |
1294 _recordingBuffersizeInFrame = 0; | 1270 _recordingBuffersizeInFrame = 0; |
1295 _recordingPeriodSizeInFrame = 0; | 1271 _recordingPeriodSizeInFrame = 0; |
1296 } | 1272 } |
1297 else { | 1273 else { |
1298 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 1274 LOG(LS_VERBOSE) << "capture snd_pcm_get_params, buffer_size:" |
1299 " capture snd_pcm_get_params " | 1275 << _recordingBuffersizeInFrame << ", period_size:" |
1300 "buffer_size:%d period_size:%d", | 1276 << _recordingPeriodSizeInFrame; |
1301 _recordingBuffersizeInFrame, _recordingPeriodSizeInFrame); | |
1302 } | 1277 } |
1303 | 1278 |
1304 if (_ptrAudioBuffer) | 1279 if (_ptrAudioBuffer) |
1305 { | 1280 { |
1306 // Update webrtc audio buffer with the selected parameters | 1281 // Update webrtc audio buffer with the selected parameters |
1307 _ptrAudioBuffer->SetRecordingSampleRate(_recordingFreq); | 1282 _ptrAudioBuffer->SetRecordingSampleRate(_recordingFreq); |
1308 _ptrAudioBuffer->SetRecordingChannels(_recChannels); | 1283 _ptrAudioBuffer->SetRecordingChannels(_recChannels); |
1309 } | 1284 } |
1310 | 1285 |
1311 // Set rec buffer size and create buffer | 1286 // Set rec buffer size and create buffer |
(...skipping 30 matching lines...) Expand all Loading... |
1342 _recording = true; | 1317 _recording = true; |
1343 | 1318 |
1344 int errVal = 0; | 1319 int errVal = 0; |
1345 _recordingFramesLeft = _recordingFramesIn10MS; | 1320 _recordingFramesLeft = _recordingFramesIn10MS; |
1346 | 1321 |
1347 // Make sure we only create the buffer once. | 1322 // Make sure we only create the buffer once. |
1348 if (!_recordingBuffer) | 1323 if (!_recordingBuffer) |
1349 _recordingBuffer = new int8_t[_recordingBufferSizeIn10MS]; | 1324 _recordingBuffer = new int8_t[_recordingBufferSizeIn10MS]; |
1350 if (!_recordingBuffer) | 1325 if (!_recordingBuffer) |
1351 { | 1326 { |
1352 WEBRTC_TRACE(kTraceCritical, kTraceAudioDevice, _id, | 1327 LOG(LS_ERROR) << "failed to alloc recording buffer"; |
1353 " failed to alloc recording buffer"); | |
1354 _recording = false; | 1328 _recording = false; |
1355 return -1; | 1329 return -1; |
1356 } | 1330 } |
1357 // RECORDING | 1331 // RECORDING |
1358 _ptrThreadRec.reset(new rtc::PlatformThread( | 1332 _ptrThreadRec.reset(new rtc::PlatformThread( |
1359 RecThreadFunc, this, "webrtc_audio_module_capture_thread")); | 1333 RecThreadFunc, this, "webrtc_audio_module_capture_thread")); |
1360 | 1334 |
1361 _ptrThreadRec->Start(); | 1335 _ptrThreadRec->Start(); |
1362 _ptrThreadRec->SetPriority(rtc::kRealtimePriority); | 1336 _ptrThreadRec->SetPriority(rtc::kRealtimePriority); |
1363 | 1337 |
1364 errVal = LATE(snd_pcm_prepare)(_handleRecord); | 1338 errVal = LATE(snd_pcm_prepare)(_handleRecord); |
1365 if (errVal < 0) | 1339 if (errVal < 0) |
1366 { | 1340 { |
1367 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 1341 LOG(LS_ERROR) << "capture snd_pcm_prepare failed (" |
1368 " capture snd_pcm_prepare failed (%s)\n", | 1342 << LATE(snd_strerror)(errVal) << ")\n"; |
1369 LATE(snd_strerror)(errVal)); | |
1370 // just log error | 1343 // just log error |
1371 // if snd_pcm_open fails will return -1 | 1344 // if snd_pcm_open fails will return -1 |
1372 } | 1345 } |
1373 | 1346 |
1374 errVal = LATE(snd_pcm_start)(_handleRecord); | 1347 errVal = LATE(snd_pcm_start)(_handleRecord); |
1375 if (errVal < 0) | 1348 if (errVal < 0) |
1376 { | 1349 { |
1377 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 1350 LOG(LS_ERROR) << "capture snd_pcm_start err: " |
1378 " capture snd_pcm_start err: %s", | 1351 << LATE(snd_strerror)(errVal); |
1379 LATE(snd_strerror)(errVal)); | |
1380 errVal = LATE(snd_pcm_start)(_handleRecord); | 1352 errVal = LATE(snd_pcm_start)(_handleRecord); |
1381 if (errVal < 0) | 1353 if (errVal < 0) |
1382 { | 1354 { |
1383 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 1355 LOG(LS_ERROR) << "capture snd_pcm_start 2nd try err: " |
1384 " capture snd_pcm_start 2nd try err: %s", | 1356 << LATE(snd_strerror)(errVal); |
1385 LATE(snd_strerror)(errVal)); | |
1386 StopRecording(); | 1357 StopRecording(); |
1387 return -1; | 1358 return -1; |
1388 } | 1359 } |
1389 } | 1360 } |
1390 | 1361 |
1391 return 0; | 1362 return 0; |
1392 } | 1363 } |
1393 | 1364 |
1394 int32_t AudioDeviceLinuxALSA::StopRecording() | 1365 int32_t AudioDeviceLinuxALSA::StopRecording() |
1395 { | 1366 { |
(...skipping 27 matching lines...) Expand all Loading... |
1423 if (_recordingBuffer) | 1394 if (_recordingBuffer) |
1424 { | 1395 { |
1425 delete [] _recordingBuffer; | 1396 delete [] _recordingBuffer; |
1426 _recordingBuffer = NULL; | 1397 _recordingBuffer = NULL; |
1427 } | 1398 } |
1428 | 1399 |
1429 // Stop and close pcm recording device. | 1400 // Stop and close pcm recording device. |
1430 int errVal = LATE(snd_pcm_drop)(_handleRecord); | 1401 int errVal = LATE(snd_pcm_drop)(_handleRecord); |
1431 if (errVal < 0) | 1402 if (errVal < 0) |
1432 { | 1403 { |
1433 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 1404 LOG(LS_ERROR) << "Error stop recording: " << LATE(snd_strerror)(errVal); |
1434 " Error stop recording: %s", | |
1435 LATE(snd_strerror)(errVal)); | |
1436 return -1; | 1405 return -1; |
1437 } | 1406 } |
1438 | 1407 |
1439 errVal = LATE(snd_pcm_close)(_handleRecord); | 1408 errVal = LATE(snd_pcm_close)(_handleRecord); |
1440 if (errVal < 0) | 1409 if (errVal < 0) |
1441 { | 1410 { |
1442 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 1411 LOG(LS_ERROR) << "Error closing record sound device, error: " |
1443 " Error closing record sound device, error: %s", | 1412 << LATE(snd_strerror)(errVal); |
1444 LATE(snd_strerror)(errVal)); | |
1445 return -1; | 1413 return -1; |
1446 } | 1414 } |
1447 | 1415 |
1448 // Check if we have muted and unmute if so. | 1416 // Check if we have muted and unmute if so. |
1449 bool muteEnabled = false; | 1417 bool muteEnabled = false; |
1450 MicrophoneMute(muteEnabled); | 1418 MicrophoneMute(muteEnabled); |
1451 if (muteEnabled) | 1419 if (muteEnabled) |
1452 { | 1420 { |
1453 SetMicrophoneMute(false); | 1421 SetMicrophoneMute(false); |
1454 } | 1422 } |
(...skipping 30 matching lines...) Expand all Loading... |
1485 return 0; | 1453 return 0; |
1486 } | 1454 } |
1487 | 1455 |
1488 _playing = true; | 1456 _playing = true; |
1489 | 1457 |
1490 _playoutFramesLeft = 0; | 1458 _playoutFramesLeft = 0; |
1491 if (!_playoutBuffer) | 1459 if (!_playoutBuffer) |
1492 _playoutBuffer = new int8_t[_playoutBufferSizeIn10MS]; | 1460 _playoutBuffer = new int8_t[_playoutBufferSizeIn10MS]; |
1493 if (!_playoutBuffer) | 1461 if (!_playoutBuffer) |
1494 { | 1462 { |
1495 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 1463 LOG(LS_ERROR) << "failed to alloc playout buf"; |
1496 " failed to alloc playout buf"); | |
1497 _playing = false; | 1464 _playing = false; |
1498 return -1; | 1465 return -1; |
1499 } | 1466 } |
1500 | 1467 |
1501 // PLAYOUT | 1468 // PLAYOUT |
1502 _ptrThreadPlay.reset(new rtc::PlatformThread( | 1469 _ptrThreadPlay.reset(new rtc::PlatformThread( |
1503 PlayThreadFunc, this, "webrtc_audio_module_play_thread")); | 1470 PlayThreadFunc, this, "webrtc_audio_module_play_thread")); |
1504 _ptrThreadPlay->Start(); | 1471 _ptrThreadPlay->Start(); |
1505 _ptrThreadPlay->SetPriority(rtc::kRealtimePriority); | 1472 _ptrThreadPlay->SetPriority(rtc::kRealtimePriority); |
1506 | 1473 |
1507 int errVal = LATE(snd_pcm_prepare)(_handlePlayout); | 1474 int errVal = LATE(snd_pcm_prepare)(_handlePlayout); |
1508 if (errVal < 0) | 1475 if (errVal < 0) |
1509 { | 1476 { |
1510 WEBRTC_TRACE(kTraceCritical, kTraceAudioDevice, _id, | 1477 LOG(LS_ERROR) << "playout snd_pcm_prepare failed (" |
1511 " playout snd_pcm_prepare failed (%s)\n", | 1478 << LATE(snd_strerror)(errVal) << ")\n"; |
1512 LATE(snd_strerror)(errVal)); | |
1513 // just log error | 1479 // just log error |
1514 // if snd_pcm_open fails will return -1 | 1480 // if snd_pcm_open fails will return -1 |
1515 } | 1481 } |
1516 | 1482 |
1517 return 0; | 1483 return 0; |
1518 } | 1484 } |
1519 | 1485 |
1520 int32_t AudioDeviceLinuxALSA::StopPlayout() | 1486 int32_t AudioDeviceLinuxALSA::StopPlayout() |
1521 { | 1487 { |
1522 | 1488 |
(...skipping 23 matching lines...) Expand all Loading... |
1546 rtc::CritScope lock(&_critSect); | 1512 rtc::CritScope lock(&_critSect); |
1547 | 1513 |
1548 _playoutFramesLeft = 0; | 1514 _playoutFramesLeft = 0; |
1549 delete [] _playoutBuffer; | 1515 delete [] _playoutBuffer; |
1550 _playoutBuffer = NULL; | 1516 _playoutBuffer = NULL; |
1551 | 1517 |
1552 // stop and close pcm playout device | 1518 // stop and close pcm playout device |
1553 int errVal = LATE(snd_pcm_drop)(_handlePlayout); | 1519 int errVal = LATE(snd_pcm_drop)(_handlePlayout); |
1554 if (errVal < 0) | 1520 if (errVal < 0) |
1555 { | 1521 { |
1556 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 1522 LOG(LS_ERROR) << "Error stop playing: " << LATE(snd_strerror)(errVal); |
1557 " Error stop playing: %s", | |
1558 LATE(snd_strerror)(errVal)); | |
1559 } | 1523 } |
1560 | 1524 |
1561 errVal = LATE(snd_pcm_close)(_handlePlayout); | 1525 errVal = LATE(snd_pcm_close)(_handlePlayout); |
1562 if (errVal < 0) | 1526 if (errVal < 0) |
1563 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 1527 LOG(LS_ERROR) << "Error closing playout sound device, error: " |
1564 " Error closing playout sound device, error: %s", | 1528 << LATE(snd_strerror)(errVal); |
1565 LATE(snd_strerror)(errVal)); | |
1566 | 1529 |
1567 // set the pcm input handle to NULL | 1530 // set the pcm input handle to NULL |
1568 _playIsInitialized = false; | 1531 _playIsInitialized = false; |
1569 _handlePlayout = NULL; | 1532 _handlePlayout = NULL; |
1570 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 1533 LOG(LS_VERBOSE) << "handle_playout is now set to NULL"; |
1571 " handle_playout is now set to NULL"); | |
1572 | 1534 |
1573 return 0; | 1535 return 0; |
1574 } | 1536 } |
1575 | 1537 |
1576 int32_t AudioDeviceLinuxALSA::PlayoutDelay(uint16_t& delayMS) const | 1538 int32_t AudioDeviceLinuxALSA::PlayoutDelay(uint16_t& delayMS) const |
1577 { | 1539 { |
1578 delayMS = (uint16_t)_playoutDelay * 1000 / _playoutFreq; | 1540 delayMS = (uint16_t)_playoutDelay * 1000 / _playoutFreq; |
1579 return 0; | 1541 return 0; |
1580 } | 1542 } |
1581 | 1543 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1619 { | 1581 { |
1620 sizeMS = _playBufDelay; | 1582 sizeMS = _playBufDelay; |
1621 } | 1583 } |
1622 | 1584 |
1623 return 0; | 1585 return 0; |
1624 } | 1586 } |
1625 | 1587 |
1626 int32_t AudioDeviceLinuxALSA::CPULoad(uint16_t& load) const | 1588 int32_t AudioDeviceLinuxALSA::CPULoad(uint16_t& load) const |
1627 { | 1589 { |
1628 | 1590 |
1629 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 1591 LOG(LS_WARNING) << "API call not supported on this platform"; |
1630 " API call not supported on this platform"); | |
1631 return -1; | 1592 return -1; |
1632 } | 1593 } |
1633 | 1594 |
1634 bool AudioDeviceLinuxALSA::PlayoutWarning() const | 1595 bool AudioDeviceLinuxALSA::PlayoutWarning() const |
1635 { | 1596 { |
1636 rtc::CritScope lock(&_critSect); | 1597 rtc::CritScope lock(&_critSect); |
1637 return (_playWarning > 0); | 1598 return (_playWarning > 0); |
1638 } | 1599 } |
1639 | 1600 |
1640 bool AudioDeviceLinuxALSA::PlayoutError() const | 1601 bool AudioDeviceLinuxALSA::PlayoutError() const |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1709 // From Chromium issue 95797 | 1670 // From Chromium issue 95797 |
1710 // Loop through the sound cards to get Alsa device hints. | 1671 // Loop through the sound cards to get Alsa device hints. |
1711 // Don't use snd_device_name_hint(-1,..) since there is a access violation | 1672 // Don't use snd_device_name_hint(-1,..) since there is a access violation |
1712 // inside this ALSA API with libasound.so.2.0.0. | 1673 // inside this ALSA API with libasound.so.2.0.0. |
1713 int card = -1; | 1674 int card = -1; |
1714 while (!(LATE(snd_card_next)(&card)) && (card >= 0) && keepSearching) { | 1675 while (!(LATE(snd_card_next)(&card)) && (card >= 0) && keepSearching) { |
1715 void **hints; | 1676 void **hints; |
1716 err = LATE(snd_device_name_hint)(card, "pcm", &hints); | 1677 err = LATE(snd_device_name_hint)(card, "pcm", &hints); |
1717 if (err != 0) | 1678 if (err != 0) |
1718 { | 1679 { |
1719 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 1680 LOG(LS_ERROR) << "GetDevicesInfo - device name hint error: " |
1720 "GetDevicesInfo - device name hint error: %s", | 1681 << LATE(snd_strerror)(err); |
1721 LATE(snd_strerror)(err)); | |
1722 return -1; | 1682 return -1; |
1723 } | 1683 } |
1724 | 1684 |
1725 enumCount++; // default is 0 | 1685 enumCount++; // default is 0 |
1726 if ((function == FUNC_GET_DEVICE_NAME || | 1686 if ((function == FUNC_GET_DEVICE_NAME || |
1727 function == FUNC_GET_DEVICE_NAME_FOR_AN_ENUM) && enumDeviceNo == 0) | 1687 function == FUNC_GET_DEVICE_NAME_FOR_AN_ENUM) && enumDeviceNo == 0) |
1728 { | 1688 { |
1729 strcpy(enumDeviceName, "default"); | 1689 strcpy(enumDeviceName, "default"); |
1730 | 1690 |
1731 err = LATE(snd_device_name_free_hint)(hints); | 1691 err = LATE(snd_device_name_free_hint)(hints); |
1732 if (err != 0) | 1692 if (err != 0) |
1733 { | 1693 { |
1734 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 1694 LOG(LS_ERROR) |
1735 "GetDevicesInfo - device name free hint error: %s", | 1695 << "GetDevicesInfo - device name free hint error: " |
1736 LATE(snd_strerror)(err)); | 1696 << LATE(snd_strerror)(err); |
1737 } | 1697 } |
1738 | 1698 |
1739 return 0; | 1699 return 0; |
1740 } | 1700 } |
1741 | 1701 |
1742 for (void **list = hints; *list != NULL; ++list) | 1702 for (void **list = hints; *list != NULL; ++list) |
1743 { | 1703 { |
1744 char *actualType = LATE(snd_device_name_get_hint)(*list, "IOID"); | 1704 char *actualType = LATE(snd_device_name_get_hint)(*list, "IOID"); |
1745 if (actualType) | 1705 if (actualType) |
1746 { // NULL means it's both. | 1706 { // NULL means it's both. |
1747 bool wrongType = (strcmp(actualType, type) != 0); | 1707 bool wrongType = (strcmp(actualType, type) != 0); |
1748 free(actualType); | 1708 free(actualType); |
1749 if (wrongType) | 1709 if (wrongType) |
1750 { | 1710 { |
1751 // Wrong type of device (i.e., input vs. output). | 1711 // Wrong type of device (i.e., input vs. output). |
1752 continue; | 1712 continue; |
1753 } | 1713 } |
1754 } | 1714 } |
1755 | 1715 |
1756 char *name = LATE(snd_device_name_get_hint)(*list, "NAME"); | 1716 char *name = LATE(snd_device_name_get_hint)(*list, "NAME"); |
1757 if (!name) | 1717 if (!name) |
1758 { | 1718 { |
1759 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 1719 LOG(LS_ERROR) << "Device has no name"; |
1760 "Device has no name"); | |
1761 // Skip it. | 1720 // Skip it. |
1762 continue; | 1721 continue; |
1763 } | 1722 } |
1764 | 1723 |
1765 // Now check if we actually want to show this device. | 1724 // Now check if we actually want to show this device. |
1766 if (strcmp(name, "default") != 0 && | 1725 if (strcmp(name, "default") != 0 && |
1767 strcmp(name, "null") != 0 && | 1726 strcmp(name, "null") != 0 && |
1768 strcmp(name, "pulse") != 0 && | 1727 strcmp(name, "pulse") != 0 && |
1769 strncmp(name, ignorePrefix, strlen(ignorePrefix)) != 0) | 1728 strncmp(name, ignorePrefix, strlen(ignorePrefix)) != 0) |
1770 { | 1729 { |
1771 // Yes, we do. | 1730 // Yes, we do. |
1772 char *desc = LATE(snd_device_name_get_hint)(*list, "DESC"); | 1731 char *desc = LATE(snd_device_name_get_hint)(*list, "DESC"); |
1773 if (!desc) | 1732 if (!desc) |
1774 { | 1733 { |
1775 // Virtual devices don't necessarily have descriptions. | 1734 // Virtual devices don't necessarily have descriptions. |
1776 // Use their names instead. | 1735 // Use their names instead. |
1777 desc = name; | 1736 desc = name; |
1778 } | 1737 } |
1779 | 1738 |
1780 if (FUNC_GET_NUM_OF_DEVICE == function) | 1739 if (FUNC_GET_NUM_OF_DEVICE == function) |
1781 { | 1740 { |
1782 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 1741 LOG(LS_VERBOSE) << "Enum device " << enumCount << " - " |
1783 " Enum device %d - %s", enumCount, name); | 1742 << name; |
1784 | 1743 |
1785 } | 1744 } |
1786 if ((FUNC_GET_DEVICE_NAME == function) && | 1745 if ((FUNC_GET_DEVICE_NAME == function) && |
1787 (enumDeviceNo == enumCount)) | 1746 (enumDeviceNo == enumCount)) |
1788 { | 1747 { |
1789 // We have found the enum device, copy the name to buffer. | 1748 // We have found the enum device, copy the name to buffer. |
1790 strncpy(enumDeviceName, desc, ednLen); | 1749 strncpy(enumDeviceName, desc, ednLen); |
1791 enumDeviceName[ednLen-1] = '\0'; | 1750 enumDeviceName[ednLen-1] = '\0'; |
1792 keepSearching = false; | 1751 keepSearching = false; |
1793 // Replace '\n' with '-'. | 1752 // Replace '\n' with '-'. |
(...skipping 19 matching lines...) Expand all Loading... |
1813 | 1772 |
1814 free(name); | 1773 free(name); |
1815 | 1774 |
1816 if (!keepSearching) | 1775 if (!keepSearching) |
1817 break; | 1776 break; |
1818 } | 1777 } |
1819 | 1778 |
1820 err = LATE(snd_device_name_free_hint)(hints); | 1779 err = LATE(snd_device_name_free_hint)(hints); |
1821 if (err != 0) | 1780 if (err != 0) |
1822 { | 1781 { |
1823 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 1782 LOG(LS_ERROR) << "GetDevicesInfo - device name free hint error: " |
1824 "GetDevicesInfo - device name free hint error: %s", | 1783 << LATE(snd_strerror)(err); |
1825 LATE(snd_strerror)(err)); | |
1826 // Continue and return true anyway, since we did get the whole list. | 1784 // Continue and return true anyway, since we did get the whole list. |
1827 } | 1785 } |
1828 } | 1786 } |
1829 | 1787 |
1830 if (FUNC_GET_NUM_OF_DEVICE == function) | 1788 if (FUNC_GET_NUM_OF_DEVICE == function) |
1831 { | 1789 { |
1832 if (enumCount == 1) // only default? | 1790 if (enumCount == 1) // only default? |
1833 enumCount = 0; | 1791 enumCount = 0; |
1834 return enumCount; // Normal return point for function 0 | 1792 return enumCount; // Normal return point for function 0 |
1835 } | 1793 } |
1836 | 1794 |
1837 if (keepSearching) | 1795 if (keepSearching) |
1838 { | 1796 { |
1839 // If we get here for function 1 and 2, we didn't find the specified | 1797 // If we get here for function 1 and 2, we didn't find the specified |
1840 // enum device. | 1798 // enum device. |
1841 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 1799 LOG(LS_ERROR) |
1842 "GetDevicesInfo - Could not find device name or numbers"); | 1800 << "GetDevicesInfo - Could not find device name or numbers"; |
1843 return -1; | 1801 return -1; |
1844 } | 1802 } |
1845 | 1803 |
1846 return 0; | 1804 return 0; |
1847 } | 1805 } |
1848 | 1806 |
1849 int32_t AudioDeviceLinuxALSA::InputSanityCheckAfterUnlockedPeriod() const | 1807 int32_t AudioDeviceLinuxALSA::InputSanityCheckAfterUnlockedPeriod() const |
1850 { | 1808 { |
1851 if (_handleRecord == NULL) | 1809 if (_handleRecord == NULL) |
1852 { | 1810 { |
1853 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 1811 LOG(LS_ERROR) << "input state has been modified during unlocked period"; |
1854 " input state has been modified during unlocked period"); | |
1855 return -1; | 1812 return -1; |
1856 } | 1813 } |
1857 return 0; | 1814 return 0; |
1858 } | 1815 } |
1859 | 1816 |
1860 int32_t AudioDeviceLinuxALSA::OutputSanityCheckAfterUnlockedPeriod() const | 1817 int32_t AudioDeviceLinuxALSA::OutputSanityCheckAfterUnlockedPeriod() const |
1861 { | 1818 { |
1862 if (_handlePlayout == NULL) | 1819 if (_handlePlayout == NULL) |
1863 { | 1820 { |
1864 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 1821 LOG(LS_ERROR) |
1865 " output state has been modified during unlocked period"); | 1822 << "output state has been modified during unlocked period"; |
1866 return -1; | 1823 return -1; |
1867 } | 1824 } |
1868 return 0; | 1825 return 0; |
1869 } | 1826 } |
1870 | 1827 |
1871 int32_t AudioDeviceLinuxALSA::ErrorRecovery(int32_t error, | 1828 int32_t AudioDeviceLinuxALSA::ErrorRecovery(int32_t error, |
1872 snd_pcm_t* deviceHandle) | 1829 snd_pcm_t* deviceHandle) |
1873 { | 1830 { |
1874 int st = LATE(snd_pcm_state)(deviceHandle); | 1831 int st = LATE(snd_pcm_state)(deviceHandle); |
1875 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 1832 LOG(LS_VERBOSE) << "Trying to recover from " |
1876 "Trying to recover from error: %s (%d) (state %d)", | 1833 << ((LATE(snd_pcm_stream)(deviceHandle) == SND_PCM_STREAM_CAPTURE) |
1877 (LATE(snd_pcm_stream)(deviceHandle) == SND_PCM_STREAM_CAPTURE) ? | 1834 ? "capture" : "playout") << " error: " << LATE(snd_strerror)(error) |
1878 "capture" : "playout", LATE(snd_strerror)(error), error, st); | 1835 << " (" << error << ") (state " << st << ")"; |
1879 | 1836 |
1880 // It is recommended to use snd_pcm_recover for all errors. If that function | 1837 // It is recommended to use snd_pcm_recover for all errors. If that function |
1881 // cannot handle the error, the input error code will be returned, otherwise | 1838 // cannot handle the error, the input error code will be returned, otherwise |
1882 // 0 is returned. From snd_pcm_recover API doc: "This functions handles | 1839 // 0 is returned. From snd_pcm_recover API doc: "This functions handles |
1883 // -EINTR (4) (interrupted system call), -EPIPE (32) (playout overrun or | 1840 // -EINTR (4) (interrupted system call), -EPIPE (32) (playout overrun or |
1884 // capture underrun) and -ESTRPIPE (86) (stream is suspended) error codes | 1841 // capture underrun) and -ESTRPIPE (86) (stream is suspended) error codes |
1885 // trying to prepare given stream for next I/O." | 1842 // trying to prepare given stream for next I/O." |
1886 | 1843 |
1887 /** Open */ | 1844 /** Open */ |
1888 // SND_PCM_STATE_OPEN = 0, | 1845 // SND_PCM_STATE_OPEN = 0, |
(...skipping 14 matching lines...) Expand all Loading... |
1903 // ** Hardware is disconnected */ | 1860 // ** Hardware is disconnected */ |
1904 // SND_PCM_STATE_DISCONNECTED, | 1861 // SND_PCM_STATE_DISCONNECTED, |
1905 // SND_PCM_STATE_LAST = SND_PCM_STATE_DISCONNECTED | 1862 // SND_PCM_STATE_LAST = SND_PCM_STATE_DISCONNECTED |
1906 | 1863 |
1907 // snd_pcm_recover isn't available in older alsa, e.g. on the FC4 machine | 1864 // snd_pcm_recover isn't available in older alsa, e.g. on the FC4 machine |
1908 // in Sthlm lab. | 1865 // in Sthlm lab. |
1909 | 1866 |
1910 int res = LATE(snd_pcm_recover)(deviceHandle, error, 1); | 1867 int res = LATE(snd_pcm_recover)(deviceHandle, error, 1); |
1911 if (0 == res) | 1868 if (0 == res) |
1912 { | 1869 { |
1913 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 1870 LOG(LS_VERBOSE) << "Recovery - snd_pcm_recover OK"; |
1914 " Recovery - snd_pcm_recover OK"); | |
1915 | 1871 |
1916 if ((error == -EPIPE || error == -ESTRPIPE) && // Buf underrun/overrun. | 1872 if ((error == -EPIPE || error == -ESTRPIPE) && // Buf underrun/overrun. |
1917 _recording && | 1873 _recording && |
1918 LATE(snd_pcm_stream)(deviceHandle) == SND_PCM_STREAM_CAPTURE) | 1874 LATE(snd_pcm_stream)(deviceHandle) == SND_PCM_STREAM_CAPTURE) |
1919 { | 1875 { |
1920 // For capture streams we also have to repeat the explicit start() | 1876 // For capture streams we also have to repeat the explicit start() |
1921 // to get data flowing again. | 1877 // to get data flowing again. |
1922 int err = LATE(snd_pcm_start)(deviceHandle); | 1878 int err = LATE(snd_pcm_start)(deviceHandle); |
1923 if (err != 0) | 1879 if (err != 0) |
1924 { | 1880 { |
1925 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 1881 LOG(LS_ERROR) << "Recovery - snd_pcm_start error: " << err; |
1926 " Recovery - snd_pcm_start error: %u", err); | |
1927 return -1; | 1882 return -1; |
1928 } | 1883 } |
1929 } | 1884 } |
1930 | 1885 |
1931 if ((error == -EPIPE || error == -ESTRPIPE) && // Buf underrun/overrun. | 1886 if ((error == -EPIPE || error == -ESTRPIPE) && // Buf underrun/overrun. |
1932 _playing && | 1887 _playing && |
1933 LATE(snd_pcm_stream)(deviceHandle) == SND_PCM_STREAM_PLAYBACK) | 1888 LATE(snd_pcm_stream)(deviceHandle) == SND_PCM_STREAM_PLAYBACK) |
1934 { | 1889 { |
1935 // For capture streams we also have to repeat the explicit start() t
o get | 1890 // For capture streams we also have to repeat the explicit start() t
o get |
1936 // data flowing again. | 1891 // data flowing again. |
1937 int err = LATE(snd_pcm_start)(deviceHandle); | 1892 int err = LATE(snd_pcm_start)(deviceHandle); |
1938 if (err != 0) | 1893 if (err != 0) |
1939 { | 1894 { |
1940 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 1895 LOG(LS_ERROR) << "Recovery - snd_pcm_start error: " |
1941 " Recovery - snd_pcm_start error: %s", | 1896 << LATE(snd_strerror)(err); |
1942 LATE(snd_strerror)(err)); | |
1943 return -1; | 1897 return -1; |
1944 } | 1898 } |
1945 } | 1899 } |
1946 | 1900 |
1947 return -EPIPE == error ? 1 : 0; | 1901 return -EPIPE == error ? 1 : 0; |
1948 } | 1902 } |
1949 else { | 1903 else { |
1950 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 1904 LOG(LS_ERROR) << "Unrecoverable alsa stream error: " << res; |
1951 " Unrecoverable alsa stream error: %d", res); | |
1952 } | 1905 } |
1953 | 1906 |
1954 return res; | 1907 return res; |
1955 } | 1908 } |
1956 | 1909 |
1957 // ============================================================================ | 1910 // ============================================================================ |
1958 // Thread Methods | 1911 // Thread Methods |
1959 // ============================================================================ | 1912 // ============================================================================ |
1960 | 1913 |
1961 bool AudioDeviceLinuxALSA::PlayThreadFunc(void* pThis) | 1914 bool AudioDeviceLinuxALSA::PlayThreadFunc(void* pThis) |
(...skipping 13 matching lines...) Expand all Loading... |
1975 | 1928 |
1976 int err; | 1929 int err; |
1977 snd_pcm_sframes_t frames; | 1930 snd_pcm_sframes_t frames; |
1978 snd_pcm_sframes_t avail_frames; | 1931 snd_pcm_sframes_t avail_frames; |
1979 | 1932 |
1980 Lock(); | 1933 Lock(); |
1981 //return a positive number of frames ready otherwise a negative error code | 1934 //return a positive number of frames ready otherwise a negative error code |
1982 avail_frames = LATE(snd_pcm_avail_update)(_handlePlayout); | 1935 avail_frames = LATE(snd_pcm_avail_update)(_handlePlayout); |
1983 if (avail_frames < 0) | 1936 if (avail_frames < 0) |
1984 { | 1937 { |
1985 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 1938 LOG(LS_ERROR) << "playout snd_pcm_avail_update error: " |
1986 "playout snd_pcm_avail_update error: %s", | 1939 << LATE(snd_strerror)(avail_frames); |
1987 LATE(snd_strerror)(avail_frames)); | |
1988 ErrorRecovery(avail_frames, _handlePlayout); | 1940 ErrorRecovery(avail_frames, _handlePlayout); |
1989 UnLock(); | 1941 UnLock(); |
1990 return true; | 1942 return true; |
1991 } | 1943 } |
1992 else if (avail_frames == 0) | 1944 else if (avail_frames == 0) |
1993 { | 1945 { |
1994 UnLock(); | 1946 UnLock(); |
1995 | 1947 |
1996 //maximum tixe in milliseconds to wait, a negative value means infinity | 1948 //maximum tixe in milliseconds to wait, a negative value means infinity |
1997 err = LATE(snd_pcm_wait)(_handlePlayout, 2); | 1949 err = LATE(snd_pcm_wait)(_handlePlayout, 2); |
1998 if (err == 0) | 1950 if (err == 0) |
1999 { //timeout occured | 1951 { //timeout occured |
2000 WEBRTC_TRACE(kTraceStream, kTraceAudioDevice, _id, | 1952 LOG(LS_VERBOSE) << "playout snd_pcm_wait timeout"; |
2001 "playout snd_pcm_wait timeout"); | |
2002 } | 1953 } |
2003 | 1954 |
2004 return true; | 1955 return true; |
2005 } | 1956 } |
2006 | 1957 |
2007 if (_playoutFramesLeft <= 0) | 1958 if (_playoutFramesLeft <= 0) |
2008 { | 1959 { |
2009 UnLock(); | 1960 UnLock(); |
2010 _ptrAudioBuffer->RequestPlayoutData(_playoutFramesIn10MS); | 1961 _ptrAudioBuffer->RequestPlayoutData(_playoutFramesIn10MS); |
2011 Lock(); | 1962 Lock(); |
2012 | 1963 |
2013 _playoutFramesLeft = _ptrAudioBuffer->GetPlayoutData(_playoutBuffer); | 1964 _playoutFramesLeft = _ptrAudioBuffer->GetPlayoutData(_playoutBuffer); |
2014 assert(_playoutFramesLeft == _playoutFramesIn10MS); | 1965 assert(_playoutFramesLeft == _playoutFramesIn10MS); |
2015 } | 1966 } |
2016 | 1967 |
2017 if (static_cast<uint32_t>(avail_frames) > _playoutFramesLeft) | 1968 if (static_cast<uint32_t>(avail_frames) > _playoutFramesLeft) |
2018 avail_frames = _playoutFramesLeft; | 1969 avail_frames = _playoutFramesLeft; |
2019 | 1970 |
2020 int size = LATE(snd_pcm_frames_to_bytes)(_handlePlayout, | 1971 int size = LATE(snd_pcm_frames_to_bytes)(_handlePlayout, |
2021 _playoutFramesLeft); | 1972 _playoutFramesLeft); |
2022 frames = LATE(snd_pcm_writei)( | 1973 frames = LATE(snd_pcm_writei)( |
2023 _handlePlayout, | 1974 _handlePlayout, |
2024 &_playoutBuffer[_playoutBufferSizeIn10MS - size], | 1975 &_playoutBuffer[_playoutBufferSizeIn10MS - size], |
2025 avail_frames); | 1976 avail_frames); |
2026 | 1977 |
2027 if (frames < 0) | 1978 if (frames < 0) |
2028 { | 1979 { |
2029 WEBRTC_TRACE(kTraceStream, kTraceAudioDevice, _id, | 1980 LOG(LS_VERBOSE) << "playout snd_pcm_writei error: " |
2030 "playout snd_pcm_writei error: %s", | 1981 << LATE(snd_strerror)(frames); |
2031 LATE(snd_strerror)(frames)); | |
2032 _playoutFramesLeft = 0; | 1982 _playoutFramesLeft = 0; |
2033 ErrorRecovery(frames, _handlePlayout); | 1983 ErrorRecovery(frames, _handlePlayout); |
2034 UnLock(); | 1984 UnLock(); |
2035 return true; | 1985 return true; |
2036 } | 1986 } |
2037 else { | 1987 else { |
2038 assert(frames==avail_frames); | 1988 assert(frames==avail_frames); |
2039 _playoutFramesLeft -= frames; | 1989 _playoutFramesLeft -= frames; |
2040 } | 1990 } |
2041 | 1991 |
(...skipping 10 matching lines...) Expand all Loading... |
2052 snd_pcm_sframes_t frames; | 2002 snd_pcm_sframes_t frames; |
2053 snd_pcm_sframes_t avail_frames; | 2003 snd_pcm_sframes_t avail_frames; |
2054 int8_t buffer[_recordingBufferSizeIn10MS]; | 2004 int8_t buffer[_recordingBufferSizeIn10MS]; |
2055 | 2005 |
2056 Lock(); | 2006 Lock(); |
2057 | 2007 |
2058 //return a positive number of frames ready otherwise a negative error code | 2008 //return a positive number of frames ready otherwise a negative error code |
2059 avail_frames = LATE(snd_pcm_avail_update)(_handleRecord); | 2009 avail_frames = LATE(snd_pcm_avail_update)(_handleRecord); |
2060 if (avail_frames < 0) | 2010 if (avail_frames < 0) |
2061 { | 2011 { |
2062 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 2012 LOG(LS_ERROR) << "capture snd_pcm_avail_update error: " |
2063 "capture snd_pcm_avail_update error: %s", | 2013 << LATE(snd_strerror)(avail_frames); |
2064 LATE(snd_strerror)(avail_frames)); | |
2065 ErrorRecovery(avail_frames, _handleRecord); | 2014 ErrorRecovery(avail_frames, _handleRecord); |
2066 UnLock(); | 2015 UnLock(); |
2067 return true; | 2016 return true; |
2068 } | 2017 } |
2069 else if (avail_frames == 0) | 2018 else if (avail_frames == 0) |
2070 { // no frame is available now | 2019 { // no frame is available now |
2071 UnLock(); | 2020 UnLock(); |
2072 | 2021 |
2073 //maximum time in milliseconds to wait, a negative value means infinity | 2022 //maximum time in milliseconds to wait, a negative value means infinity |
2074 err = LATE(snd_pcm_wait)(_handleRecord, | 2023 err = LATE(snd_pcm_wait)(_handleRecord, |
2075 ALSA_CAPTURE_WAIT_TIMEOUT); | 2024 ALSA_CAPTURE_WAIT_TIMEOUT); |
2076 if (err == 0) //timeout occured | 2025 if (err == 0) //timeout occured |
2077 WEBRTC_TRACE(kTraceStream, kTraceAudioDevice, _id, | 2026 LOG(LS_VERBOSE) << "capture snd_pcm_wait timeout"; |
2078 "capture snd_pcm_wait timeout"); | |
2079 | 2027 |
2080 return true; | 2028 return true; |
2081 } | 2029 } |
2082 | 2030 |
2083 if (static_cast<uint32_t>(avail_frames) > _recordingFramesLeft) | 2031 if (static_cast<uint32_t>(avail_frames) > _recordingFramesLeft) |
2084 avail_frames = _recordingFramesLeft; | 2032 avail_frames = _recordingFramesLeft; |
2085 | 2033 |
2086 frames = LATE(snd_pcm_readi)(_handleRecord, | 2034 frames = LATE(snd_pcm_readi)(_handleRecord, |
2087 buffer, avail_frames); // frames to be written | 2035 buffer, avail_frames); // frames to be written |
2088 if (frames < 0) | 2036 if (frames < 0) |
2089 { | 2037 { |
2090 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 2038 LOG(LS_ERROR) << "capture snd_pcm_readi error: " |
2091 "capture snd_pcm_readi error: %s", | 2039 << LATE(snd_strerror)(frames); |
2092 LATE(snd_strerror)(frames)); | |
2093 ErrorRecovery(frames, _handleRecord); | 2040 ErrorRecovery(frames, _handleRecord); |
2094 UnLock(); | 2041 UnLock(); |
2095 return true; | 2042 return true; |
2096 } | 2043 } |
2097 else if (frames > 0) | 2044 else if (frames > 0) |
2098 { | 2045 { |
2099 assert(frames == avail_frames); | 2046 assert(frames == avail_frames); |
2100 | 2047 |
2101 int left_size = LATE(snd_pcm_frames_to_bytes)(_handleRecord, | 2048 int left_size = LATE(snd_pcm_frames_to_bytes)(_handleRecord, |
2102 _recordingFramesLeft); | 2049 _recordingFramesLeft); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2134 _playoutDelay = 0; | 2081 _playoutDelay = 0; |
2135 _recordingDelay = 0; | 2082 _recordingDelay = 0; |
2136 if (_handlePlayout) | 2083 if (_handlePlayout) |
2137 { | 2084 { |
2138 err = LATE(snd_pcm_delay)(_handlePlayout, | 2085 err = LATE(snd_pcm_delay)(_handlePlayout, |
2139 &_playoutDelay); // returned delay in frames | 2086 &_playoutDelay); // returned delay in frames |
2140 if (err < 0) | 2087 if (err < 0) |
2141 { | 2088 { |
2142 // TODO(xians): Shall we call ErrorRecovery() here? | 2089 // TODO(xians): Shall we call ErrorRecovery() here? |
2143 _playoutDelay = 0; | 2090 _playoutDelay = 0; |
2144 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 2091 LOG(LS_ERROR) << "playout snd_pcm_delay: " |
2145 "playout snd_pcm_delay: %s", | 2092 << LATE(snd_strerror)(err); |
2146 LATE(snd_strerror)(err)); | |
2147 } | 2093 } |
2148 } | 2094 } |
2149 | 2095 |
2150 err = LATE(snd_pcm_delay)(_handleRecord, | 2096 err = LATE(snd_pcm_delay)(_handleRecord, |
2151 &_recordingDelay); // returned delay in frames | 2097 &_recordingDelay); // returned delay in frames |
2152 if (err < 0) | 2098 if (err < 0) |
2153 { | 2099 { |
2154 // TODO(xians): Shall we call ErrorRecovery() here? | 2100 // TODO(xians): Shall we call ErrorRecovery() here? |
2155 _recordingDelay = 0; | 2101 _recordingDelay = 0; |
2156 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 2102 LOG(LS_ERROR) << "capture snd_pcm_delay: " |
2157 "capture snd_pcm_delay: %s", | 2103 << LATE(snd_strerror)(err); |
2158 LATE(snd_strerror)(err)); | |
2159 } | 2104 } |
2160 | 2105 |
2161 // TODO(xians): Shall we add 10ms buffer delay to the record delay? | 2106 // TODO(xians): Shall we add 10ms buffer delay to the record delay? |
2162 _ptrAudioBuffer->SetVQEData( | 2107 _ptrAudioBuffer->SetVQEData( |
2163 _playoutDelay * 1000 / _playoutFreq, | 2108 _playoutDelay * 1000 / _playoutFreq, |
2164 _recordingDelay * 1000 / _recordingFreq, 0); | 2109 _recordingDelay * 1000 / _recordingFreq, 0); |
2165 | 2110 |
2166 _ptrAudioBuffer->SetTypingStatus(KeyPressed()); | 2111 _ptrAudioBuffer->SetTypingStatus(KeyPressed()); |
2167 | 2112 |
2168 // Deliver recorded samples at specified sample rate, mic level etc. | 2113 // Deliver recorded samples at specified sample rate, mic level etc. |
2169 // to the observer using callback. | 2114 // to the observer using callback. |
2170 UnLock(); | 2115 UnLock(); |
2171 _ptrAudioBuffer->DeliverRecordedData(); | 2116 _ptrAudioBuffer->DeliverRecordedData(); |
2172 Lock(); | 2117 Lock(); |
2173 | 2118 |
2174 if (AGC()) | 2119 if (AGC()) |
2175 { | 2120 { |
2176 newMicLevel = _ptrAudioBuffer->NewMicLevel(); | 2121 newMicLevel = _ptrAudioBuffer->NewMicLevel(); |
2177 if (newMicLevel != 0) | 2122 if (newMicLevel != 0) |
2178 { | 2123 { |
2179 // The VQE will only deliver non-zero microphone levels when
a | 2124 // The VQE will only deliver non-zero microphone levels when
a |
2180 // change is needed. Set this new mic level (received from t
he | 2125 // change is needed. Set this new mic level (received from t
he |
2181 // observer as return value in the callback). | 2126 // observer as return value in the callback). |
2182 if (SetMicrophoneVolume(newMicLevel) == -1) | 2127 if (SetMicrophoneVolume(newMicLevel) == -1) |
2183 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 2128 LOG(LS_WARNING) |
2184 " the required modification of the " | 2129 << "the required modification of the microphone volu
me failed"; |
2185 "microphone volume failed"); | |
2186 } | 2130 } |
2187 } | 2131 } |
2188 } | 2132 } |
2189 } | 2133 } |
2190 | 2134 |
2191 UnLock(); | 2135 UnLock(); |
2192 return true; | 2136 return true; |
2193 } | 2137 } |
2194 | 2138 |
2195 | 2139 |
(...skipping 14 matching lines...) Expand all Loading... |
2210 state |= (szKey[i] ^ _oldKeyState[i]) & szKey[i]; | 2154 state |= (szKey[i] ^ _oldKeyState[i]) & szKey[i]; |
2211 | 2155 |
2212 // Save old state | 2156 // Save old state |
2213 memcpy((char*)_oldKeyState, (char*)szKey, sizeof(_oldKeyState)); | 2157 memcpy((char*)_oldKeyState, (char*)szKey, sizeof(_oldKeyState)); |
2214 return (state != 0); | 2158 return (state != 0); |
2215 #else | 2159 #else |
2216 return false; | 2160 return false; |
2217 #endif | 2161 #endif |
2218 } | 2162 } |
2219 } // namespace webrtc | 2163 } // namespace webrtc |
OLD | NEW |