| 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 |