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 |