Chromium Code Reviews| 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) { |
|
scherkus (not reviewing)
2014/07/22 19:25:50
I'm not sure what this was actually checking for .
DaleCurtis
2014/07/22 19:32:56
I think it was just trying to provide some extra c
| |
| 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 |