OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // MSVC++ requires this to get M_PI. | 5 // MSVC++ requires this to get M_PI. |
6 #define _USE_MATH_DEFINES | 6 #define _USE_MATH_DEFINES |
7 #include <math.h> | 7 #include <math.h> |
| 8 #include <stddef.h> |
| 9 #include <stdint.h> |
8 | 10 |
9 #include "remoting/codec/audio_encoder_opus.h" | 11 #include "remoting/codec/audio_encoder_opus.h" |
10 | 12 |
11 #include "base/logging.h" | 13 #include "base/logging.h" |
12 #include "remoting/codec/audio_decoder_opus.h" | 14 #include "remoting/codec/audio_decoder_opus.h" |
13 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
14 | 16 |
15 namespace remoting { | 17 namespace remoting { |
16 | 18 |
17 namespace { | 19 namespace { |
(...skipping 26 matching lines...) Expand all Loading... |
44 const double kMaxSignalDeviation = 0.1; | 46 const double kMaxSignalDeviation = 0.1; |
45 | 47 |
46 } // namespace | 48 } // namespace |
47 | 49 |
48 class OpusAudioEncoderTest : public testing::Test { | 50 class OpusAudioEncoderTest : public testing::Test { |
49 public: | 51 public: |
50 // Return test signal value at the specified position |pos|. |frequency_hz| | 52 // Return test signal value at the specified position |pos|. |frequency_hz| |
51 // defines frequency of the signal. |channel| is used to calculate phase shift | 53 // defines frequency of the signal. |channel| is used to calculate phase shift |
52 // of the signal, so that different signals are generated for left and right | 54 // of the signal, so that different signals are generated for left and right |
53 // channels. | 55 // channels. |
54 static int16 GetSampleValue( | 56 static int16_t GetSampleValue(AudioPacket::SamplingRate rate, |
55 AudioPacket::SamplingRate rate, | 57 double frequency_hz, |
56 double frequency_hz, | 58 double pos, |
57 double pos, | 59 int channel) { |
58 int channel) { | |
59 double angle = pos * 2 * M_PI * frequency_hz / rate + | 60 double angle = pos * 2 * M_PI * frequency_hz / rate + |
60 kChannelPhaseShift * channel; | 61 kChannelPhaseShift * channel; |
61 return static_cast<int>(sin(angle) * kMaxSampleValue + 0.5); | 62 return static_cast<int>(sin(angle) * kMaxSampleValue + 0.5); |
62 } | 63 } |
63 | 64 |
64 // Creates audio packet filled with a test signal with the specified | 65 // Creates audio packet filled with a test signal with the specified |
65 // |frequency_hz|. | 66 // |frequency_hz|. |
66 scoped_ptr<AudioPacket> CreatePacket( | 67 scoped_ptr<AudioPacket> CreatePacket( |
67 int samples, | 68 int samples, |
68 AudioPacket::SamplingRate rate, | 69 AudioPacket::SamplingRate rate, |
69 double frequency_hz, | 70 double frequency_hz, |
70 int pos) { | 71 int pos) { |
71 std::vector<int16> data(samples * kChannels); | 72 std::vector<int16_t> data(samples * kChannels); |
72 for (int i = 0; i < samples; ++i) { | 73 for (int i = 0; i < samples; ++i) { |
73 data[i * kChannels] = GetSampleValue(rate, frequency_hz, i + pos, 0); | 74 data[i * kChannels] = GetSampleValue(rate, frequency_hz, i + pos, 0); |
74 data[i * kChannels + 1] = GetSampleValue(rate, frequency_hz, i + pos, 1); | 75 data[i * kChannels + 1] = GetSampleValue(rate, frequency_hz, i + pos, 1); |
75 } | 76 } |
76 | 77 |
77 scoped_ptr<AudioPacket> packet(new AudioPacket()); | 78 scoped_ptr<AudioPacket> packet(new AudioPacket()); |
78 packet->add_data(reinterpret_cast<char*>(&(data[0])), | 79 packet->add_data(reinterpret_cast<char*>(&(data[0])), |
79 samples * kChannels * sizeof(int16)); | 80 samples * kChannels * sizeof(int16_t)); |
80 packet->set_encoding(AudioPacket::ENCODING_RAW); | 81 packet->set_encoding(AudioPacket::ENCODING_RAW); |
81 packet->set_sampling_rate(rate); | 82 packet->set_sampling_rate(rate); |
82 packet->set_bytes_per_sample(AudioPacket::BYTES_PER_SAMPLE_2); | 83 packet->set_bytes_per_sample(AudioPacket::BYTES_PER_SAMPLE_2); |
83 packet->set_channels(AudioPacket::CHANNELS_STEREO); | 84 packet->set_channels(AudioPacket::CHANNELS_STEREO); |
84 return packet.Pass(); | 85 return packet.Pass(); |
85 } | 86 } |
86 | 87 |
87 // Decoded data is normally shifted in phase relative to the original signal. | 88 // Decoded data is normally shifted in phase relative to the original signal. |
88 // This function returns the approximate shift in samples by finding the first | 89 // This function returns the approximate shift in samples by finding the first |
89 // point when signal goes from negative to positive. | 90 // point when signal goes from negative to positive. |
90 double EstimateSignalShift(const std::vector<int16>& received_data) { | 91 double EstimateSignalShift(const std::vector<int16_t>& received_data) { |
91 for (size_t i = kSkippedFirstSamples; | 92 for (size_t i = kSkippedFirstSamples; |
92 i < received_data.size() / kChannels - 1; i++) { | 93 i < received_data.size() / kChannels - 1; i++) { |
93 int16 this_sample = received_data[i * kChannels]; | 94 int16_t this_sample = received_data[i * kChannels]; |
94 int16 next_sample = received_data[(i + 1) * kChannels]; | 95 int16_t next_sample = received_data[(i + 1) * kChannels]; |
95 if (this_sample < 0 && next_sample > 0) { | 96 if (this_sample < 0 && next_sample > 0) { |
96 return | 97 return |
97 i + static_cast<double>(-this_sample) / (next_sample - this_sample); | 98 i + static_cast<double>(-this_sample) / (next_sample - this_sample); |
98 } | 99 } |
99 } | 100 } |
100 return 0; | 101 return 0; |
101 } | 102 } |
102 | 103 |
103 // Compares decoded signal with the test signal that was encoded. It estimates | 104 // Compares decoded signal with the test signal that was encoded. It estimates |
104 // phase shift from the original signal, then calculates standard deviation of | 105 // phase shift from the original signal, then calculates standard deviation of |
105 // the difference between original and decoded signals. | 106 // the difference between original and decoded signals. |
106 void ValidateReceivedData(int samples, | 107 void ValidateReceivedData(int samples, |
107 AudioPacket::SamplingRate rate, | 108 AudioPacket::SamplingRate rate, |
108 double frequency_hz, | 109 double frequency_hz, |
109 const std::vector<int16>& received_data) { | 110 const std::vector<int16_t>& received_data) { |
110 double shift = EstimateSignalShift(received_data); | 111 double shift = EstimateSignalShift(received_data); |
111 double diff_sqare_sum = 0; | 112 double diff_sqare_sum = 0; |
112 for (size_t i = kSkippedFirstSamples; | 113 for (size_t i = kSkippedFirstSamples; |
113 i < received_data.size() / kChannels; i++) { | 114 i < received_data.size() / kChannels; i++) { |
114 double d = received_data[i * kChannels] - | 115 double d = received_data[i * kChannels] - |
115 GetSampleValue(rate, frequency_hz, i - shift, 0); | 116 GetSampleValue(rate, frequency_hz, i - shift, 0); |
116 diff_sqare_sum += d * d; | 117 diff_sqare_sum += d * d; |
117 d = received_data[i * kChannels + 1] - | 118 d = received_data[i * kChannels + 1] - |
118 GetSampleValue(rate, frequency_hz, i - shift, 1); | 119 GetSampleValue(rate, frequency_hz, i - shift, 1); |
119 diff_sqare_sum += d * d; | 120 diff_sqare_sum += d * d; |
120 } | 121 } |
121 double deviation = sqrt(diff_sqare_sum / received_data.size()) | 122 double deviation = sqrt(diff_sqare_sum / received_data.size()) |
122 / kMaxSampleValue; | 123 / kMaxSampleValue; |
123 LOG(ERROR) << "Decoded signal deviation: " << deviation; | 124 LOG(ERROR) << "Decoded signal deviation: " << deviation; |
124 EXPECT_LE(deviation, kMaxSignalDeviation); | 125 EXPECT_LE(deviation, kMaxSignalDeviation); |
125 } | 126 } |
126 | 127 |
127 void TestEncodeDecode(int packet_size, | 128 void TestEncodeDecode(int packet_size, |
128 double frequency_hz, | 129 double frequency_hz, |
129 AudioPacket::SamplingRate rate) { | 130 AudioPacket::SamplingRate rate) { |
130 const int kTotalTestSamples = 24000; | 131 const int kTotalTestSamples = 24000; |
131 | 132 |
132 encoder_.reset(new AudioEncoderOpus()); | 133 encoder_.reset(new AudioEncoderOpus()); |
133 decoder_.reset(new AudioDecoderOpus()); | 134 decoder_.reset(new AudioDecoderOpus()); |
134 | 135 |
135 std::vector<int16> received_data; | 136 std::vector<int16_t> received_data; |
136 int pos = 0; | 137 int pos = 0; |
137 for (; pos < kTotalTestSamples; pos += packet_size) { | 138 for (; pos < kTotalTestSamples; pos += packet_size) { |
138 scoped_ptr<AudioPacket> source_packet = | 139 scoped_ptr<AudioPacket> source_packet = |
139 CreatePacket(packet_size, rate, frequency_hz, pos); | 140 CreatePacket(packet_size, rate, frequency_hz, pos); |
140 scoped_ptr<AudioPacket> encoded = | 141 scoped_ptr<AudioPacket> encoded = |
141 encoder_->Encode(source_packet.Pass()); | 142 encoder_->Encode(source_packet.Pass()); |
142 if (encoded.get()) { | 143 if (encoded.get()) { |
143 scoped_ptr<AudioPacket> decoded = decoder_->Decode(encoded.Pass()); | 144 scoped_ptr<AudioPacket> decoded = decoder_->Decode(encoded.Pass()); |
144 EXPECT_EQ(kDefaultSamplingRate, decoded->sampling_rate()); | 145 EXPECT_EQ(kDefaultSamplingRate, decoded->sampling_rate()); |
145 for (int i = 0; i < decoded->data_size(); ++i) { | 146 for (int i = 0; i < decoded->data_size(); ++i) { |
146 const int16* data = | 147 const int16_t* data = |
147 reinterpret_cast<const int16*>(decoded->data(i).data()); | 148 reinterpret_cast<const int16_t*>(decoded->data(i).data()); |
148 received_data.insert( | 149 received_data.insert( |
149 received_data.end(), data, | 150 received_data.end(), data, |
150 data + decoded->data(i).size() / sizeof(int16)); | 151 data + decoded->data(i).size() / sizeof(int16_t)); |
151 } | 152 } |
152 } | 153 } |
153 } | 154 } |
154 | 155 |
155 // Verify that at most kMaxLatencyMs worth of samples is buffered inside | 156 // Verify that at most kMaxLatencyMs worth of samples is buffered inside |
156 // |encoder_| and |decoder_|. | 157 // |encoder_| and |decoder_|. |
157 EXPECT_GE(static_cast<int>(received_data.size()) / kChannels, | 158 EXPECT_GE(static_cast<int>(received_data.size()) / kChannels, |
158 pos - rate * kMaxLatencyMs / 1000); | 159 pos - rate * kMaxLatencyMs / 1000); |
159 | 160 |
160 ValidateReceivedData(packet_size, kDefaultSamplingRate, | 161 ValidateReceivedData(packet_size, kDefaultSamplingRate, |
(...skipping 20 matching lines...) Expand all Loading... |
181 TestEncodeDecode(2000, 10000, AudioPacket::SAMPLING_RATE_44100); | 182 TestEncodeDecode(2000, 10000, AudioPacket::SAMPLING_RATE_44100); |
182 } | 183 } |
183 | 184 |
184 TEST_F(OpusAudioEncoderTest, BufferSizeAndResampling) { | 185 TEST_F(OpusAudioEncoderTest, BufferSizeAndResampling) { |
185 TestEncodeDecode(500, 3000, AudioPacket::SAMPLING_RATE_44100); | 186 TestEncodeDecode(500, 3000, AudioPacket::SAMPLING_RATE_44100); |
186 TestEncodeDecode(1000, 3000, AudioPacket::SAMPLING_RATE_44100); | 187 TestEncodeDecode(1000, 3000, AudioPacket::SAMPLING_RATE_44100); |
187 TestEncodeDecode(5000, 3000, AudioPacket::SAMPLING_RATE_44100); | 188 TestEncodeDecode(5000, 3000, AudioPacket::SAMPLING_RATE_44100); |
188 } | 189 } |
189 | 190 |
190 } // namespace remoting | 191 } // namespace remoting |
OLD | NEW |