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 <math.h> | 11 #include <math.h> |
12 #include <stdio.h> | 12 #include <stdio.h> |
13 #include <string.h> | 13 #include <string.h> |
14 #ifdef WEBRTC_ANDROID | 14 #ifdef WEBRTC_ANDROID |
15 #include <sys/stat.h> | 15 #include <sys/stat.h> |
16 #endif | 16 #endif |
17 | 17 |
18 #include <algorithm> | 18 #include <algorithm> |
19 #include <memory> | 19 #include <memory> |
20 | 20 |
21 #include "webrtc/base/format_macros.h" | 21 #include "webrtc/base/format_macros.h" |
| 22 #include "webrtc/base/timeutils.h" |
22 #include "webrtc/common.h" | 23 #include "webrtc/common.h" |
23 #include "webrtc/modules/audio_processing/include/audio_processing.h" | 24 #include "webrtc/modules/audio_processing/include/audio_processing.h" |
24 #include "webrtc/modules/audio_processing/test/protobuf_utils.h" | 25 #include "webrtc/modules/audio_processing/test/protobuf_utils.h" |
25 #include "webrtc/modules/audio_processing/test/test_utils.h" | 26 #include "webrtc/modules/audio_processing/test/test_utils.h" |
26 #include "webrtc/modules/include/module_common_types.h" | 27 #include "webrtc/modules/include/module_common_types.h" |
27 #include "webrtc/system_wrappers/include/cpu_features_wrapper.h" | 28 #include "webrtc/system_wrappers/include/cpu_features_wrapper.h" |
28 #include "webrtc/system_wrappers/include/tick_util.h" | |
29 #include "webrtc/test/testsupport/fileutils.h" | 29 #include "webrtc/test/testsupport/fileutils.h" |
30 #include "webrtc/test/testsupport/perf_test.h" | 30 #include "webrtc/test/testsupport/perf_test.h" |
31 #ifdef WEBRTC_ANDROID_PLATFORM_BUILD | 31 #ifdef WEBRTC_ANDROID_PLATFORM_BUILD |
32 #include "gtest/gtest.h" | 32 #include "gtest/gtest.h" |
33 #include "external/webrtc/webrtc/modules/audio_processing/debug.pb.h" | 33 #include "external/webrtc/webrtc/modules/audio_processing/debug.pb.h" |
34 #else | 34 #else |
35 #include "testing/gtest/include/gtest/gtest.h" | 35 #include "testing/gtest/include/gtest/gtest.h" |
36 #include "webrtc/modules/audio_processing/debug.pb.h" | 36 #include "webrtc/modules/audio_processing/debug.pb.h" |
37 #endif | 37 #endif |
38 | 38 |
(...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
555 } | 555 } |
556 | 556 |
557 if (aecm_echo_path_out_filename != NULL) { | 557 if (aecm_echo_path_out_filename != NULL) { |
558 aecm_echo_path_out_file = OpenFile(aecm_echo_path_out_filename, "wb"); | 558 aecm_echo_path_out_file = OpenFile(aecm_echo_path_out_filename, "wb"); |
559 } | 559 } |
560 | 560 |
561 size_t read_count = 0; | 561 size_t read_count = 0; |
562 int reverse_count = 0; | 562 int reverse_count = 0; |
563 int primary_count = 0; | 563 int primary_count = 0; |
564 int near_read_bytes = 0; | 564 int near_read_bytes = 0; |
565 TickInterval acc_ticks; | 565 int64_t acc_nanos = 0; |
566 | 566 |
567 AudioFrame far_frame; | 567 AudioFrame far_frame; |
568 AudioFrame near_frame; | 568 AudioFrame near_frame; |
569 | 569 |
570 int delay_ms = 0; | 570 int delay_ms = 0; |
571 int drift_samples = 0; | 571 int drift_samples = 0; |
572 int capture_level = 127; | 572 int capture_level = 127; |
573 int8_t stream_has_voice = 0; | 573 int8_t stream_has_voice = 0; |
574 float ns_speech_prob = 0.0f; | 574 float ns_speech_prob = 0.0f; |
575 | 575 |
576 TickTime t0 = TickTime::Now(); | 576 int64_t t0 = rtc::TimeNanos(); |
577 TickTime t1 = t0; | 577 int64_t t1 = t0; |
578 int64_t max_time_us = 0; | 578 int64_t max_time_us = 0; |
579 int64_t max_time_reverse_us = 0; | 579 int64_t max_time_reverse_us = 0; |
580 int64_t min_time_us = 1e6; | 580 int64_t min_time_us = 1e6; |
581 int64_t min_time_reverse_us = 1e6; | 581 int64_t min_time_reverse_us = 1e6; |
582 | 582 |
583 // TODO(ajm): Ideally we would refactor this block into separate functions, | 583 // TODO(ajm): Ideally we would refactor this block into separate functions, |
584 // but for now we want to share the variables. | 584 // but for now we want to share the variables. |
585 if (pb_file) { | 585 if (pb_file) { |
586 Event event_msg; | 586 Event event_msg; |
587 std::unique_ptr<ChannelBuffer<float> > reverse_cb; | 587 std::unique_ptr<ChannelBuffer<float> > reverse_cb; |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
669 } else { | 669 } else { |
670 for (int i = 0; i < msg.channel_size(); ++i) { | 670 for (int i = 0; i < msg.channel_size(); ++i) { |
671 memcpy(reverse_cb->channels()[i], | 671 memcpy(reverse_cb->channels()[i], |
672 msg.channel(i).data(), | 672 msg.channel(i).data(), |
673 reverse_cb->num_frames() * | 673 reverse_cb->num_frames() * |
674 sizeof(reverse_cb->channels()[i][0])); | 674 sizeof(reverse_cb->channels()[i][0])); |
675 } | 675 } |
676 } | 676 } |
677 | 677 |
678 if (perf_testing) { | 678 if (perf_testing) { |
679 t0 = TickTime::Now(); | 679 t0 = rtc::TimeNanos(); |
680 } | 680 } |
681 | 681 |
682 if (msg.has_data()) { | 682 if (msg.has_data()) { |
683 ASSERT_EQ(apm->kNoError, | 683 ASSERT_EQ(apm->kNoError, |
684 apm->ProcessReverseStream(&far_frame)); | 684 apm->ProcessReverseStream(&far_frame)); |
685 } else { | 685 } else { |
686 ASSERT_EQ(apm->kNoError, | 686 ASSERT_EQ(apm->kNoError, |
687 apm->AnalyzeReverseStream( | 687 apm->AnalyzeReverseStream( |
688 reverse_cb->channels(), | 688 reverse_cb->channels(), |
689 far_frame.samples_per_channel_, | 689 far_frame.samples_per_channel_, |
690 far_frame.sample_rate_hz_, | 690 far_frame.sample_rate_hz_, |
691 LayoutFromChannels(far_frame.num_channels_))); | 691 LayoutFromChannels(far_frame.num_channels_))); |
692 } | 692 } |
693 | 693 |
694 if (perf_testing) { | 694 if (perf_testing) { |
695 t1 = TickTime::Now(); | 695 t1 = rtc::TimeNanos(); |
696 TickInterval tick_diff = t1 - t0; | 696 int64_t diff_nanos = t1 - t0; |
697 acc_ticks += tick_diff; | 697 acc_nanos += diff_nanos; |
698 if (tick_diff.Microseconds() > max_time_reverse_us) { | 698 int64_t diff_us = diff_nanos / rtc::kNumNanosecsPerMicrosec; |
699 max_time_reverse_us = tick_diff.Microseconds(); | 699 if (diff_us > max_time_reverse_us) { |
| 700 max_time_reverse_us = diff_us; |
700 } | 701 } |
701 if (tick_diff.Microseconds() < min_time_reverse_us) { | 702 if (diff_us < min_time_reverse_us) { |
702 min_time_reverse_us = tick_diff.Microseconds(); | 703 min_time_reverse_us = diff_us; |
703 } | 704 } |
704 } | 705 } |
705 | 706 |
706 } else if (event_msg.type() == Event::STREAM) { | 707 } else if (event_msg.type() == Event::STREAM) { |
707 ASSERT_TRUE(event_msg.has_stream()); | 708 ASSERT_TRUE(event_msg.has_stream()); |
708 const Stream msg = event_msg.stream(); | 709 const Stream msg = event_msg.stream(); |
709 primary_count++; | 710 primary_count++; |
710 | 711 |
711 // ProcessStream could have changed this for the output frame. | 712 // ProcessStream could have changed this for the output frame. |
712 near_frame.num_channels_ = apm->num_input_channels(); | 713 near_frame.num_channels_ = apm->num_input_channels(); |
(...skipping 17 matching lines...) Expand all Loading... |
730 } | 731 } |
731 | 732 |
732 if (progress && primary_count % 100 == 0) { | 733 if (progress && primary_count % 100 == 0) { |
733 near_read_bytes = std::min(near_read_bytes, near_size_bytes); | 734 near_read_bytes = std::min(near_read_bytes, near_size_bytes); |
734 printf("%.0f%% complete\r", | 735 printf("%.0f%% complete\r", |
735 (near_read_bytes * 100.0) / near_size_bytes); | 736 (near_read_bytes * 100.0) / near_size_bytes); |
736 fflush(stdout); | 737 fflush(stdout); |
737 } | 738 } |
738 | 739 |
739 if (perf_testing) { | 740 if (perf_testing) { |
740 t0 = TickTime::Now(); | 741 t0 = rtc::TimeNanos(); |
741 } | 742 } |
742 | 743 |
743 ASSERT_EQ(apm->kNoError, | 744 ASSERT_EQ(apm->kNoError, |
744 apm->gain_control()->set_stream_analog_level(msg.level())); | 745 apm->gain_control()->set_stream_analog_level(msg.level())); |
745 delay_ms = msg.delay() + extra_delay_ms; | 746 delay_ms = msg.delay() + extra_delay_ms; |
746 if (override_delay_ms) { | 747 if (override_delay_ms) { |
747 delay_ms = override_delay_ms; | 748 delay_ms = override_delay_ms; |
748 } | 749 } |
749 ASSERT_EQ(apm->kNoError, | 750 ASSERT_EQ(apm->kNoError, |
750 apm->set_stream_delay_ms(delay_ms)); | 751 apm->set_stream_delay_ms(delay_ms)); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
788 | 789 |
789 if (ns_prob_file != NULL) { | 790 if (ns_prob_file != NULL) { |
790 ns_speech_prob = apm->noise_suppression()->speech_probability(); | 791 ns_speech_prob = apm->noise_suppression()->speech_probability(); |
791 ASSERT_EQ(1u, fwrite(&ns_speech_prob, | 792 ASSERT_EQ(1u, fwrite(&ns_speech_prob, |
792 sizeof(ns_speech_prob), | 793 sizeof(ns_speech_prob), |
793 1, | 794 1, |
794 ns_prob_file)); | 795 ns_prob_file)); |
795 } | 796 } |
796 | 797 |
797 if (perf_testing) { | 798 if (perf_testing) { |
798 t1 = TickTime::Now(); | 799 t1 = rtc::TimeNanos(); |
799 TickInterval tick_diff = t1 - t0; | 800 int64_t diff_nanos = t1 - t0; |
800 acc_ticks += tick_diff; | 801 acc_nanos += diff_nanos; |
801 if (tick_diff.Microseconds() > max_time_us) { | 802 int64_t diff_us = diff_nanos / rtc::kNumNanosecsPerMicrosec; |
802 max_time_us = tick_diff.Microseconds(); | 803 if (diff_us > max_time_us) { |
| 804 max_time_us = diff_us; |
803 } | 805 } |
804 if (tick_diff.Microseconds() < min_time_us) { | 806 if (diff_us < min_time_us) { |
805 min_time_us = tick_diff.Microseconds(); | 807 min_time_us = diff_us; |
806 } | 808 } |
807 } | 809 } |
808 | 810 |
809 const size_t samples_per_channel = output_sample_rate / 100; | 811 const size_t samples_per_channel = output_sample_rate / 100; |
810 if (msg.has_input_data()) { | 812 if (msg.has_input_data()) { |
811 if (raw_output && !output_raw_file) { | 813 if (raw_output && !output_raw_file) { |
812 output_raw_file.reset(new RawFile(out_filename + ".pcm")); | 814 output_raw_file.reset(new RawFile(out_filename + ".pcm")); |
813 } | 815 } |
814 WriteIntData(near_frame.data_, | 816 WriteIntData(near_frame.data_, |
815 apm->num_output_channels() * samples_per_channel, | 817 apm->num_output_channels() * samples_per_channel, |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
918 // not reaching end-of-file. | 920 // not reaching end-of-file. |
919 EXPECT_EQ(0, fseek(near_file, read_count * sizeof(int16_t), | 921 EXPECT_EQ(0, fseek(near_file, read_count * sizeof(int16_t), |
920 SEEK_CUR)); | 922 SEEK_CUR)); |
921 break; // This is expected. | 923 break; // This is expected. |
922 } | 924 } |
923 } else { | 925 } else { |
924 ASSERT_EQ(size, read_count); | 926 ASSERT_EQ(size, read_count); |
925 } | 927 } |
926 | 928 |
927 if (perf_testing) { | 929 if (perf_testing) { |
928 t0 = TickTime::Now(); | 930 t0 = rtc::TimeNanos(); |
929 } | 931 } |
930 | 932 |
931 ASSERT_EQ(apm->kNoError, | 933 ASSERT_EQ(apm->kNoError, |
932 apm->ProcessReverseStream(&far_frame)); | 934 apm->ProcessReverseStream(&far_frame)); |
933 | 935 |
934 if (perf_testing) { | 936 if (perf_testing) { |
935 t1 = TickTime::Now(); | 937 t1 = rtc::TimeNanos(); |
936 TickInterval tick_diff = t1 - t0; | 938 int64_t diff_nanos = t1 - t0; |
937 acc_ticks += tick_diff; | 939 acc_nanos += diff_nanos; |
938 if (tick_diff.Microseconds() > max_time_reverse_us) { | 940 int64_t diff_us = diff_nanos / rtc::kNumNanosecsPerMicrosec; |
939 max_time_reverse_us = tick_diff.Microseconds(); | 941 if (diff_us > max_time_reverse_us) { |
| 942 max_time_reverse_us = diff_us; |
940 } | 943 } |
941 if (tick_diff.Microseconds() < min_time_reverse_us) { | 944 if (diff_us < min_time_reverse_us) { |
942 min_time_reverse_us = tick_diff.Microseconds(); | 945 min_time_reverse_us = diff_us; |
943 } | 946 } |
944 } | 947 } |
945 | 948 |
946 } else if (event == kCaptureEvent) { | 949 } else if (event == kCaptureEvent) { |
947 primary_count++; | 950 primary_count++; |
948 near_frame.num_channels_ = num_capture_input_channels; | 951 near_frame.num_channels_ = num_capture_input_channels; |
949 | 952 |
950 size_t size = samples_per_channel * num_capture_input_channels; | 953 size_t size = samples_per_channel * num_capture_input_channels; |
951 read_count = fread(near_frame.data_, | 954 read_count = fread(near_frame.data_, |
952 sizeof(int16_t), | 955 sizeof(int16_t), |
(...skipping 22 matching lines...) Expand all Loading... |
975 ASSERT_EQ(1u, | 978 ASSERT_EQ(1u, |
976 fread(&drift_samples, sizeof(drift_samples), 1, drift_file)); | 979 fread(&drift_samples, sizeof(drift_samples), 1, drift_file)); |
977 } | 980 } |
978 | 981 |
979 if (apm->gain_control()->is_enabled() && | 982 if (apm->gain_control()->is_enabled() && |
980 apm->gain_control()->mode() == GainControl::kAdaptiveAnalog) { | 983 apm->gain_control()->mode() == GainControl::kAdaptiveAnalog) { |
981 SimulateMic(capture_level, &near_frame); | 984 SimulateMic(capture_level, &near_frame); |
982 } | 985 } |
983 | 986 |
984 if (perf_testing) { | 987 if (perf_testing) { |
985 t0 = TickTime::Now(); | 988 t0 = rtc::TimeNanos(); |
986 } | 989 } |
987 | 990 |
988 const int capture_level_in = capture_level; | 991 const int capture_level_in = capture_level; |
989 ASSERT_EQ(apm->kNoError, | 992 ASSERT_EQ(apm->kNoError, |
990 apm->gain_control()->set_stream_analog_level(capture_level)); | 993 apm->gain_control()->set_stream_analog_level(capture_level)); |
991 delay_ms += extra_delay_ms; | 994 delay_ms += extra_delay_ms; |
992 if (override_delay_ms) { | 995 if (override_delay_ms) { |
993 delay_ms = override_delay_ms; | 996 delay_ms = override_delay_ms; |
994 } | 997 } |
995 ASSERT_EQ(apm->kNoError, | 998 ASSERT_EQ(apm->kNoError, |
(...skipping 27 matching lines...) Expand all Loading... |
1023 sizeof(ns_speech_prob), | 1026 sizeof(ns_speech_prob), |
1024 1, | 1027 1, |
1025 ns_prob_file)); | 1028 ns_prob_file)); |
1026 } | 1029 } |
1027 | 1030 |
1028 if (apm->gain_control()->mode() != GainControl::kAdaptiveAnalog) { | 1031 if (apm->gain_control()->mode() != GainControl::kAdaptiveAnalog) { |
1029 ASSERT_EQ(capture_level_in, capture_level); | 1032 ASSERT_EQ(capture_level_in, capture_level); |
1030 } | 1033 } |
1031 | 1034 |
1032 if (perf_testing) { | 1035 if (perf_testing) { |
1033 t1 = TickTime::Now(); | 1036 t1 = rtc::TimeNanos(); |
1034 TickInterval tick_diff = t1 - t0; | 1037 int64_t diff_nanos = t1 - t0; |
1035 acc_ticks += tick_diff; | 1038 acc_nanos += diff_nanos; |
1036 if (tick_diff.Microseconds() > max_time_us) { | 1039 int64_t diff_us = diff_nanos / rtc::kNumNanosecsPerMicrosec; |
1037 max_time_us = tick_diff.Microseconds(); | 1040 if (diff_us > max_time_us) { |
| 1041 max_time_us = diff_us; |
1038 } | 1042 } |
1039 if (tick_diff.Microseconds() < min_time_us) { | 1043 if (diff_us < min_time_us) { |
1040 min_time_us = tick_diff.Microseconds(); | 1044 min_time_us = diff_us; |
1041 } | 1045 } |
1042 } | 1046 } |
1043 | 1047 |
1044 if (raw_output && !output_raw_file) { | 1048 if (raw_output && !output_raw_file) { |
1045 output_raw_file.reset(new RawFile(out_filename + ".pcm")); | 1049 output_raw_file.reset(new RawFile(out_filename + ".pcm")); |
1046 } | 1050 } |
1047 if (!raw_output && !output_wav_file) { | 1051 if (!raw_output && !output_wav_file) { |
1048 output_wav_file.reset(new WavWriter(out_filename + ".wav", | 1052 output_wav_file.reset(new WavWriter(out_filename + ".wav", |
1049 sample_rate_hz, | 1053 sample_rate_hz, |
1050 num_capture_output_channels)); | 1054 num_capture_output_channels)); |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1123 EXPECT_NE(0, feof(event_file)) << "Event file not fully processed"; | 1127 EXPECT_NE(0, feof(event_file)) << "Event file not fully processed"; |
1124 read_count = fread(&temp_int8, sizeof(temp_int8), 1, delay_file); | 1128 read_count = fread(&temp_int8, sizeof(temp_int8), 1, delay_file); |
1125 EXPECT_NE(0, feof(delay_file)) << "Delay file not fully processed"; | 1129 EXPECT_NE(0, feof(delay_file)) << "Delay file not fully processed"; |
1126 read_count = fread(&temp_int8, sizeof(temp_int8), 1, drift_file); | 1130 read_count = fread(&temp_int8, sizeof(temp_int8), 1, drift_file); |
1127 EXPECT_NE(0, feof(drift_file)) << "Drift file not fully processed"; | 1131 EXPECT_NE(0, feof(drift_file)) << "Drift file not fully processed"; |
1128 } | 1132 } |
1129 } | 1133 } |
1130 | 1134 |
1131 if (perf_testing) { | 1135 if (perf_testing) { |
1132 if (primary_count > 0) { | 1136 if (primary_count > 0) { |
1133 int64_t exec_time = acc_ticks.Milliseconds(); | 1137 int64_t exec_time = acc_nanos / rtc::kNumNanosecsPerMillisec; |
1134 printf("\nTotal time: %.3f s, file time: %.2f s\n", | 1138 printf("\nTotal time: %.3f s, file time: %.2f s\n", |
1135 exec_time * 0.001, primary_count * 0.01); | 1139 exec_time * 0.001, primary_count * 0.01); |
1136 printf("Time per frame: %.3f ms (average), %.3f ms (max)," | 1140 printf("Time per frame: %.3f ms (average), %.3f ms (max)," |
1137 " %.3f ms (min)\n", | 1141 " %.3f ms (min)\n", |
1138 (exec_time * 1.0) / primary_count, | 1142 (exec_time * 1.0) / primary_count, |
1139 (max_time_us + max_time_reverse_us) / 1000.0, | 1143 (max_time_us + max_time_reverse_us) / 1000.0, |
1140 (min_time_us + min_time_reverse_us) / 1000.0); | 1144 (min_time_us + min_time_reverse_us) / 1000.0); |
1141 // Record the results with Perf test tools. | 1145 // Record the results with Perf test tools. |
1142 webrtc::test::PrintResult("audioproc", "", "time_per_10ms_frame", | 1146 webrtc::test::PrintResult("audioproc", "", "time_per_10ms_frame", |
1143 (exec_time * 1000) / primary_count, "us", false); | 1147 (exec_time * 1000) / primary_count, "us", false); |
1144 } else { | 1148 } else { |
1145 printf("Warning: no capture frames\n"); | 1149 printf("Warning: no capture frames\n"); |
1146 } | 1150 } |
1147 } | 1151 } |
1148 } | 1152 } |
1149 | 1153 |
1150 } // namespace | 1154 } // namespace |
1151 } // namespace webrtc | 1155 } // namespace webrtc |
1152 | 1156 |
1153 int main(int argc, char* argv[]) { | 1157 int main(int argc, char* argv[]) { |
1154 webrtc::void_main(argc, argv); | 1158 webrtc::void_main(argc, argv); |
1155 | 1159 |
1156 // Optional, but removes memory leak noise from Valgrind. | 1160 // Optional, but removes memory leak noise from Valgrind. |
1157 google::protobuf::ShutdownProtobufLibrary(); | 1161 google::protobuf::ShutdownProtobufLibrary(); |
1158 return 0; | 1162 return 0; |
1159 } | 1163 } |
OLD | NEW |