Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 // MSVC++ requires this to get M_PI. | |
| 6 #define _USE_MATH_DEFINES | |
| 7 #include <math.h> | |
| 8 | |
| 9 #include "remoting/codec/audio_encoder_opus.h" | |
| 10 | |
| 11 #include "base/logging.h" | |
| 12 #include "remoting/codec/audio_decoder_opus.h" | |
| 13 #include "testing/gtest/include/gtest/gtest.h" | |
| 14 | |
| 15 namespace remoting { | |
| 16 | |
| 17 namespace { | |
| 18 | |
| 19 const int kChannels = 2; | |
| 20 const double kChannelPhaseShift = 2 * M_PI / 3; | |
|
Wez
2012/10/22 22:50:21
nit: Add comments explaining what this is used for
Sergey Ulanov
2012/10/23 00:43:50
Done.
| |
| 21 const AudioPacket_SamplingRate kDefaultSamplingRate = | |
| 22 AudioPacket::SAMPLING_RATE_48000; | |
| 23 const int kMaxLatencyMs = 40; | |
| 24 | |
| 25 // When verifying results ignore the first 1k samples. This is necessary because | |
| 26 // it takes some time for the codec to adjust for the input signal. | |
| 27 const int kSkippedFirstSamples = 1000; | |
| 28 | |
| 29 } // namespace | |
| 30 | |
| 31 class OpusAudioEncoderTest : public testing::Test { | |
| 32 public: | |
| 33 | |
| 34 static int16 GetSampleValue( | |
| 35 AudioPacket::SamplingRate rate, | |
| 36 double frequency, | |
|
Wez
2012/10/22 22:50:21
nit: Specify units.
Sergey Ulanov
2012/10/23 00:43:50
Done.
| |
| 37 double pos, | |
|
Wez
2012/10/22 22:50:21
nit: How can we have sub-sample position?
Sergey Ulanov
2012/10/23 00:43:50
That's used when comparing results - GetSignalShif
| |
| 38 int channel) { | |
| 39 double angle = pos * 2 * M_PI * frequency / rate + | |
| 40 kChannelPhaseShift * channel; | |
| 41 return static_cast<int>(sin(angle) * 32767 + 0.5); | |
| 42 } | |
| 43 | |
| 44 scoped_ptr<AudioPacket> CreatePacket( | |
| 45 int samples, | |
| 46 AudioPacket::SamplingRate rate, | |
| 47 double frequency, | |
| 48 int pos) { | |
| 49 | |
| 50 std::vector<int16> data(samples * kChannels); | |
|
Wez
2012/10/22 22:50:21
nit: Add a comment to explain that we're filling t
Sergey Ulanov
2012/10/23 00:43:50
Done.
| |
| 51 for (int i = 0; i < samples; ++i) { | |
| 52 data[i * kChannels] = GetSampleValue(rate, frequency, i + pos, 0); | |
| 53 data[i * kChannels + 1] = GetSampleValue(rate, frequency, i + pos, 1); | |
| 54 } | |
| 55 | |
| 56 scoped_ptr<AudioPacket> packet(new AudioPacket()); | |
| 57 packet->add_data(reinterpret_cast<char*>(&(data[0])), | |
| 58 samples * kChannels * sizeof(int16)); | |
| 59 packet->set_encoding(AudioPacket::ENCODING_RAW); | |
| 60 packet->set_sampling_rate(rate); | |
| 61 packet->set_bytes_per_sample(AudioPacket::BYTES_PER_SAMPLE_2); | |
| 62 packet->set_channels(AudioPacket::CHANNELS_STEREO); | |
| 63 return packet.Pass(); | |
| 64 } | |
| 65 | |
| 66 // Decoded data is normally shifted in phase relative to the raw date. This | |
|
Wez
2012/10/22 22:50:21
typo: date -> data
Sergey Ulanov
2012/10/23 00:43:50
Done.
| |
| 67 // function returns approximate the phase difference by finding the first | |
|
Wez
2012/10/22 22:50:21
typo: approximate the phase ... -> ... the approxi
Sergey Ulanov
2012/10/23 00:43:50
Done.
| |
| 68 // point when signal goes from negative to positive. | |
| 69 double GetSignalShift(const std::vector<int16>& received_data) { | |
|
Wez
2012/10/22 22:50:21
nit: So this function is supposed to be getting th
Sergey Ulanov
2012/10/23 00:43:50
Renamed to EstimateSignalShift(). I don't think it
| |
| 70 for (size_t i = kSkippedFirstSamples; | |
| 71 i < received_data.size() / kChannels - 1; i++) { | |
| 72 int16 this_sample = received_data[i * kChannels]; | |
| 73 int16 next_sample = received_data[(i + 1) * kChannels]; | |
| 74 if (this_sample < 0 && next_sample > 0) { | |
| 75 return i + | |
| 76 static_cast<double>(-this_sample) / (next_sample - this_sample); | |
| 77 } | |
| 78 } | |
| 79 return 0; | |
| 80 } | |
| 81 | |
| 82 void ValidateReceivedData(int samples, | |
| 83 AudioPacket::SamplingRate rate, | |
| 84 double frequency, | |
| 85 const std::vector<int16>& received_data) { | |
|
Wez
2012/10/22 22:50:21
nit: Add a comment explaining that we validate the
Sergey Ulanov
2012/10/23 00:43:50
Done.
| |
| 86 double shift = GetSignalShift(received_data); | |
| 87 double diff_sqare_sum = 0; | |
| 88 for (size_t i = kSkippedFirstSamples; | |
| 89 i < received_data.size() / kChannels; i++) { | |
| 90 double d = received_data[i * kChannels] - | |
| 91 GetSampleValue(rate, frequency, i - shift, 0); | |
| 92 diff_sqare_sum += d * d; | |
| 93 d = received_data[i * kChannels + 1] - | |
| 94 GetSampleValue(rate, frequency, i - shift, 1); | |
| 95 diff_sqare_sum += d * d; | |
| 96 } | |
| 97 double averate_difference = sqrt(diff_sqare_sum / received_data.size()); | |
|
Wez
2012/10/22 22:50:21
typo: average_difference
Wez
2012/10/22 22:50:21
nit: Clarify the units you're using for the differ
Sergey Ulanov
2012/10/23 00:43:50
Done.
Sergey Ulanov
2012/10/23 00:43:50
Done.
| |
| 98 EXPECT_LE(averate_difference, 5000); | |
|
Wez
2012/10/22 22:50:21
nit: Consider moving 5000 to a constant, above
Sergey Ulanov
2012/10/23 00:43:50
Done.
| |
| 99 } | |
| 100 | |
| 101 void ResetEncoder() { | |
|
Wez
2012/10/22 22:50:21
nit: ResetEncoder -> Reset or ResetEncoderAndDecod
Sergey Ulanov
2012/10/23 00:43:50
Removed this function.
| |
| 102 encoder_.reset(new AudioEncoderOpus()); | |
| 103 decoder_.reset(new AudioDecoderOpus()); | |
| 104 } | |
| 105 | |
| 106 void TestEncoderDecoder(int packet_size, | |
|
Wez
2012/10/22 22:50:21
typo: TestEncodeDecode
Sergey Ulanov
2012/10/23 00:43:50
Done.
| |
| 107 double frequency, | |
| 108 AudioPacket::SamplingRate rate) { | |
| 109 const int kTotalTestSamples = 24000; | |
| 110 ResetEncoder(); | |
| 111 | |
| 112 std::vector<int16> received_data; | |
| 113 int pos = 0; | |
| 114 for (; pos < kTotalTestSamples; pos += packet_size) { | |
| 115 scoped_ptr<AudioPacket> source_packet = | |
| 116 CreatePacket(packet_size, rate, frequency, pos); | |
| 117 scoped_ptr<AudioPacket> encoded = encoder_->Encode(source_packet.Pass()) ; | |
|
Wez
2012/10/22 22:50:21
Line too long?
Sergey Ulanov
2012/10/23 00:43:50
Done.
| |
| 118 if (encoded.get()) { | |
|
Wez
2012/10/22 22:50:21
EXPECT(encoded.get())?
Sergey Ulanov
2012/10/23 00:43:50
Encoder is allowed to return NULL packet sometimes
| |
| 119 scoped_ptr<AudioPacket> decoded = decoder_->Decode(encoded.Pass()); | |
| 120 EXPECT_EQ(kDefaultSamplingRate, decoded->sampling_rate()); | |
| 121 for (int i = 0; i < decoded->data_size(); ++i) { | |
| 122 const int16* data = | |
| 123 reinterpret_cast<const int16*>(decoded->data(i).data()); | |
| 124 received_data.insert( | |
| 125 received_data.end(), data, | |
| 126 data + decoded->data(i).size() / sizeof(int16)); | |
| 127 } | |
| 128 } | |
| 129 } | |
| 130 | |
| 131 // Verify that at most kMaxLatencyMs worth of samples is buffered inside | |
| 132 // |encoder_| and |decoder_|. | |
| 133 EXPECT_GE(static_cast<int>(received_data.size()) / kChannels, | |
| 134 pos - rate * kMaxLatencyMs / 1000); | |
| 135 | |
| 136 ValidateReceivedData(packet_size, kDefaultSamplingRate, | |
| 137 frequency, received_data); | |
| 138 } | |
| 139 | |
| 140 protected: | |
| 141 scoped_ptr<AudioEncoderOpus> encoder_; | |
| 142 scoped_ptr<AudioDecoderOpus> decoder_; | |
| 143 }; | |
| 144 | |
| 145 TEST_F(OpusAudioEncoderTest, CreateAndDestroy) { | |
| 146 } | |
| 147 | |
| 148 TEST_F(OpusAudioEncoderTest, NoResampling) { | |
| 149 TestEncoderDecoder(2000, 50, AudioPacket::SAMPLING_RATE_48000); | |
| 150 TestEncoderDecoder(2000, 3000, AudioPacket::SAMPLING_RATE_48000); | |
| 151 TestEncoderDecoder(2000, 10000, AudioPacket::SAMPLING_RATE_48000); | |
| 152 } | |
| 153 | |
| 154 TEST_F(OpusAudioEncoderTest, Resampling) { | |
| 155 TestEncoderDecoder(2000, 50, AudioPacket::SAMPLING_RATE_44100); | |
| 156 TestEncoderDecoder(2000, 3000, AudioPacket::SAMPLING_RATE_44100); | |
| 157 TestEncoderDecoder(2000, 10000, AudioPacket::SAMPLING_RATE_44100); | |
| 158 } | |
| 159 | |
| 160 TEST_F(OpusAudioEncoderTest, BufferSize) { | |
|
Wez
2012/10/22 22:50:21
nit: BufferingAndResampling / BufferSizeAndResampl
Sergey Ulanov
2012/10/23 00:43:50
Done.
| |
| 161 TestEncoderDecoder(500, 3000, AudioPacket::SAMPLING_RATE_44100); | |
| 162 TestEncoderDecoder(1000, 3000, AudioPacket::SAMPLING_RATE_44100); | |
| 163 TestEncoderDecoder(5000, 3000, AudioPacket::SAMPLING_RATE_44100); | |
|
Wez
2012/10/22 22:50:21
How long to these tests take?
Sergey Ulanov
2012/10/23 00:43:50
About 0.6 seconds total for all tests in this file
| |
| 164 } | |
| 165 | |
| 166 } // namespace remoting | |
| OLD | NEW |