diff options
Diffstat (limited to 'chromium/third_party/webrtc/modules/audio_coding/neteq/dtmf_tone_generator_unittest.cc')
-rw-r--r-- | chromium/third_party/webrtc/modules/audio_coding/neteq/dtmf_tone_generator_unittest.cc | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/chromium/third_party/webrtc/modules/audio_coding/neteq/dtmf_tone_generator_unittest.cc b/chromium/third_party/webrtc/modules/audio_coding/neteq/dtmf_tone_generator_unittest.cc new file mode 100644 index 00000000000..94f79dc3456 --- /dev/null +++ b/chromium/third_party/webrtc/modules/audio_coding/neteq/dtmf_tone_generator_unittest.cc @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2012 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. + */ + +// Unit tests for DtmfToneGenerator class. + +#include "webrtc/modules/audio_coding/neteq/dtmf_tone_generator.h" + +#include <math.h> + +#include "gtest/gtest.h" +#include "webrtc/modules/audio_coding/neteq/audio_multi_vector.h" + +namespace webrtc { + +TEST(DtmfToneGenerator, CreateAndDestroy) { + DtmfToneGenerator* tone_gen = new DtmfToneGenerator(); + delete tone_gen; +} + +TEST(DtmfToneGenerator, TestErrors) { + DtmfToneGenerator tone_gen; + const int kNumSamples = 10; + AudioMultiVector signal(1); // One channel. + + // Try to generate tones without initializing. + EXPECT_EQ(DtmfToneGenerator::kNotInitialized, + tone_gen.Generate(kNumSamples, &signal)); + + const int fs = 16000; // Valid sample rate. + const int event = 7; // Valid event. + const int attenuation = 0; // Valid attenuation. + // Initialize with invalid event -1. + EXPECT_EQ(DtmfToneGenerator::kParameterError, + tone_gen.Init(fs, -1, attenuation)); + // Initialize with invalid event 16. + EXPECT_EQ(DtmfToneGenerator::kParameterError, + tone_gen.Init(fs, 16, attenuation)); + // Initialize with invalid attenuation -1. + EXPECT_EQ(DtmfToneGenerator::kParameterError, tone_gen.Init(fs, event, -1)); + // Initialize with invalid attenuation 37. + EXPECT_EQ(DtmfToneGenerator::kParameterError, tone_gen.Init(fs, event, 37)); + EXPECT_FALSE(tone_gen.initialized()); // Should still be uninitialized. + + // Initialize with valid parameters. + ASSERT_EQ(0, tone_gen.Init(fs, event, attenuation)); + EXPECT_TRUE(tone_gen.initialized()); + // Negative number of samples. + EXPECT_EQ(DtmfToneGenerator::kParameterError, tone_gen.Generate(-1, &signal)); + // NULL pointer to destination. + EXPECT_EQ(DtmfToneGenerator::kParameterError, + tone_gen.Generate(kNumSamples, NULL)); +} + +TEST(DtmfToneGenerator, TestTones) { + DtmfToneGenerator tone_gen; + const int kAttenuation = 0; + const int kNumSamples = 10; + AudioMultiVector signal(1); // One channel. + + // Low and high frequencies for events 0 through 15. + const double low_freq_hz[] = { 941.0, 697.0, 697.0, 697.0, 770.0, 770.0, + 770.0, 852.0, 852.0, 852.0, 941.0, 941.0, 697.0, 770.0, 852.0, 941.0 }; + const double hi_freq_hz[] = { 1336.0, 1209.0, 1336.0, 1477.0, 1209.0, 1336.0, + 1477.0, 1209.0, 1336.0, 1477.0, 1209.0, 1477.0, 1633.0, 1633.0, 1633.0, + 1633.0 }; + const double attenuate_3dB = 23171.0 / 32768; // 3 dB attenuation. + const double base_attenuation = 16141.0 / 16384.0; // This is the attenuation + // applied to all cases. + const int fs_vec[] = { 8000, 16000, 32000, 48000 }; + for (int f = 0; f < 4; ++f) { + int fs = fs_vec[f]; + for (int event = 0; event <= 15; ++event) { + std::ostringstream ss; + ss << "Checking event " << event << " at sample rate " << fs; + SCOPED_TRACE(ss.str()); + ASSERT_EQ(0, tone_gen.Init(fs, event, kAttenuation)); + EXPECT_TRUE(tone_gen.initialized()); + EXPECT_EQ(kNumSamples, tone_gen.Generate(kNumSamples, &signal)); + + double f1 = low_freq_hz[event]; + double f2 = hi_freq_hz[event]; + const double pi = 3.14159265358979323846; + + for (int n = 0; n < kNumSamples; ++n) { + double x = attenuate_3dB * sin(2.0 * pi * f1 / fs * (-n - 1)) + + sin(2.0 * pi * f2 / fs * (-n - 1)); + x *= base_attenuation; + x = ldexp(x, 14); // Scale to Q14. + static const int kChannel = 0; + EXPECT_NEAR(x, static_cast<double>(signal[kChannel][n]), 25); + } + + tone_gen.Reset(); + EXPECT_FALSE(tone_gen.initialized()); + } + } +} + +TEST(DtmfToneGenerator, TestAmplitudes) { + DtmfToneGenerator tone_gen; + const int kNumSamples = 10; + AudioMultiVector signal(1); // One channel. + AudioMultiVector ref_signal(1); // One channel. + + const int fs_vec[] = { 8000, 16000, 32000, 48000 }; + const int event_vec[] = { 0, 4, 9, 13 }; // Test a few events. + for (int f = 0; f < 4; ++f) { + int fs = fs_vec[f]; + int event = event_vec[f]; + // Create full-scale reference. + ASSERT_EQ(0, tone_gen.Init(fs, event, 0)); // 0 attenuation. + EXPECT_EQ(kNumSamples, tone_gen.Generate(kNumSamples, &ref_signal)); + // Test every 5 steps (to save time). + for (int attenuation = 1; attenuation <= 36; attenuation += 5) { + std::ostringstream ss; + ss << "Checking event " << event << " at sample rate " << fs; + ss << "; attenuation " << attenuation; + SCOPED_TRACE(ss.str()); + ASSERT_EQ(0, tone_gen.Init(fs, event, attenuation)); + EXPECT_EQ(kNumSamples, tone_gen.Generate(kNumSamples, &signal)); + for (int n = 0; n < kNumSamples; ++n) { + double attenuation_factor = + pow(10, -static_cast<double>(attenuation)/20); + // Verify that the attenuation is correct. + static const int kChannel = 0; + EXPECT_NEAR(attenuation_factor * ref_signal[kChannel][n], + signal[kChannel][n], 2); + } + + tone_gen.Reset(); + } + } +} + +} // namespace webrtc |