OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2015 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 <algorithm> | 11 #include <algorithm> |
12 #include <limits> | 12 #include <limits> |
13 #include <list> | 13 #include <list> |
| 14 #include <memory> |
14 #include <numeric> | 15 #include <numeric> |
15 #include <string> | 16 #include <string> |
16 #include <vector> | 17 #include <vector> |
17 | 18 |
18 #include "testing/gmock/include/gmock/gmock.h" | 19 #include "testing/gmock/include/gmock/gmock.h" |
19 #include "testing/gtest/include/gtest/gtest.h" | 20 #include "testing/gtest/include/gtest/gtest.h" |
20 #include "webrtc/base/arraysize.h" | 21 #include "webrtc/base/arraysize.h" |
21 #include "webrtc/base/criticalsection.h" | 22 #include "webrtc/base/criticalsection.h" |
22 #include "webrtc/base/format_macros.h" | 23 #include "webrtc/base/format_macros.h" |
23 #include "webrtc/base/scoped_ptr.h" | |
24 #include "webrtc/base/scoped_ref_ptr.h" | 24 #include "webrtc/base/scoped_ref_ptr.h" |
25 #include "webrtc/modules/audio_device/android/audio_common.h" | 25 #include "webrtc/modules/audio_device/android/audio_common.h" |
26 #include "webrtc/modules/audio_device/android/audio_manager.h" | 26 #include "webrtc/modules/audio_device/android/audio_manager.h" |
27 #include "webrtc/modules/audio_device/android/build_info.h" | 27 #include "webrtc/modules/audio_device/android/build_info.h" |
28 #include "webrtc/modules/audio_device/android/ensure_initialized.h" | 28 #include "webrtc/modules/audio_device/android/ensure_initialized.h" |
29 #include "webrtc/modules/audio_device/audio_device_impl.h" | 29 #include "webrtc/modules/audio_device/audio_device_impl.h" |
30 #include "webrtc/modules/audio_device/include/audio_device.h" | 30 #include "webrtc/modules/audio_device/include/audio_device.h" |
31 #include "webrtc/system_wrappers/include/clock.h" | 31 #include "webrtc/system_wrappers/include/clock.h" |
32 #include "webrtc/system_wrappers/include/event_wrapper.h" | 32 #include "webrtc/system_wrappers/include/event_wrapper.h" |
33 #include "webrtc/system_wrappers/include/sleep.h" | 33 #include "webrtc/system_wrappers/include/sleep.h" |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
137 return static_cast<int>( | 137 return static_cast<int>( |
138 file_size_in_bytes_ / (kBytesPerSample * sample_rate_)); | 138 file_size_in_bytes_ / (kBytesPerSample * sample_rate_)); |
139 } | 139 } |
140 size_t file_size_in_callbacks() const { | 140 size_t file_size_in_callbacks() const { |
141 return file_size_in_seconds() * kNumCallbacksPerSecond; | 141 return file_size_in_seconds() * kNumCallbacksPerSecond; |
142 } | 142 } |
143 | 143 |
144 private: | 144 private: |
145 size_t file_size_in_bytes_; | 145 size_t file_size_in_bytes_; |
146 int sample_rate_; | 146 int sample_rate_; |
147 rtc::scoped_ptr<int16_t[]> file_; | 147 std::unique_ptr<int16_t[]> file_; |
148 size_t file_pos_; | 148 size_t file_pos_; |
149 }; | 149 }; |
150 | 150 |
151 // Simple first in first out (FIFO) class that wraps a list of 16-bit audio | 151 // Simple first in first out (FIFO) class that wraps a list of 16-bit audio |
152 // buffers of fixed size and allows Write and Read operations. The idea is to | 152 // buffers of fixed size and allows Write and Read operations. The idea is to |
153 // store recorded audio buffers (using Write) and then read (using Read) these | 153 // store recorded audio buffers (using Write) and then read (using Read) these |
154 // stored buffers with as short delay as possible when the audio layer needs | 154 // stored buffers with as short delay as possible when the audio layer needs |
155 // data to play out. The number of buffers in the FIFO will stabilize under | 155 // data to play out. The number of buffers in the FIFO will stabilize under |
156 // normal conditions since there will be a balance between Write and Read calls. | 156 // normal conditions since there will be a balance between Write and Read calls. |
157 // The container is a std::list container and access is protected with a lock | 157 // The container is a std::list container and access is protected with a lock |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
232 for (auto it = fifo_->begin(); it != fifo_->end(); ++it) { | 232 for (auto it = fifo_->begin(); it != fifo_->end(); ++it) { |
233 delete *it; | 233 delete *it; |
234 } | 234 } |
235 fifo_->clear(); | 235 fifo_->clear(); |
236 } | 236 } |
237 | 237 |
238 using AudioBufferList = std::list<int16_t*>; | 238 using AudioBufferList = std::list<int16_t*>; |
239 rtc::CriticalSection lock_; | 239 rtc::CriticalSection lock_; |
240 const size_t frames_per_buffer_; | 240 const size_t frames_per_buffer_; |
241 const size_t bytes_per_buffer_; | 241 const size_t bytes_per_buffer_; |
242 rtc::scoped_ptr<AudioBufferList> fifo_; | 242 std::unique_ptr<AudioBufferList> fifo_; |
243 size_t largest_size_; | 243 size_t largest_size_; |
244 size_t total_written_elements_; | 244 size_t total_written_elements_; |
245 size_t write_count_; | 245 size_t write_count_; |
246 }; | 246 }; |
247 | 247 |
248 // Inserts periodic impulses and measures the latency between the time of | 248 // Inserts periodic impulses and measures the latency between the time of |
249 // transmission and time of receiving the same impulse. | 249 // transmission and time of receiving the same impulse. |
250 // Usage requires a special hardware called Audio Loopback Dongle. | 250 // Usage requires a special hardware called Audio Loopback Dongle. |
251 // See http://source.android.com/devices/audio/loopback.html for details. | 251 // See http://source.android.com/devices/audio/loopback.html for details. |
252 class LatencyMeasuringAudioStream : public AudioStreamInterface { | 252 class LatencyMeasuringAudioStream : public AudioStreamInterface { |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
484 bool play_mode() const { return type_ & kPlayout; } | 484 bool play_mode() const { return type_ & kPlayout; } |
485 bool rec_mode() const { return type_ & kRecording; } | 485 bool rec_mode() const { return type_ & kRecording; } |
486 | 486 |
487 private: | 487 private: |
488 EventWrapper* test_is_done_; | 488 EventWrapper* test_is_done_; |
489 size_t num_callbacks_; | 489 size_t num_callbacks_; |
490 int type_; | 490 int type_; |
491 size_t play_count_; | 491 size_t play_count_; |
492 size_t rec_count_; | 492 size_t rec_count_; |
493 AudioStreamInterface* audio_stream_; | 493 AudioStreamInterface* audio_stream_; |
494 rtc::scoped_ptr<LatencyMeasuringAudioStream> latency_audio_stream_; | 494 std::unique_ptr<LatencyMeasuringAudioStream> latency_audio_stream_; |
495 }; | 495 }; |
496 | 496 |
497 // AudioDeviceTest test fixture. | 497 // AudioDeviceTest test fixture. |
498 class AudioDeviceTest : public ::testing::Test { | 498 class AudioDeviceTest : public ::testing::Test { |
499 protected: | 499 protected: |
500 AudioDeviceTest() | 500 AudioDeviceTest() |
501 : test_is_done_(EventWrapper::Create()) { | 501 : test_is_done_(EventWrapper::Create()) { |
502 // One-time initialization of JVM and application context. Ensures that we | 502 // One-time initialization of JVM and application context. Ensures that we |
503 // can do calls between C++ and Java. Initializes both Java and OpenSL ES | 503 // can do calls between C++ and Java. Initializes both Java and OpenSL ES |
504 // implementations. | 504 // implementations. |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
681 EXPECT_EQ(0, audio_device()->MinSpeakerVolume(&min_volume)); | 681 EXPECT_EQ(0, audio_device()->MinSpeakerVolume(&min_volume)); |
682 return min_volume; | 682 return min_volume; |
683 } | 683 } |
684 | 684 |
685 int GetSpeakerVolume() const { | 685 int GetSpeakerVolume() const { |
686 uint32_t volume(0); | 686 uint32_t volume(0); |
687 EXPECT_EQ(0, audio_device()->SpeakerVolume(&volume)); | 687 EXPECT_EQ(0, audio_device()->SpeakerVolume(&volume)); |
688 return volume; | 688 return volume; |
689 } | 689 } |
690 | 690 |
691 rtc::scoped_ptr<EventWrapper> test_is_done_; | 691 std::unique_ptr<EventWrapper> test_is_done_; |
692 rtc::scoped_refptr<AudioDeviceModule> audio_device_; | 692 rtc::scoped_refptr<AudioDeviceModule> audio_device_; |
693 AudioParameters playout_parameters_; | 693 AudioParameters playout_parameters_; |
694 AudioParameters record_parameters_; | 694 AudioParameters record_parameters_; |
695 rtc::scoped_ptr<BuildInfo> build_info_; | 695 std::unique_ptr<BuildInfo> build_info_; |
696 }; | 696 }; |
697 | 697 |
698 TEST_F(AudioDeviceTest, ConstructDestruct) { | 698 TEST_F(AudioDeviceTest, ConstructDestruct) { |
699 // Using the test fixture to create and destruct the audio device module. | 699 // Using the test fixture to create and destruct the audio device module. |
700 } | 700 } |
701 | 701 |
702 // We always ask for a default audio layer when the ADM is constructed. But the | 702 // We always ask for a default audio layer when the ADM is constructed. But the |
703 // ADM will then internally set the best suitable combination of audio layers, | 703 // ADM will then internally set the best suitable combination of audio layers, |
704 // for input and output based on if low-latency output audio in combination | 704 // for input and output based on if low-latency output audio in combination |
705 // with OpenSL ES is supported or not. This test ensures that the correct | 705 // with OpenSL ES is supported or not. This test ensures that the correct |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
928 | 928 |
929 // Start playout and read audio from an external PCM file when the audio layer | 929 // Start playout and read audio from an external PCM file when the audio layer |
930 // asks for data to play out. Real audio is played out in this test but it does | 930 // asks for data to play out. Real audio is played out in this test but it does |
931 // not contain any explicit verification that the audio quality is perfect. | 931 // not contain any explicit verification that the audio quality is perfect. |
932 TEST_F(AudioDeviceTest, RunPlayoutWithFileAsSource) { | 932 TEST_F(AudioDeviceTest, RunPlayoutWithFileAsSource) { |
933 // TODO(henrika): extend test when mono output is supported. | 933 // TODO(henrika): extend test when mono output is supported. |
934 EXPECT_EQ(1u, playout_channels()); | 934 EXPECT_EQ(1u, playout_channels()); |
935 NiceMock<MockAudioTransport> mock(kPlayout); | 935 NiceMock<MockAudioTransport> mock(kPlayout); |
936 const int num_callbacks = kFilePlayTimeInSec * kNumCallbacksPerSecond; | 936 const int num_callbacks = kFilePlayTimeInSec * kNumCallbacksPerSecond; |
937 std::string file_name = GetFileName(playout_sample_rate()); | 937 std::string file_name = GetFileName(playout_sample_rate()); |
938 rtc::scoped_ptr<FileAudioStream> file_audio_stream( | 938 std::unique_ptr<FileAudioStream> file_audio_stream( |
939 new FileAudioStream(num_callbacks, file_name, playout_sample_rate())); | 939 new FileAudioStream(num_callbacks, file_name, playout_sample_rate())); |
940 mock.HandleCallbacks(test_is_done_.get(), | 940 mock.HandleCallbacks(test_is_done_.get(), |
941 file_audio_stream.get(), | 941 file_audio_stream.get(), |
942 num_callbacks); | 942 num_callbacks); |
943 // SetMaxPlayoutVolume(); | 943 // SetMaxPlayoutVolume(); |
944 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock)); | 944 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock)); |
945 StartPlayout(); | 945 StartPlayout(); |
946 test_is_done_->Wait(kTestTimeOutInMilliseconds); | 946 test_is_done_->Wait(kTestTimeOutInMilliseconds); |
947 StopPlayout(); | 947 StopPlayout(); |
948 } | 948 } |
949 | 949 |
950 // Start playout and recording and store recorded data in an intermediate FIFO | 950 // Start playout and recording and store recorded data in an intermediate FIFO |
951 // buffer from which the playout side then reads its samples in the same order | 951 // buffer from which the playout side then reads its samples in the same order |
952 // as they were stored. Under ideal circumstances, a callback sequence would | 952 // as they were stored. Under ideal circumstances, a callback sequence would |
953 // look like: ...+-+-+-+-+-+-+-..., where '+' means 'packet recorded' and '-' | 953 // look like: ...+-+-+-+-+-+-+-..., where '+' means 'packet recorded' and '-' |
954 // means 'packet played'. Under such conditions, the FIFO would only contain | 954 // means 'packet played'. Under such conditions, the FIFO would only contain |
955 // one packet on average. However, under more realistic conditions, the size | 955 // one packet on average. However, under more realistic conditions, the size |
956 // of the FIFO will vary more due to an unbalance between the two sides. | 956 // of the FIFO will vary more due to an unbalance between the two sides. |
957 // This test tries to verify that the device maintains a balanced callback- | 957 // This test tries to verify that the device maintains a balanced callback- |
958 // sequence by running in loopback for ten seconds while measuring the size | 958 // sequence by running in loopback for ten seconds while measuring the size |
959 // (max and average) of the FIFO. The size of the FIFO is increased by the | 959 // (max and average) of the FIFO. The size of the FIFO is increased by the |
960 // recording side and decreased by the playout side. | 960 // recording side and decreased by the playout side. |
961 // TODO(henrika): tune the final test parameters after running tests on several | 961 // TODO(henrika): tune the final test parameters after running tests on several |
962 // different devices. | 962 // different devices. |
963 TEST_F(AudioDeviceTest, RunPlayoutAndRecordingInFullDuplex) { | 963 TEST_F(AudioDeviceTest, RunPlayoutAndRecordingInFullDuplex) { |
964 EXPECT_EQ(record_channels(), playout_channels()); | 964 EXPECT_EQ(record_channels(), playout_channels()); |
965 EXPECT_EQ(record_sample_rate(), playout_sample_rate()); | 965 EXPECT_EQ(record_sample_rate(), playout_sample_rate()); |
966 NiceMock<MockAudioTransport> mock(kPlayout | kRecording); | 966 NiceMock<MockAudioTransport> mock(kPlayout | kRecording); |
967 rtc::scoped_ptr<FifoAudioStream> fifo_audio_stream( | 967 std::unique_ptr<FifoAudioStream> fifo_audio_stream( |
968 new FifoAudioStream(playout_frames_per_10ms_buffer())); | 968 new FifoAudioStream(playout_frames_per_10ms_buffer())); |
969 mock.HandleCallbacks(test_is_done_.get(), | 969 mock.HandleCallbacks(test_is_done_.get(), |
970 fifo_audio_stream.get(), | 970 fifo_audio_stream.get(), |
971 kFullDuplexTimeInSec * kNumCallbacksPerSecond); | 971 kFullDuplexTimeInSec * kNumCallbacksPerSecond); |
972 SetMaxPlayoutVolume(); | 972 SetMaxPlayoutVolume(); |
973 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock)); | 973 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock)); |
974 StartRecording(); | 974 StartRecording(); |
975 StartPlayout(); | 975 StartPlayout(); |
976 test_is_done_->Wait(std::max(kTestTimeOutInMilliseconds, | 976 test_is_done_->Wait(std::max(kTestTimeOutInMilliseconds, |
977 1000 * kFullDuplexTimeInSec)); | 977 1000 * kFullDuplexTimeInSec)); |
978 StopPlayout(); | 978 StopPlayout(); |
979 StopRecording(); | 979 StopRecording(); |
980 EXPECT_LE(fifo_audio_stream->average_size(), 10u); | 980 EXPECT_LE(fifo_audio_stream->average_size(), 10u); |
981 EXPECT_LE(fifo_audio_stream->largest_size(), 20u); | 981 EXPECT_LE(fifo_audio_stream->largest_size(), 20u); |
982 } | 982 } |
983 | 983 |
984 // Measures loopback latency and reports the min, max and average values for | 984 // Measures loopback latency and reports the min, max and average values for |
985 // a full duplex audio session. | 985 // a full duplex audio session. |
986 // The latency is measured like so: | 986 // The latency is measured like so: |
987 // - Insert impulses periodically on the output side. | 987 // - Insert impulses periodically on the output side. |
988 // - Detect the impulses on the input side. | 988 // - Detect the impulses on the input side. |
989 // - Measure the time difference between the transmit time and receive time. | 989 // - Measure the time difference between the transmit time and receive time. |
990 // - Store time differences in a vector and calculate min, max and average. | 990 // - Store time differences in a vector and calculate min, max and average. |
991 // This test requires a special hardware called Audio Loopback Dongle. | 991 // This test requires a special hardware called Audio Loopback Dongle. |
992 // See http://source.android.com/devices/audio/loopback.html for details. | 992 // See http://source.android.com/devices/audio/loopback.html for details. |
993 TEST_F(AudioDeviceTest, DISABLED_MeasureLoopbackLatency) { | 993 TEST_F(AudioDeviceTest, DISABLED_MeasureLoopbackLatency) { |
994 EXPECT_EQ(record_channels(), playout_channels()); | 994 EXPECT_EQ(record_channels(), playout_channels()); |
995 EXPECT_EQ(record_sample_rate(), playout_sample_rate()); | 995 EXPECT_EQ(record_sample_rate(), playout_sample_rate()); |
996 NiceMock<MockAudioTransport> mock(kPlayout | kRecording); | 996 NiceMock<MockAudioTransport> mock(kPlayout | kRecording); |
997 rtc::scoped_ptr<LatencyMeasuringAudioStream> latency_audio_stream( | 997 std::unique_ptr<LatencyMeasuringAudioStream> latency_audio_stream( |
998 new LatencyMeasuringAudioStream(playout_frames_per_10ms_buffer())); | 998 new LatencyMeasuringAudioStream(playout_frames_per_10ms_buffer())); |
999 mock.HandleCallbacks(test_is_done_.get(), | 999 mock.HandleCallbacks(test_is_done_.get(), |
1000 latency_audio_stream.get(), | 1000 latency_audio_stream.get(), |
1001 kMeasureLatencyTimeInSec * kNumCallbacksPerSecond); | 1001 kMeasureLatencyTimeInSec * kNumCallbacksPerSecond); |
1002 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock)); | 1002 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock)); |
1003 SetMaxPlayoutVolume(); | 1003 SetMaxPlayoutVolume(); |
1004 DisableBuiltInAECIfAvailable(); | 1004 DisableBuiltInAECIfAvailable(); |
1005 StartRecording(); | 1005 StartRecording(); |
1006 StartPlayout(); | 1006 StartPlayout(); |
1007 test_is_done_->Wait(std::max(kTestTimeOutInMilliseconds, | 1007 test_is_done_->Wait(std::max(kTestTimeOutInMilliseconds, |
1008 1000 * kMeasureLatencyTimeInSec)); | 1008 1000 * kMeasureLatencyTimeInSec)); |
1009 StopPlayout(); | 1009 StopPlayout(); |
1010 StopRecording(); | 1010 StopRecording(); |
1011 // Verify that the correct number of transmitted impulses are detected. | 1011 // Verify that the correct number of transmitted impulses are detected. |
1012 EXPECT_EQ(latency_audio_stream->num_latency_values(), | 1012 EXPECT_EQ(latency_audio_stream->num_latency_values(), |
1013 static_cast<size_t>( | 1013 static_cast<size_t>( |
1014 kImpulseFrequencyInHz * kMeasureLatencyTimeInSec - 1)); | 1014 kImpulseFrequencyInHz * kMeasureLatencyTimeInSec - 1)); |
1015 latency_audio_stream->PrintResults(); | 1015 latency_audio_stream->PrintResults(); |
1016 } | 1016 } |
1017 | 1017 |
1018 } // namespace webrtc | 1018 } // namespace webrtc |
OLD | NEW |