Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(87)

Side by Side Diff: remoting/codec/audio_encoder_opus_unittest.cc

Issue 11189047: Add opus audio codec support in remoting (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698