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 // The format of these tests are to enqueue a known amount of data and then | 5 // The format of these tests are to enqueue a known amount of data and then |
6 // request the exact amount we expect in order to dequeue the known amount of | 6 // request the exact amount we expect in order to dequeue the known amount of |
7 // data. This ensures that for any rate we are consuming input data at the | 7 // data. This ensures that for any rate we are consuming input data at the |
8 // correct rate. We always pass in a very large destination buffer with the | 8 // correct rate. We always pass in a very large destination buffer with the |
9 // expectation that FillBuffer() will fill as much as it can but no more. | 9 // expectation that FillBuffer() will fill as much as it can but no more. |
10 | 10 |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
87 channels_ = ChannelLayoutToChannelCount(channel_layout); | 87 channels_ = ChannelLayoutToChannelCount(channel_layout); |
88 samples_per_second_ = samples_per_second; | 88 samples_per_second_ = samples_per_second; |
89 channel_layout_ = channel_layout; | 89 channel_layout_ = channel_layout; |
90 sample_format_ = sample_format; | 90 sample_format_ = sample_format; |
91 bytes_per_sample_ = SampleFormatToBytesPerChannel(sample_format); | 91 bytes_per_sample_ = SampleFormatToBytesPerChannel(sample_format); |
92 AudioParameters params(media::AudioParameters::AUDIO_PCM_LINEAR, | 92 AudioParameters params(media::AudioParameters::AUDIO_PCM_LINEAR, |
93 channel_layout, | 93 channel_layout, |
94 samples_per_second, | 94 samples_per_second, |
95 bytes_per_sample_ * 8, | 95 bytes_per_sample_ * 8, |
96 samples_per_second / 100); | 96 samples_per_second / 100); |
97 algorithm_.Initialize(1, params); | 97 algorithm_.Initialize(params); |
98 FillAlgorithmQueue(); | 98 FillAlgorithmQueue(); |
99 } | 99 } |
100 | 100 |
101 void FillAlgorithmQueue() { | 101 void FillAlgorithmQueue() { |
102 // The value of the data is meaningless; we just want non-zero data to | 102 // The value of the data is meaningless; we just want non-zero data to |
103 // differentiate it from muted data. | 103 // differentiate it from muted data. |
104 scoped_refptr<AudioBuffer> buffer; | 104 scoped_refptr<AudioBuffer> buffer; |
105 while (!algorithm_.IsQueueFull()) { | 105 while (!algorithm_.IsQueueFull()) { |
106 switch (sample_format_) { | 106 switch (sample_format_) { |
107 case kSampleFormatU8: | 107 case kSampleFormatU8: |
(...skipping 30 matching lines...) Expand all Loading... |
138 kNoTimestamp()); | 138 kNoTimestamp()); |
139 break; | 139 break; |
140 default: | 140 default: |
141 NOTREACHED() << "Unrecognized format " << sample_format_; | 141 NOTREACHED() << "Unrecognized format " << sample_format_; |
142 } | 142 } |
143 algorithm_.EnqueueBuffer(buffer); | 143 algorithm_.EnqueueBuffer(buffer); |
144 frames_enqueued_ += kFrameSize; | 144 frames_enqueued_ += kFrameSize; |
145 } | 145 } |
146 } | 146 } |
147 | 147 |
148 void CheckFakeData(AudioBus* audio_data, int frames_written) { | 148 bool AudioDataIsMuted(AudioBus* audio_data, int frames_written) { |
149 // Check each channel individually. | |
150 for (int ch = 0; ch < channels_; ++ch) { | 149 for (int ch = 0; ch < channels_; ++ch) { |
151 bool all_zero = true; | 150 for (int i = 0; i < frames_written; ++i) { |
152 for (int i = 0; i < frames_written && all_zero; ++i) | 151 if (audio_data->channel(ch)[i] != 0.0f) |
153 all_zero = audio_data->channel(ch)[i] == 0.0f; | 152 return false; |
154 ASSERT_EQ(algorithm_.is_muted(), all_zero) << " for channel " << ch; | 153 } |
155 } | 154 } |
| 155 return true; |
156 } | 156 } |
157 | 157 |
158 int ComputeConsumedFrames(int initial_frames_enqueued, | 158 int ComputeConsumedFrames(int initial_frames_enqueued, |
159 int initial_frames_buffered) { | 159 int initial_frames_buffered) { |
160 int frame_delta = frames_enqueued_ - initial_frames_enqueued; | 160 int frame_delta = frames_enqueued_ - initial_frames_enqueued; |
161 int buffered_delta = algorithm_.frames_buffered() - initial_frames_buffered; | 161 int buffered_delta = algorithm_.frames_buffered() - initial_frames_buffered; |
162 int consumed = frame_delta - buffered_delta; | 162 int consumed = frame_delta - buffered_delta; |
163 CHECK_GE(consumed, 0); | 163 CHECK_GE(consumed, 0); |
164 return consumed; | 164 return consumed; |
165 } | 165 } |
166 | 166 |
167 void TestPlaybackRate(double playback_rate) { | 167 void TestPlaybackRate(double playback_rate) { |
168 const int kDefaultBufferSize = algorithm_.samples_per_second() / 100; | 168 const int kDefaultBufferSize = algorithm_.samples_per_second() / 100; |
169 const int kDefaultFramesRequested = kOutputDurationInSec * | 169 const int kDefaultFramesRequested = kOutputDurationInSec * |
170 algorithm_.samples_per_second(); | 170 algorithm_.samples_per_second(); |
171 | 171 |
172 TestPlaybackRate( | 172 TestPlaybackRate( |
173 playback_rate, kDefaultBufferSize, kDefaultFramesRequested); | 173 playback_rate, kDefaultBufferSize, kDefaultFramesRequested); |
174 } | 174 } |
175 | 175 |
176 void TestPlaybackRate(double playback_rate, | 176 void TestPlaybackRate(double playback_rate, |
177 int buffer_size_in_frames, | 177 int buffer_size_in_frames, |
178 int total_frames_requested) { | 178 int total_frames_requested) { |
179 int initial_frames_enqueued = frames_enqueued_; | 179 int initial_frames_enqueued = frames_enqueued_; |
180 int initial_frames_buffered = algorithm_.frames_buffered(); | 180 int initial_frames_buffered = algorithm_.frames_buffered(); |
181 algorithm_.SetPlaybackRate(static_cast<float>(playback_rate)); | |
182 | 181 |
183 scoped_ptr<AudioBus> bus = | 182 scoped_ptr<AudioBus> bus = |
184 AudioBus::Create(channels_, buffer_size_in_frames); | 183 AudioBus::Create(channels_, buffer_size_in_frames); |
185 if (playback_rate == 0.0) { | 184 if (playback_rate == 0.0) { |
186 int frames_written = | 185 int frames_written = algorithm_.FillBuffer( |
187 algorithm_.FillBuffer(bus.get(), buffer_size_in_frames); | 186 bus.get(), buffer_size_in_frames, playback_rate); |
188 EXPECT_EQ(0, frames_written); | 187 EXPECT_EQ(0, frames_written); |
189 return; | 188 return; |
190 } | 189 } |
191 | 190 |
| 191 bool expect_muted = (playback_rate < 0.5 || playback_rate > 4); |
| 192 |
192 int frames_remaining = total_frames_requested; | 193 int frames_remaining = total_frames_requested; |
193 bool first_fill_buffer = true; | 194 bool first_fill_buffer = true; |
194 while (frames_remaining > 0) { | 195 while (frames_remaining > 0) { |
195 int frames_requested = std::min(buffer_size_in_frames, frames_remaining); | 196 int frames_requested = std::min(buffer_size_in_frames, frames_remaining); |
196 int frames_written = algorithm_.FillBuffer(bus.get(), frames_requested); | 197 int frames_written = |
| 198 algorithm_.FillBuffer(bus.get(), frames_requested, playback_rate); |
197 ASSERT_GT(frames_written, 0) << "Requested: " << frames_requested | 199 ASSERT_GT(frames_written, 0) << "Requested: " << frames_requested |
198 << ", playing at " << playback_rate; | 200 << ", playing at " << playback_rate; |
199 | 201 |
200 // Do not check data if it is first pull out and only one frame written. | 202 // Do not check data if it is first pull out and only one frame written. |
201 // The very first frame out of WSOLA is always zero because of | 203 // The very first frame out of WSOLA is always zero because of |
202 // overlap-and-add window, which is zero for the first sample. Therefore, | 204 // overlap-and-add window, which is zero for the first sample. Therefore, |
203 // if at very first buffer-fill only one frame is written, that is zero | 205 // if at very first buffer-fill only one frame is written, that is zero |
204 // which might cause exception in CheckFakeData(). | 206 // which might cause exception in CheckFakeData(). |
205 if (!first_fill_buffer || frames_written > 1) | 207 if (!first_fill_buffer || frames_written > 1) |
206 CheckFakeData(bus.get(), frames_written); | 208 ASSERT_EQ(expect_muted, AudioDataIsMuted(bus.get(), frames_written)); |
207 first_fill_buffer = false; | 209 first_fill_buffer = false; |
208 frames_remaining -= frames_written; | 210 frames_remaining -= frames_written; |
209 | 211 |
210 FillAlgorithmQueue(); | 212 FillAlgorithmQueue(); |
211 } | 213 } |
212 | 214 |
213 int frames_consumed = | 215 int frames_consumed = |
214 ComputeConsumedFrames(initial_frames_enqueued, initial_frames_buffered); | 216 ComputeConsumedFrames(initial_frames_enqueued, initial_frames_buffered); |
215 | 217 |
216 // If playing back at normal speed, we should always get back the same | 218 // If playing back at normal speed, we should always get back the same |
(...skipping 18 matching lines...) Expand all Loading... |
235 | 237 |
236 void WsolaTest(float playback_rate) { | 238 void WsolaTest(float playback_rate) { |
237 const int kSampleRateHz = 48000; | 239 const int kSampleRateHz = 48000; |
238 const ChannelLayout kChannelLayout = CHANNEL_LAYOUT_STEREO; | 240 const ChannelLayout kChannelLayout = CHANNEL_LAYOUT_STEREO; |
239 const int kBytesPerSample = 2; | 241 const int kBytesPerSample = 2; |
240 const int kNumFrames = kSampleRateHz / 100; // 10 milliseconds. | 242 const int kNumFrames = kSampleRateHz / 100; // 10 milliseconds. |
241 | 243 |
242 channels_ = ChannelLayoutToChannelCount(kChannelLayout); | 244 channels_ = ChannelLayoutToChannelCount(kChannelLayout); |
243 AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, | 245 AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, |
244 kSampleRateHz, kBytesPerSample * 8, kNumFrames); | 246 kSampleRateHz, kBytesPerSample * 8, kNumFrames); |
245 algorithm_.Initialize(playback_rate, params); | 247 algorithm_.Initialize(params); |
246 | 248 |
247 // A pulse is 6 milliseconds (even number of samples). | 249 // A pulse is 6 milliseconds (even number of samples). |
248 const int kPulseWidthSamples = 6 * kSampleRateHz / 1000; | 250 const int kPulseWidthSamples = 6 * kSampleRateHz / 1000; |
249 const int kHalfPulseWidthSamples = kPulseWidthSamples / 2; | 251 const int kHalfPulseWidthSamples = kPulseWidthSamples / 2; |
250 | 252 |
251 // For the ease of implementation get 1 frame every call to FillBuffer(). | 253 // For the ease of implementation get 1 frame every call to FillBuffer(). |
252 scoped_ptr<AudioBus> output = AudioBus::Create(channels_, 1); | 254 scoped_ptr<AudioBus> output = AudioBus::Create(channels_, 1); |
253 | 255 |
254 // Input buffer to inject pulses. | 256 // Input buffer to inject pulses. |
255 scoped_refptr<AudioBuffer> input = | 257 scoped_refptr<AudioBuffer> input = |
(...skipping 16 matching lines...) Expand all Loading... |
272 // reference pulse is compared with this buffer. | 274 // reference pulse is compared with this buffer. |
273 scoped_ptr<AudioBus> pulse_buffer = AudioBus::Create( | 275 scoped_ptr<AudioBus> pulse_buffer = AudioBus::Create( |
274 channels_, kPulseWidthSamples); | 276 channels_, kPulseWidthSamples); |
275 | 277 |
276 const float kTolerance = 0.000001f; | 278 const float kTolerance = 0.000001f; |
277 // Equivalent of 4 seconds. | 279 // Equivalent of 4 seconds. |
278 const int kNumRequestedPulses = kSampleRateHz * 4 / kPulseWidthSamples; | 280 const int kNumRequestedPulses = kSampleRateHz * 4 / kPulseWidthSamples; |
279 for (int n = 0; n < kNumRequestedPulses; ++n) { | 281 for (int n = 0; n < kNumRequestedPulses; ++n) { |
280 int num_buffered_frames = 0; | 282 int num_buffered_frames = 0; |
281 while (num_buffered_frames < kPulseWidthSamples) { | 283 while (num_buffered_frames < kPulseWidthSamples) { |
282 int num_samples = algorithm_.FillBuffer(output.get(), 1); | 284 int num_samples = algorithm_.FillBuffer(output.get(), 1, playback_rate); |
283 ASSERT_LE(num_samples, 1); | 285 ASSERT_LE(num_samples, 1); |
284 if (num_samples > 0) { | 286 if (num_samples > 0) { |
285 output->CopyPartialFramesTo(0, num_samples, num_buffered_frames, | 287 output->CopyPartialFramesTo(0, num_samples, num_buffered_frames, |
286 pulse_buffer.get()); | 288 pulse_buffer.get()); |
287 num_buffered_frames++; | 289 num_buffered_frames++; |
288 } else { | 290 } else { |
289 algorithm_.EnqueueBuffer(input); | 291 algorithm_.EnqueueBuffer(input); |
290 } | 292 } |
291 } | 293 } |
292 | 294 |
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
634 | 636 |
635 TEST_F(AudioRendererAlgorithmTest, WsolaSlowdown) { | 637 TEST_F(AudioRendererAlgorithmTest, WsolaSlowdown) { |
636 WsolaTest(0.6f); | 638 WsolaTest(0.6f); |
637 } | 639 } |
638 | 640 |
639 TEST_F(AudioRendererAlgorithmTest, WsolaSpeedup) { | 641 TEST_F(AudioRendererAlgorithmTest, WsolaSpeedup) { |
640 WsolaTest(1.6f); | 642 WsolaTest(1.6f); |
641 } | 643 } |
642 | 644 |
643 } // namespace media | 645 } // namespace media |
OLD | NEW |