diff --git a/webrtc/base/BUILD.gn b/webrtc/base/BUILD.gn index c7c953d84c..ca96e920e5 100644 --- a/webrtc/base/BUILD.gn +++ b/webrtc/base/BUILD.gn @@ -134,6 +134,8 @@ static_library("rtc_base_approved") { "platform_thread.cc", "platform_thread.h", "platform_thread_types.h", + "random.cc", + "random.h", "safe_conversions.h", "safe_conversions_impl.h", "scoped_ptr.h", diff --git a/webrtc/base/base.gyp b/webrtc/base/base.gyp index 9d104032e3..77cd011f1c 100644 --- a/webrtc/base/base.gyp +++ b/webrtc/base/base.gyp @@ -88,6 +88,8 @@ 'platform_thread.cc', 'platform_thread.h', 'platform_thread_types.h', + 'random.cc', + 'random.h', 'ratetracker.cc', 'ratetracker.h', 'safe_conversions.h', diff --git a/webrtc/base/base_tests.gyp b/webrtc/base/base_tests.gyp index 1da93defd4..b813197422 100644 --- a/webrtc/base/base_tests.gyp +++ b/webrtc/base/base_tests.gyp @@ -84,6 +84,7 @@ 'profiler_unittest.cc', 'proxy_unittest.cc', 'proxydetect_unittest.cc', + 'random_unittest.cc', 'ratelimiter_unittest.cc', 'ratetracker_unittest.cc', 'referencecountedsingletonfactory_unittest.cc', diff --git a/webrtc/base/random.cc b/webrtc/base/random.cc new file mode 100644 index 0000000000..14a9faf5b3 --- /dev/null +++ b/webrtc/base/random.cc @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ +#include "webrtc/base/random.h" + +#include + +#include "webrtc/base/checks.h" + +namespace webrtc { + +Random::Random(uint64_t seed) { + RTC_DCHECK(seed != 0x0ull); + state_ = seed; +} + +uint32_t Random::Rand(uint32_t t) { + // Casting the output to 32 bits will give an almost uniform number. + // Pr[x=0] = (2^32-1) / (2^64-1) + // Pr[x=k] = 2^32 / (2^64-1) for k!=0 + // Uniform would be Pr[x=k] = 2^32 / 2^64 for all 32-bit integers k. + uint32_t x = NextOutput(); + // If x / 2^32 is uniform on [0,1), then x / 2^32 * (t+1) is uniform on + // the interval [0,t+1), so the integer part is uniform on [0,t]. + uint64_t result = x * (static_cast(t) + 1); + result >>= 32; + return result; +} + +uint32_t Random::Rand(uint32_t low, uint32_t high) { + RTC_DCHECK(low <= high); + return Rand(high - low) + low; +} + +int32_t Random::Rand(int32_t low, int32_t high) { + RTC_DCHECK(low <= high); + // We rely on subtraction (and addition) to be the same for signed and + // unsigned numbers in two-complement representation. Thus, although + // high - low might be negative as an int, it is the correct difference + // when interpreted as an unsigned. + return Rand(high - low) + low; +} + +template <> +float Random::Rand() { + double result = NextOutput() - 1; + result = result / 0xFFFFFFFFFFFFFFFEull; + return static_cast(result); +} + +template <> +double Random::Rand() { + double result = NextOutput() - 1; + result = result / 0xFFFFFFFFFFFFFFFEull; + return result; +} + +template <> +bool Random::Rand() { + return Rand(0, 1) == 1; +} + +double Random::Gaussian(double mean, double standard_deviation) { + // Creating a Normal distribution variable from two independent uniform + // variables based on the Box-Muller transform, which is defined on the + // interval (0, 1]. Note that we rely on NextOutput to generate integers + // in the range [1, 2^64-1]. Normally this behavior is a bit frustrating, + // but here it is exactly what we need. + const double kPi = 3.14159265358979323846; + double u1 = static_cast(NextOutput()) / 0xFFFFFFFFFFFFFFFFull; + double u2 = static_cast(NextOutput()) / 0xFFFFFFFFFFFFFFFFull; + return mean + standard_deviation * sqrt(-2 * log(u1)) * cos(2 * kPi * u2); +} + +double Random::Exponential(double lambda) { + double uniform = Rand(); + return -log(uniform) / lambda; +} + +} // namespace webrtc diff --git a/webrtc/test/random.h b/webrtc/base/random.h similarity index 63% rename from webrtc/test/random.h rename to webrtc/base/random.h index c7254a9b49..647b84c9c9 100644 --- a/webrtc/test/random.h +++ b/webrtc/base/random.h @@ -8,23 +8,23 @@ * be found in the AUTHORS file in the root of the source tree. */ -#ifndef WEBRTC_TEST_RANDOM_H_ -#define WEBRTC_TEST_RANDOM_H_ +#ifndef WEBRTC_BASE_RANDOM_H_ +#define WEBRTC_BASE_RANDOM_H_ #include #include "webrtc/typedefs.h" #include "webrtc/base/constructormagic.h" +#include "webrtc/base/checks.h" namespace webrtc { -namespace test { - class Random { public: - explicit Random(uint32_t seed); + explicit Random(uint64_t seed); // Return pseudo-random integer of the specified type. + // We need to limit the size to 32 bits to keep the output close to uniform. template T Rand() { static_assert(std::numeric_limits::is_integer && @@ -32,7 +32,7 @@ class Random { std::numeric_limits::digits <= 32, "Rand is only supported for built-in integer types that are " "32 bits or smaller."); - return static_cast(Rand(std::numeric_limits::max())); + return static_cast(NextOutput()); } // Uniformly distributed pseudo-random number in the interval [0, t]. @@ -41,18 +41,26 @@ class Random { // Uniformly distributed pseudo-random number in the interval [low, high]. uint32_t Rand(uint32_t low, uint32_t high); + // Uniformly distributed pseudo-random number in the interval [low, high]. + int32_t Rand(int32_t low, int32_t high); + // Normal Distribution. - int Gaussian(int mean, int standard_deviation); + double Gaussian(double mean, double standard_deviation); // Exponential Distribution. - int Exponential(float lambda); - - // TODO(solenberg): Random from histogram. - // template int Distribution(const std::vector histogram) { + double Exponential(double lambda); private: - uint32_t a_; - uint32_t b_; + // Outputs a nonzero 64-bit random number. + uint64_t NextOutput() { + state_ ^= state_ >> 12; + state_ ^= state_ << 25; + state_ ^= state_ >> 27; + RTC_DCHECK(state_ != 0x0ULL); + return state_ * 2685821657736338717ull; + } + + uint64_t state_; RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(Random); }; @@ -61,11 +69,14 @@ class Random { template <> float Random::Rand(); +// Return pseudo-random number in the interval [0.0, 1.0). +template <> +double Random::Rand(); + // Return pseudo-random boolean value. template <> bool Random::Rand(); -} // namespace test } // namespace webrtc -#endif // WEBRTC_TEST_RANDOM_H_ +#endif // WEBRTC_BASE_RANDOM_H_ diff --git a/webrtc/base/random_unittest.cc b/webrtc/base/random_unittest.cc new file mode 100644 index 0000000000..febae1c28f --- /dev/null +++ b/webrtc/base/random_unittest.cc @@ -0,0 +1,302 @@ +/* + * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include + +#include +#include + +#include "testing/gtest/include/gtest/gtest.h" +#include "webrtc/base/random.h" + +namespace webrtc { + +namespace { +// Computes the positive remainder of x/n. +template +T fdiv_remainder(T x, T n) { + RTC_CHECK_GE(n, static_cast(0)); + T remainder = x % n; + if (remainder < 0) + remainder += n; + return remainder; +} +} // namespace + +// Sample a number of random integers of type T. Divide them into buckets +// based on the remainder when dividing by bucket_count and check that each +// bucket gets roughly the expected number of elements. +template +void UniformBucketTest(T bucket_count, int samples, Random* prng) { + std::vector buckets(bucket_count, 0); + + uint64_t total_values = 1ull << (std::numeric_limits::digits + + std::numeric_limits::is_signed); + T upper_limit = + std::numeric_limits::max() - + static_cast(total_values % static_cast(bucket_count)); + ASSERT_GT(upper_limit, std::numeric_limits::max() / 2); + + for (int i = 0; i < samples; i++) { + T sample; + do { + // We exclude a few numbers from the range so that it is divisible by + // the number of buckets. If we are unlucky and hit one of the excluded + // numbers we just resample. Note that if the number of buckets is a + // power of 2, then we don't have to exclude anything. + sample = prng->Rand(); + } while (sample > upper_limit); + buckets[fdiv_remainder(sample, bucket_count)]++; + } + + for (T i = 0; i < bucket_count; i++) { + // Expect the result to be within 3 standard deviations of the mean. + EXPECT_NEAR(buckets[i], samples / bucket_count, + 3 * sqrt(samples / bucket_count)); + } +} + +TEST(RandomNumberGeneratorTest, BucketTestSignedChar) { + Random prng(7297352569824ull); + UniformBucketTest(64, 640000, &prng); + UniformBucketTest(11, 440000, &prng); + UniformBucketTest(3, 270000, &prng); +} + +TEST(RandomNumberGeneratorTest, BucketTestUnsignedChar) { + Random prng(7297352569824ull); + UniformBucketTest(64, 640000, &prng); + UniformBucketTest(11, 440000, &prng); + UniformBucketTest(3, 270000, &prng); +} + +TEST(RandomNumberGeneratorTest, BucketTestSignedShort) { + Random prng(7297352569824ull); + UniformBucketTest(64, 640000, &prng); + UniformBucketTest(11, 440000, &prng); + UniformBucketTest(3, 270000, &prng); +} + +TEST(RandomNumberGeneratorTest, BucketTestUnsignedShort) { + Random prng(7297352569824ull); + UniformBucketTest(64, 640000, &prng); + UniformBucketTest(11, 440000, &prng); + UniformBucketTest(3, 270000, &prng); +} + +TEST(RandomNumberGeneratorTest, BucketTestSignedInt) { + Random prng(7297352569824ull); + UniformBucketTest(64, 640000, &prng); + UniformBucketTest(11, 440000, &prng); + UniformBucketTest(3, 270000, &prng); +} + +TEST(RandomNumberGeneratorTest, BucketTestUnsignedInt) { + Random prng(7297352569824ull); + UniformBucketTest(64, 640000, &prng); + UniformBucketTest(11, 440000, &prng); + UniformBucketTest(3, 270000, &prng); +} + +// The range of the random numbers is divided into bucket_count intervals +// of consecutive numbers. Check that approximately equally many numbers +// from each inteval are generated. +void BucketTestSignedInterval(unsigned int bucket_count, + unsigned int samples, + int32_t low, + int32_t high, + int sigma_level, + Random* prng) { + std::vector buckets(bucket_count, 0); + + ASSERT_GE(high, low); + ASSERT_GE(bucket_count, 2u); + uint32_t interval = static_cast(high - low + 1); + uint32_t numbers_per_bucket; + if (interval == 0) { + // The computation high - low + 1 should be 2^32 but overflowed + // Hence, bucket_count must be a power of 2 + ASSERT_EQ(bucket_count & (bucket_count - 1), 0u); + numbers_per_bucket = (0x80000000u / bucket_count) * 2; + } else { + ASSERT_EQ(interval % bucket_count, 0u); + numbers_per_bucket = interval / bucket_count; + } + + for (unsigned int i = 0; i < samples; i++) { + int32_t sample = prng->Rand(low, high); + EXPECT_LE(low, sample); + EXPECT_GE(high, sample); + buckets[static_cast(sample - low) / numbers_per_bucket]++; + } + + for (unsigned int i = 0; i < bucket_count; i++) { + // Expect the result to be within 3 standard deviations of the mean, + // or more generally, within sigma_level standard deviations of the mean. + double mean = static_cast(samples) / bucket_count; + EXPECT_NEAR(buckets[i], mean, sigma_level * sqrt(mean)); + } +} + +// The range of the random numbers is divided into bucket_count intervals +// of consecutive numbers. Check that approximately equally many numbers +// from each inteval are generated. +void BucketTestUnsignedInterval(unsigned int bucket_count, + unsigned int samples, + uint32_t low, + uint32_t high, + int sigma_level, + Random* prng) { + std::vector buckets(bucket_count, 0); + + ASSERT_GE(high, low); + ASSERT_GE(bucket_count, 2u); + uint32_t interval = static_cast(high - low + 1); + uint32_t numbers_per_bucket; + if (interval == 0) { + // The computation high - low + 1 should be 2^32 but overflowed + // Hence, bucket_count must be a power of 2 + ASSERT_EQ(bucket_count & (bucket_count - 1), 0u); + numbers_per_bucket = (0x80000000u / bucket_count) * 2; + } else { + ASSERT_EQ(interval % bucket_count, 0u); + numbers_per_bucket = interval / bucket_count; + } + + for (unsigned int i = 0; i < samples; i++) { + uint32_t sample = prng->Rand(low, high); + EXPECT_LE(low, sample); + EXPECT_GE(high, sample); + buckets[static_cast(sample - low) / numbers_per_bucket]++; + } + + for (unsigned int i = 0; i < bucket_count; i++) { + // Expect the result to be within 3 standard deviations of the mean, + // or more generally, within sigma_level standard deviations of the mean. + double mean = static_cast(samples) / bucket_count; + EXPECT_NEAR(buckets[i], mean, sigma_level * sqrt(mean)); + } +} + +TEST(RandomNumberGeneratorTest, UniformUnsignedInterval) { + Random prng(299792458ull); + BucketTestUnsignedInterval(2, 100000, 0, 1, 3, &prng); + BucketTestUnsignedInterval(7, 100000, 1, 14, 3, &prng); + BucketTestUnsignedInterval(11, 100000, 1000, 1010, 3, &prng); + BucketTestUnsignedInterval(100, 100000, 0, 99, 3, &prng); + BucketTestUnsignedInterval(2, 100000, 0, 4294967295, 3, &prng); + BucketTestUnsignedInterval(17, 100000, 455, 2147484110, 3, &prng); + // 99.7% of all samples will be within 3 standard deviations of the mean, + // but since we test 1000 buckets we allow an interval of 4 sigma. + BucketTestUnsignedInterval(1000, 1000000, 0, 2147483999, 4, &prng); +} + +TEST(RandomNumberGeneratorTest, UniformSignedInterval) { + Random prng(66260695729ull); + BucketTestSignedInterval(2, 100000, 0, 1, 3, &prng); + BucketTestSignedInterval(7, 100000, -2, 4, 3, &prng); + BucketTestSignedInterval(11, 100000, 1000, 1010, 3, &prng); + BucketTestSignedInterval(100, 100000, 0, 99, 3, &prng); + BucketTestSignedInterval(2, 100000, std::numeric_limits::min(), + std::numeric_limits::max(), 3, &prng); + BucketTestSignedInterval(17, 100000, -1073741826, 1073741829, 3, &prng); + // 99.7% of all samples will be within 3 standard deviations of the mean, + // but since we test 1000 buckets we allow an interval of 4 sigma. + BucketTestSignedInterval(1000, 1000000, -352, 2147483647, 4, &prng); +} + +// The range of the random numbers is divided into bucket_count intervals +// of consecutive numbers. Check that approximately equally many numbers +// from each inteval are generated. +void BucketTestFloat(unsigned int bucket_count, + unsigned int samples, + int sigma_level, + Random* prng) { + ASSERT_GE(bucket_count, 2u); + std::vector buckets(bucket_count, 0); + + for (unsigned int i = 0; i < samples; i++) { + uint32_t sample = bucket_count * prng->Rand(); + EXPECT_LE(0u, sample); + EXPECT_GE(bucket_count - 1, sample); + buckets[sample]++; + } + + for (unsigned int i = 0; i < bucket_count; i++) { + // Expect the result to be within 3 standard deviations of the mean, + // or more generally, within sigma_level standard deviations of the mean. + double mean = static_cast(samples) / bucket_count; + EXPECT_NEAR(buckets[i], mean, sigma_level * sqrt(mean)); + } +} + +TEST(RandomNumberGeneratorTest, UniformFloatInterval) { + Random prng(1380648813ull); + BucketTestFloat(100, 100000, 3, &prng); + // 99.7% of all samples will be within 3 standard deviations of the mean, + // but since we test 1000 buckets we allow an interval of 4 sigma. + // BucketTestSignedInterval(1000, 1000000, -352, 2147483647, 4, &prng); +} + +TEST(RandomNumberGeneratorTest, SignedHasSameBitPattern) { + Random prng_signed(66738480ull), prng_unsigned(66738480ull); + + for (int i = 0; i < 1000; i++) { + signed int s = prng_signed.Rand(); + unsigned int u = prng_unsigned.Rand(); + EXPECT_EQ(u, static_cast(s)); + } + + for (int i = 0; i < 1000; i++) { + int16_t s = prng_signed.Rand(); + uint16_t u = prng_unsigned.Rand(); + EXPECT_EQ(u, static_cast(s)); + } + + for (int i = 0; i < 1000; i++) { + signed char s = prng_signed.Rand(); + unsigned char u = prng_unsigned.Rand(); + EXPECT_EQ(u, static_cast(s)); + } +} + +TEST(RandomNumberGeneratorTest, Gaussian) { + const int kN = 100000; + const int kBuckets = 100; + const double kMean = 49; + const double kStddev = 10; + + Random prng(1256637061); + + std::vector buckets(kBuckets, 0); + for (int i = 0; i < kN; i++) { + int index = prng.Gaussian(kMean, kStddev) + 0.5; + if (index >= 0 && index < kBuckets) { + buckets[index]++; + } + } + + const double kPi = 3.14159265358979323846; + const double kScale = 1 / (kStddev * sqrt(2.0 * kPi)); + const double kDiv = -2.0 * kStddev * kStddev; + for (int n = 0; n < kBuckets; ++n) { + // Use Simpsons rule to estimate the probability that a random gaussian + // sample is in the interval [n-0.5, n+0.5]. + double f_left = kScale * exp((n - kMean - 0.5) * (n - kMean - 0.5) / kDiv); + double f_mid = kScale * exp((n - kMean) * (n - kMean) / kDiv); + double f_right = kScale * exp((n - kMean + 0.5) * (n - kMean + 0.5) / kDiv); + double normal_dist = (f_left + 4 * f_mid + f_right) / 6; + // Expect the number of samples to be within 3 standard deviations + // (rounded up) of the expected number of samples in the bucket. + EXPECT_NEAR(buckets[n], kN * normal_dist, 3 * sqrt(kN * normal_dist) + 1); + } +} + +} // namespace webrtc diff --git a/webrtc/call/rtc_event_log_unittest.cc b/webrtc/call/rtc_event_log_unittest.cc index eb3c14814c..dd2a2f801c 100644 --- a/webrtc/call/rtc_event_log_unittest.cc +++ b/webrtc/call/rtc_event_log_unittest.cc @@ -17,6 +17,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "webrtc/base/buffer.h" #include "webrtc/base/checks.h" +#include "webrtc/base/random.h" #include "webrtc/base/scoped_ptr.h" #include "webrtc/base/thread.h" #include "webrtc/call.h" @@ -24,7 +25,6 @@ #include "webrtc/modules/rtp_rtcp/source/rtcp_packet.h" #include "webrtc/modules/rtp_rtcp/source/rtp_sender.h" #include "webrtc/system_wrappers/include/clock.h" -#include "webrtc/test/random.h" #include "webrtc/test/test_suite.h" #include "webrtc/test/testsupport/fileutils.h" #include "webrtc/test/testsupport/gtest_disable.h" @@ -301,7 +301,7 @@ size_t GenerateRtpPacket(uint32_t extensions_bitvector, uint32_t csrcs_count, uint8_t* packet, size_t packet_size, - test::Random* prng) { + Random* prng) { RTC_CHECK_GE(packet_size, 16 + 4 * csrcs_count + 4 * kNumExtensions); Clock* clock = Clock::GetRealTimeClock(); @@ -349,7 +349,7 @@ size_t GenerateRtpPacket(uint32_t extensions_bitvector, return header_size; } -rtc::scoped_ptr GenerateRtcpPacket(test::Random* prng) { +rtc::scoped_ptr GenerateRtcpPacket(Random* prng) { rtcp::ReportBlock report_block; report_block.To(prng->Rand()); // Remote SSRC. report_block.WithFractionLost(prng->Rand(50)); @@ -366,7 +366,7 @@ rtc::scoped_ptr GenerateRtcpPacket(test::Random* prng) { void GenerateVideoReceiveConfig(uint32_t extensions_bitvector, VideoReceiveStream::Config* config, - test::Random* prng) { + Random* prng) { // Create a map from a payload type to an encoder name. VideoReceiveStream::Decoder decoder; decoder.payload_type = prng->Rand(0, 127); @@ -395,7 +395,7 @@ void GenerateVideoReceiveConfig(uint32_t extensions_bitvector, void GenerateVideoSendConfig(uint32_t extensions_bitvector, VideoSendStream::Config* config, - test::Random* prng) { + Random* prng) { // Create a map from a payload type to an encoder name. config->encoder_settings.payload_type = prng->Rand(0, 127); config->encoder_settings.payload_name = (prng->Rand() ? "VP8" : "H264"); @@ -434,7 +434,7 @@ void LogSessionAndReadBack(size_t rtp_count, VideoReceiveStream::Config receiver_config(nullptr); VideoSendStream::Config sender_config(nullptr); - test::Random prng(random_seed); + Random prng(random_seed); // Create rtp_count RTP packets containing random data. for (size_t i = 0; i < rtp_count; i++) { @@ -591,7 +591,7 @@ TEST(RtcEventLogTest, LogSessionAndReadBack) { 1 + csrcs_count, // Number of BWE loss events. extensions, // Bit vector choosing extensions. csrcs_count, // Number of contributing sources. - extensions + csrcs_count); // Random seed. + extensions * 3 + csrcs_count + 1); // Random seed. } } } @@ -609,7 +609,7 @@ void DropOldEvents(uint32_t extensions_bitvector, VideoReceiveStream::Config receiver_config(nullptr); VideoSendStream::Config sender_config(nullptr); - test::Random prng(random_seed); + Random prng(random_seed); // Create two RTP packets containing random data. size_t packet_size = prng.Rand(1000, 1100); diff --git a/webrtc/modules/audio_processing/audio_processing_impl_locking_unittest.cc b/webrtc/modules/audio_processing/audio_processing_impl_locking_unittest.cc index 308cf1fd39..cd4b31c2c8 100644 --- a/webrtc/modules/audio_processing/audio_processing_impl_locking_unittest.cc +++ b/webrtc/modules/audio_processing/audio_processing_impl_locking_unittest.cc @@ -18,11 +18,11 @@ #include "webrtc/base/criticalsection.h" #include "webrtc/base/event.h" #include "webrtc/base/platform_thread.h" +#include "webrtc/base/random.h" #include "webrtc/config.h" #include "webrtc/modules/audio_processing/test/test_utils.h" #include "webrtc/modules/include/module_common_types.h" #include "webrtc/system_wrappers/include/sleep.h" -#include "webrtc/test/random.h" namespace webrtc { @@ -84,7 +84,7 @@ class RandomGenerator { private: rtc::CriticalSection crit_; - test::Random rand_gen_ GUARDED_BY(crit_); + Random rand_gen_ GUARDED_BY(crit_); }; // Variables related to the audio data and formats. diff --git a/webrtc/modules/remote_bitrate_estimator/bwe_simulations.cc b/webrtc/modules/remote_bitrate_estimator/bwe_simulations.cc index fb8de7cabc..309ff8d3ff 100644 --- a/webrtc/modules/remote_bitrate_estimator/bwe_simulations.cc +++ b/webrtc/modules/remote_bitrate_estimator/bwe_simulations.cc @@ -36,7 +36,7 @@ class BweSimulation : public BweTest, VerboseLogging(true); } - test::Random random_; + Random random_; private: RTC_DISALLOW_COPY_AND_ASSIGN(BweSimulation); diff --git a/webrtc/modules/remote_bitrate_estimator/overuse_detector_unittest.cc b/webrtc/modules/remote_bitrate_estimator/overuse_detector_unittest.cc index dcad04b5f6..53cffa8fef 100644 --- a/webrtc/modules/remote_bitrate_estimator/overuse_detector_unittest.cc +++ b/webrtc/modules/remote_bitrate_estimator/overuse_detector_unittest.cc @@ -14,6 +14,7 @@ #include "testing/gtest/include/gtest/gtest.h" +#include "webrtc/base/random.h" #include "webrtc/base/scoped_ptr.h" #include "webrtc/common_types.h" #include "webrtc/modules/remote_bitrate_estimator/inter_arrival.h" @@ -21,7 +22,6 @@ #include "webrtc/modules/remote_bitrate_estimator/overuse_estimator.h" #include "webrtc/modules/remote_bitrate_estimator/rate_statistics.h" #include "webrtc/test/field_trial.h" -#include "webrtc/test/random.h" #include "webrtc/test/testsupport/gtest_disable.h" namespace webrtc { @@ -38,7 +38,7 @@ class OveruseDetectorTest : public ::testing::Test { overuse_detector_(), overuse_estimator_(new OveruseEstimator(options_)), inter_arrival_(new InterArrival(5 * 90, kRtpTimestampToMs, true)), - random_(1234) {} + random_(123456789) {} protected: void SetUp() override { @@ -55,9 +55,10 @@ class OveruseDetectorTest : public ::testing::Test { } rtp_timestamp_ += mean_ms * 90; now_ms_ += mean_ms; - receive_time_ms_ = - std::max(receive_time_ms_, - now_ms_ + random_.Gaussian(0, standard_deviation_ms)); + receive_time_ms_ = std::max( + receive_time_ms_, + now_ms_ + static_cast( + random_.Gaussian(0, standard_deviation_ms) + 0.5)); if (kBwOverusing == overuse_detector_->State()) { if (last_overuse + 1 != i) { unique_overuse++; @@ -77,9 +78,10 @@ class OveruseDetectorTest : public ::testing::Test { } rtp_timestamp_ += mean_ms * 90; now_ms_ += mean_ms + drift_per_frame_ms; - receive_time_ms_ = - std::max(receive_time_ms_, - now_ms_ + random_.Gaussian(0, standard_deviation_ms)); + receive_time_ms_ = std::max( + receive_time_ms_, + now_ms_ + static_cast( + random_.Gaussian(0, standard_deviation_ms) + 0.5)); if (kBwOverusing == overuse_detector_->State()) { return i + 1; } @@ -114,7 +116,7 @@ class OveruseDetectorTest : public ::testing::Test { rtc::scoped_ptr overuse_detector_; rtc::scoped_ptr overuse_estimator_; rtc::scoped_ptr inter_arrival_; - test::Random random_; + Random random_; }; TEST_F(OveruseDetectorTest, GaussianRandom) { @@ -222,7 +224,7 @@ TEST_F(OveruseDetectorTest, DISABLED_OveruseWithHighVariance100Kbit10fps) { UpdateDetector(rtp_timestamp, now_ms_, packet_size); rtp_timestamp += frame_duration_ms * 90; if (i % 2) { - offset = rand() % 50; + offset = random_.Rand(0, 49); now_ms_ += frame_duration_ms - offset; } else { now_ms_ += frame_duration_ms + offset; @@ -254,7 +256,7 @@ TEST_F(OveruseDetectorTest, DISABLED_OveruseWithLowVariance100Kbit10fps) { UpdateDetector(rtp_timestamp, now_ms_, packet_size); rtp_timestamp += frame_duration_ms * 90; if (i % 2) { - offset = rand() % 2; + offset = random_.Rand(0, 1); now_ms_ += frame_duration_ms - offset; } else { now_ms_ += frame_duration_ms + offset; @@ -290,7 +292,7 @@ TEST_F(OveruseDetectorTest, OveruseWithLowVariance2000Kbit30fps) { UpdateDetector(rtp_timestamp, now_ms_, packet_size); rtp_timestamp += frame_duration_ms * 90; if (i % 2) { - offset = rand() % 2; + offset = random_.Rand(0, 1); now_ms_ += frame_duration_ms - offset; } else { now_ms_ += frame_duration_ms + offset; @@ -323,10 +325,10 @@ TEST_F(OveruseDetectorTest, int sigma_ms = 3; int unique_overuse = Run100000Samples(packets_per_frame, packet_size, frame_duration_ms, sigma_ms); - EXPECT_EQ(13, unique_overuse); + EXPECT_EQ(1, unique_overuse); int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size, frame_duration_ms, sigma_ms, drift_per_frame_ms); - EXPECT_EQ(14, frames_until_overuse); + EXPECT_EQ(13, frames_until_overuse); } TEST_F(OveruseDetectorTest, LowGaussianVarianceFastDrift30Kbit3fps) { @@ -337,7 +339,7 @@ TEST_F(OveruseDetectorTest, LowGaussianVarianceFastDrift30Kbit3fps) { int sigma_ms = 3; int unique_overuse = Run100000Samples(packets_per_frame, packet_size, frame_duration_ms, sigma_ms); - EXPECT_EQ(13, unique_overuse); + EXPECT_EQ(1, unique_overuse); int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size, frame_duration_ms, sigma_ms, drift_per_frame_ms); EXPECT_EQ(4, frames_until_overuse); @@ -351,10 +353,10 @@ TEST_F(OveruseDetectorTest, HighGaussianVariance30Kbit3fps) { int sigma_ms = 10; int unique_overuse = Run100000Samples(packets_per_frame, packet_size, frame_duration_ms, sigma_ms); - EXPECT_EQ(46, unique_overuse); + EXPECT_EQ(1, unique_overuse); int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size, frame_duration_ms, sigma_ms, drift_per_frame_ms); - EXPECT_EQ(42, frames_until_overuse); + EXPECT_EQ(32, frames_until_overuse); } TEST_F(OveruseDetectorTest, HighGaussianVarianceFastDrift30Kbit3fps) { @@ -365,7 +367,7 @@ TEST_F(OveruseDetectorTest, HighGaussianVarianceFastDrift30Kbit3fps) { int sigma_ms = 10; int unique_overuse = Run100000Samples(packets_per_frame, packet_size, frame_duration_ms, sigma_ms); - EXPECT_EQ(46, unique_overuse); + EXPECT_EQ(1, unique_overuse); int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size, frame_duration_ms, sigma_ms, drift_per_frame_ms); EXPECT_EQ(4, frames_until_overuse); @@ -380,10 +382,10 @@ TEST_F(OveruseDetectorTest, int sigma_ms = 3; int unique_overuse = Run100000Samples(packets_per_frame, packet_size, frame_duration_ms, sigma_ms); - EXPECT_EQ(12, unique_overuse); + EXPECT_EQ(0, unique_overuse); int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size, frame_duration_ms, sigma_ms, drift_per_frame_ms); - EXPECT_EQ(12, frames_until_overuse); + EXPECT_EQ(13, frames_until_overuse); } TEST_F(OveruseDetectorTest, @@ -395,10 +397,10 @@ TEST_F(OveruseDetectorTest, int sigma_ms = 10; int unique_overuse = Run100000Samples(packets_per_frame, packet_size, frame_duration_ms, sigma_ms); - EXPECT_EQ(16, unique_overuse); + EXPECT_EQ(1, unique_overuse); int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size, frame_duration_ms, sigma_ms, drift_per_frame_ms); - EXPECT_EQ(37, frames_until_overuse); + EXPECT_EQ(32, frames_until_overuse); } TEST_F(OveruseDetectorTest, @@ -410,10 +412,10 @@ TEST_F(OveruseDetectorTest, int sigma_ms = 3; int unique_overuse = Run100000Samples(packets_per_frame, packet_size, frame_duration_ms, sigma_ms); - EXPECT_EQ(12, unique_overuse); + EXPECT_EQ(1, unique_overuse); int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size, frame_duration_ms, sigma_ms, drift_per_frame_ms); - EXPECT_EQ(12, frames_until_overuse); + EXPECT_EQ(13, frames_until_overuse); } TEST_F(OveruseDetectorTest, @@ -425,10 +427,10 @@ TEST_F(OveruseDetectorTest, int sigma_ms = 10; int unique_overuse = Run100000Samples(packets_per_frame, packet_size, frame_duration_ms, sigma_ms); - EXPECT_EQ(12, unique_overuse); + EXPECT_EQ(0, unique_overuse); int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size, frame_duration_ms, sigma_ms, drift_per_frame_ms); - EXPECT_EQ(37, frames_until_overuse); + EXPECT_EQ(32, frames_until_overuse); } TEST_F(OveruseDetectorTest, @@ -443,7 +445,7 @@ TEST_F(OveruseDetectorTest, EXPECT_EQ(0, unique_overuse); int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size, frame_duration_ms, sigma_ms, drift_per_frame_ms); - EXPECT_EQ(14, frames_until_overuse); + EXPECT_EQ(15, frames_until_overuse); } TEST_F(OveruseDetectorTest, LowGaussianVarianceFastDrift300Kbit30fps) { @@ -471,7 +473,7 @@ TEST_F(OveruseDetectorTest, HighGaussianVariance300Kbit30fps) { EXPECT_EQ(0, unique_overuse); int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size, frame_duration_ms, sigma_ms, drift_per_frame_ms); - EXPECT_EQ(49, frames_until_overuse); + EXPECT_EQ(41, frames_until_overuse); } TEST_F(OveruseDetectorTest, HighGaussianVarianceFastDrift300Kbit30fps) { @@ -485,7 +487,7 @@ TEST_F(OveruseDetectorTest, HighGaussianVarianceFastDrift300Kbit30fps) { EXPECT_EQ(0, unique_overuse); int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size, frame_duration_ms, sigma_ms, drift_per_frame_ms); - EXPECT_EQ(8, frames_until_overuse); + EXPECT_EQ(10, frames_until_overuse); } TEST_F(OveruseDetectorTest, @@ -500,7 +502,7 @@ TEST_F(OveruseDetectorTest, EXPECT_EQ(0, unique_overuse); int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size, frame_duration_ms, sigma_ms, drift_per_frame_ms); - EXPECT_EQ(14, frames_until_overuse); + EXPECT_EQ(15, frames_until_overuse); } TEST_F(OveruseDetectorTest, LowGaussianVarianceFastDrift1000Kbit30fps) { @@ -528,7 +530,7 @@ TEST_F(OveruseDetectorTest, HighGaussianVariance1000Kbit30fps) { EXPECT_EQ(0, unique_overuse); int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size, frame_duration_ms, sigma_ms, drift_per_frame_ms); - EXPECT_EQ(49, frames_until_overuse); + EXPECT_EQ(41, frames_until_overuse); } TEST_F(OveruseDetectorTest, HighGaussianVarianceFastDrift1000Kbit30fps) { @@ -542,7 +544,7 @@ TEST_F(OveruseDetectorTest, HighGaussianVarianceFastDrift1000Kbit30fps) { EXPECT_EQ(0, unique_overuse); int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size, frame_duration_ms, sigma_ms, drift_per_frame_ms); - EXPECT_EQ(8, frames_until_overuse); + EXPECT_EQ(10, frames_until_overuse); } TEST_F(OveruseDetectorTest, @@ -557,7 +559,7 @@ TEST_F(OveruseDetectorTest, EXPECT_EQ(0, unique_overuse); int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size, frame_duration_ms, sigma_ms, drift_per_frame_ms); - EXPECT_EQ(14, frames_until_overuse); + EXPECT_EQ(15, frames_until_overuse); } TEST_F(OveruseDetectorTest, LowGaussianVarianceFastDrift2000Kbit30fps) { @@ -585,7 +587,7 @@ TEST_F(OveruseDetectorTest, HighGaussianVariance2000Kbit30fps) { EXPECT_EQ(0, unique_overuse); int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size, frame_duration_ms, sigma_ms, drift_per_frame_ms); - EXPECT_EQ(49, frames_until_overuse); + EXPECT_EQ(41, frames_until_overuse); } TEST_F(OveruseDetectorTest, HighGaussianVarianceFastDrift2000Kbit30fps) { @@ -599,7 +601,7 @@ TEST_F(OveruseDetectorTest, HighGaussianVarianceFastDrift2000Kbit30fps) { EXPECT_EQ(0, unique_overuse); int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size, frame_duration_ms, sigma_ms, drift_per_frame_ms); - EXPECT_EQ(8, frames_until_overuse); + EXPECT_EQ(10, frames_until_overuse); } class OveruseDetectorExperimentTest : public OveruseDetectorTest { diff --git a/webrtc/modules/remote_bitrate_estimator/test/bwe_test.cc b/webrtc/modules/remote_bitrate_estimator/test/bwe_test.cc index 2f54cb5b27..9da21c1aaa 100644 --- a/webrtc/modules/remote_bitrate_estimator/test/bwe_test.cc +++ b/webrtc/modules/remote_bitrate_estimator/test/bwe_test.cc @@ -948,7 +948,7 @@ std::vector BweTest::GetFileSizesBytes(int num_files) { const int kMinKbytes = 100; const int kMaxKbytes = 1000; - test::Random random(0x12345678); + Random random(0x12345678); std::vector tcp_file_sizes_bytes; while (num_files-- > 0) { @@ -961,7 +961,7 @@ std::vector BweTest::GetFileSizesBytes(int num_files) { std::vector BweTest::GetStartingTimesMs(int num_files) { // OFF state behaves as an exp. distribution with mean = 10 seconds. const float kMeanMs = 10000.0f; - test::Random random(0x12345678); + Random random(0x12345678); std::vector tcp_starting_times_ms; diff --git a/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.cc b/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.cc index 120f50166f..c3a65c1832 100644 --- a/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.cc +++ b/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.cc @@ -391,7 +391,7 @@ void JitterFilter::SetMaxJitter(int64_t max_jitter_ms) { } namespace { -inline int64_t TruncatedNSigmaGaussian(test::Random* const random, +inline int64_t TruncatedNSigmaGaussian(Random* const random, int64_t mean, int64_t std_dev) { int64_t gaussian_random = random->Gaussian(mean, std_dev); diff --git a/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.h b/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.h index d94ee17951..f7c1d1f0bf 100644 --- a/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.h +++ b/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.h @@ -22,6 +22,7 @@ #include #include "webrtc/base/common.h" +#include "webrtc/base/random.h" #include "webrtc/base/scoped_ptr.h" #include "webrtc/modules/bitrate_controller/include/bitrate_controller.h" #include "webrtc/modules/include/module_common_types.h" @@ -31,7 +32,6 @@ #include "webrtc/modules/remote_bitrate_estimator/test/packet.h" #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" #include "webrtc/system_wrappers/include/clock.h" -#include "webrtc/test/random.h" namespace webrtc { @@ -265,7 +265,7 @@ class LossFilter : public PacketProcessor { virtual void RunFor(int64_t time_ms, Packets* in_out); private: - test::Random random_; + Random random_; float loss_fraction_; RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(LossFilter); @@ -299,7 +299,7 @@ class JitterFilter : public PacketProcessor { int64_t MeanUs(); private: - test::Random random_; + Random random_; int64_t stddev_jitter_us_; int64_t last_send_time_us_; bool reordering_; // False by default. @@ -318,7 +318,7 @@ class ReorderFilter : public PacketProcessor { virtual void RunFor(int64_t time_ms, Packets* in_out); private: - test::Random random_; + Random random_; float reorder_fraction_; RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(ReorderFilter); diff --git a/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework_unittest.cc b/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework_unittest.cc index 627260678b..6bdfa847df 100644 --- a/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework_unittest.cc +++ b/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework_unittest.cc @@ -22,39 +22,6 @@ namespace webrtc { namespace testing { namespace bwe { -TEST(BweTestFramework_RandomTest, Gaussian) { - enum { - kN = 100000, - kBuckets = 100, - kMean = 49, - kStddev = 10 - }; - - test::Random random(0x12345678); - - int buckets[kBuckets] = {0}; - for (int i = 0; i < kN; ++i) { - int index = random.Gaussian(kMean, kStddev); - if (index >= 0 && index < kBuckets) { - buckets[index]++; - } - } - - const double kPi = 3.14159265358979323846; - const double kScale = kN / (kStddev * sqrt(2.0 * kPi)); - const double kDiv = -2.0 * kStddev * kStddev; - double self_corr = 0.0; - double bucket_corr = 0.0; - for (int n = 0; n < kBuckets; ++n) { - double normal_dist = kScale * exp((n - kMean) * (n - kMean) / kDiv); - self_corr += normal_dist * normal_dist; - bucket_corr += normal_dist * buckets[n]; - } - printf("Correlation: %f (random sample), %f (self), %f (quotient)\n", - bucket_corr, self_corr, bucket_corr / self_corr); - EXPECT_NEAR(1.0, bucket_corr / self_corr, 0.0004); -} - static bool IsSequenceNumberSorted(const Packets& packets) { PacketsConstIt last_it = packets.begin(); for (PacketsConstIt it = last_it; it != packets.end(); ++it) { @@ -533,7 +500,7 @@ TEST(BweTestFramework_JitterFilterTest, Jitter1031) { TestJitterFilter(1031); } -static void TestReorderFilter(uint16_t reorder_percent, uint16_t near_value) { +static void TestReorderFilter(uint16_t reorder_percent) { const uint16_t kPacketCount = 10000; // Generate packets with 10 ms interval. @@ -559,16 +526,23 @@ static void TestReorderFilter(uint16_t reorder_percent, uint16_t near_value) { for (auto* packet : packets) { const MediaPacket* media_packet = static_cast(packet); uint16_t sequence_number = media_packet->header().sequenceNumber; + // The expected position for sequence number s is in position s-1. if (sequence_number < last_sequence_number) { distance += last_sequence_number - sequence_number; } last_sequence_number = sequence_number; } - // Because reordering is random, we allow a threshold when comparing. The - // maximum distance a packet can be moved is PacketCount - 1. - EXPECT_NEAR( - ((kPacketCount - 1) * reorder_percent) / 100, distance, near_value); + // The probability that two elements are swapped is p = reorder_percent / 100. + double p = static_cast(reorder_percent) / 100; + // The expected number of swaps we perform is p * (PacketCount - 1), + // and each swap increases the distance by one. + double mean = p * (kPacketCount - 1); + // If pair i is chosen to be swapped with probability p, the variance for that + // pair is p * (1 - p). Since there are (kPacketCount - 1) independent pairs, + // the variance for the number of swaps is (kPacketCount - 1) * p * (1 - p). + double std_deviation = sqrt((kPacketCount - 1) * p * (1 - p)); + EXPECT_NEAR(mean, distance, 3 * std_deviation); for (auto* packet : packets) delete packet; @@ -576,23 +550,23 @@ static void TestReorderFilter(uint16_t reorder_percent, uint16_t near_value) { TEST(BweTestFramework_ReorderFilterTest, Reorder0) { // For 0% reordering, no packets should have been moved, so result is exact. - TestReorderFilter(0, 0); + TestReorderFilter(0); } TEST(BweTestFramework_ReorderFilterTest, Reorder10) { - TestReorderFilter(10, 30); + TestReorderFilter(10); } TEST(BweTestFramework_ReorderFilterTest, Reorder20) { - TestReorderFilter(20, 20); + TestReorderFilter(20); } TEST(BweTestFramework_ReorderFilterTest, Reorder50) { - TestReorderFilter(50, 20); + TestReorderFilter(50); } TEST(BweTestFramework_ReorderFilterTest, Reorder70) { - TestReorderFilter(70, 20); + TestReorderFilter(70); } TEST(BweTestFramework_ReorderFilterTest, Reorder100) { @@ -600,7 +574,7 @@ TEST(BweTestFramework_ReorderFilterTest, Reorder100) { // adjacent packets, when the likelihood of a swap is 1.0, a swap will always // occur, so the stream will be in order except for the first packet, which // has been moved to the end. Therefore we expect the result to be exact here. - TestReorderFilter(100.0, 0); + TestReorderFilter(100.0); } class BweTestFramework_ChokeFilterTest : public ::testing::Test { diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet/report_block_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_packet/report_block_unittest.cc index fcde0e4c17..85bbb404a4 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_packet/report_block_unittest.cc +++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet/report_block_unittest.cc @@ -13,7 +13,7 @@ #include #include "testing/gtest/include/gtest/gtest.h" -#include "webrtc/test/random.h" +#include "webrtc/base/random.h" using webrtc::rtcp::ReportBlock; @@ -42,7 +42,7 @@ TEST(RtcpPacketReportBlockTest, ParseChecksLength) { TEST(RtcpPacketReportBlockTest, ParseAnyData) { uint8_t buffer[kBufferLength]; // Fill buffer with semi-random data. - test::Random generator(testing::FLAGS_gtest_random_seed); + Random generator(0x256F8A285EC829ull); for (size_t i = 0; i < kBufferLength; ++i) buffer[i] = static_cast(generator.Rand(0, 0xff)); diff --git a/webrtc/test/random.cc b/webrtc/test/random.cc deleted file mode 100644 index 0a82b8d72d..0000000000 --- a/webrtc/test/random.cc +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/test/random.h" - -#include - -#include "webrtc/base/checks.h" - -namespace webrtc { - -namespace test { - -Random::Random(uint32_t seed) : a_(0x531FDB97 ^ seed), b_(0x6420ECA8 + seed) { -} - -uint32_t Random::Rand(uint32_t t) { - // If b / 2^32 is uniform on [0,1), then b / 2^32 * (t+1) is uniform on - // the interval [0,t+1), so the integer part is uniform on [0,t]. - uint64_t result = b_ * (static_cast(t) + 1); - result >>= 32; - a_ ^= b_; - b_ += a_; - return result; -} - -uint32_t Random::Rand(uint32_t low, uint32_t high) { - RTC_DCHECK(low <= high); - return Rand(high - low) + low; -} - -template <> -float Random::Rand() { - const double kScale = 1.0f / (static_cast(1) << 32); - double result = kScale * b_; - a_ ^= b_; - b_ += a_; - return static_cast(result); -} - -template <> -bool Random::Rand() { - return Rand(0, 1) == 1; -} - -int Random::Gaussian(int mean, int standard_deviation) { - // Creating a Normal distribution variable from two independent uniform - // variables based on the Box-Muller transform, which is defined on the - // interval (0, 1], hence the mask+add below. - const double kPi = 3.14159265358979323846; - const double kScale = 1.0 / 0x80000000ul; - double u1 = kScale * ((a_ & 0x7ffffffful) + 1); - double u2 = kScale * ((b_ & 0x7ffffffful) + 1); - a_ ^= b_; - b_ += a_; - return static_cast( - mean + standard_deviation * sqrt(-2 * log(u1)) * cos(2 * kPi * u2)); -} - -int Random::Exponential(float lambda) { - float uniform = Rand(); - return static_cast(-log(uniform) / lambda); -} -} // namespace test -} // namespace webrtc diff --git a/webrtc/test/webrtc_test_common.gyp b/webrtc/test/webrtc_test_common.gyp index 8716c9b3e8..928ef6b165 100644 --- a/webrtc/test/webrtc_test_common.gyp +++ b/webrtc/test/webrtc_test_common.gyp @@ -41,8 +41,6 @@ 'mock_voice_engine.h', 'null_transport.cc', 'null_transport.h', - 'random.cc', - 'random.h', 'rtp_rtcp_observer.h', 'run_loop.cc', 'run_loop.h', diff --git a/webrtc/voice_engine/test/auto_test/voe_output_test.cc b/webrtc/voice_engine/test/auto_test/voe_output_test.cc index 716a1a8d7d..3bedbc3b17 100644 --- a/webrtc/voice_engine/test/auto_test/voe_output_test.cc +++ b/webrtc/voice_engine/test/auto_test/voe_output_test.cc @@ -9,11 +9,11 @@ */ #include "testing/gtest/include/gtest/gtest.h" +#include "webrtc/base/random.h" #include "webrtc/base/scoped_ptr.h" #include "webrtc/base/timeutils.h" #include "webrtc/system_wrappers/include/sleep.h" #include "webrtc/test/channel_transport/channel_transport.h" -#include "webrtc/test/random.h" #include "webrtc/test/testsupport/fileutils.h" #include "webrtc/voice_engine/test/auto_test/voe_standard_test.h" @@ -27,7 +27,7 @@ const webrtc::CodecInst kCodecInst = {120, "opus", 48000, 960, 2, 64000}; namespace voetest { -using webrtc::test::Random; +using webrtc::Random; using webrtc::test::VoiceChannelTransport; // This test allows a check on the output signal in an end-to-end call.