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 #include <stddef.h> | 5 #include <stddef.h> |
| 6 #include <stdint.h> | 6 #include <stdint.h> |
| 7 | 7 |
| 8 #include <algorithm> | 8 #include <algorithm> |
| 9 #include <memory> | 9 #include <memory> |
| 10 | 10 |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 39 #include "media/audio/mac/audio_manager_mac.h" | 39 #include "media/audio/mac/audio_manager_mac.h" |
| 40 #elif defined(OS_WIN) | 40 #elif defined(OS_WIN) |
| 41 #include "media/audio/win/audio_manager_win.h" | 41 #include "media/audio/win/audio_manager_win.h" |
| 42 #include "media/audio/win/core_audio_util_win.h" | 42 #include "media/audio/win/core_audio_util_win.h" |
| 43 #elif defined(OS_ANDROID) | 43 #elif defined(OS_ANDROID) |
| 44 #include "media/audio/android/audio_manager_android.h" | 44 #include "media/audio/android/audio_manager_android.h" |
| 45 #else | 45 #else |
| 46 #include "media/audio/fake_audio_manager.h" | 46 #include "media/audio/fake_audio_manager.h" |
| 47 #endif | 47 #endif |
| 48 | 48 |
| 49 namespace media { | 49 namespace { |
|
tommi (sloooow) - chröme
2017/05/10 17:54:02
what about moving this anonymous namespace into me
eugenis
2017/05/10 18:30:54
Yes, that's a lot better!
| |
| 50 | 50 |
| 51 #if defined(USE_PULSEAUDIO) | 51 #if defined(USE_PULSEAUDIO) |
| 52 typedef AudioManagerPulse AudioManagerAnyPlatform; | 52 typedef media::AudioManagerPulse AudioManagerAnyPlatform; |
| 53 #elif defined(USE_ALSA) | 53 #elif defined(USE_ALSA) |
| 54 typedef AudioManagerAlsa AudioManagerAnyPlatform; | 54 typedef media::AudioManagerAlsa AudioManagerAnyPlatform; |
| 55 #elif defined(USE_CRAS) | 55 #elif defined(USE_CRAS) |
| 56 typedef AudioManagerCras AudioManagerAnyPlatform; | 56 typedef media::AudioManagerCras AudioManagerAnyPlatform; |
| 57 #elif defined(OS_MACOSX) | 57 #elif defined(OS_MACOSX) |
| 58 typedef AudioManagerMac AudioManagerAnyPlatform; | 58 typedef media::AudioManagerMac AudioManagerAnyPlatform; |
| 59 #elif defined(OS_WIN) | 59 #elif defined(OS_WIN) |
| 60 typedef AudioManagerWin AudioManagerAnyPlatform; | 60 typedef media::AudioManagerWin AudioManagerAnyPlatform; |
| 61 #elif defined(OS_ANDROID) | 61 #elif defined(OS_ANDROID) |
| 62 typedef AudioManagerAndroid AudioManagerAnyPlatform; | 62 typedef media::AudioManagerAndroid AudioManagerAnyPlatform; |
| 63 #else | 63 #else |
| 64 typedef FakeAudioManager AudioManagerAnyPlatform; | 64 typedef media::FakeAudioManager AudioManagerAnyPlatform; |
| 65 #endif | 65 #endif |
| 66 | 66 |
| 67 // Limits the number of delay measurements we can store in an array and | 67 // Limits the number of delay measurements we can store in an array and |
| 68 // then write to file at end of the WASAPIAudioInputOutputFullDuplex test. | 68 // then write to file at end of the WASAPIAudioInputOutputFullDuplex test. |
| 69 static const size_t kMaxDelayMeasurements = 1000; | 69 static const size_t kMaxDelayMeasurements = 1000; |
| 70 | 70 |
| 71 // Name of the output text file. The output file will be stored in the | 71 // Name of the output text file. The output file will be stored in the |
| 72 // directory containing media_unittests.exe. | 72 // directory containing media_unittests.exe. |
| 73 // Example: \src\build\Debug\audio_delay_values_ms.txt. | 73 // Example: \src\build\Debug\audio_delay_values_ms.txt. |
| 74 // See comments for the WASAPIAudioInputOutputFullDuplex test for more details | 74 // See comments for the WASAPIAudioInputOutputFullDuplex test for more details |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 105 // the main thread instead of the audio thread. | 105 // the main thread instead of the audio thread. |
| 106 class MockAudioManager : public AudioManagerAnyPlatform { | 106 class MockAudioManager : public AudioManagerAnyPlatform { |
| 107 public: | 107 public: |
| 108 MockAudioManager() | 108 MockAudioManager() |
| 109 : AudioManagerAnyPlatform(base::ThreadTaskRunnerHandle::Get(), | 109 : AudioManagerAnyPlatform(base::ThreadTaskRunnerHandle::Get(), |
| 110 base::ThreadTaskRunnerHandle::Get(), | 110 base::ThreadTaskRunnerHandle::Get(), |
| 111 &fake_audio_log_factory_) {} | 111 &fake_audio_log_factory_) {} |
| 112 ~MockAudioManager() override {} | 112 ~MockAudioManager() override {} |
| 113 | 113 |
| 114 private: | 114 private: |
| 115 FakeAudioLogFactory fake_audio_log_factory_; | 115 media::FakeAudioLogFactory fake_audio_log_factory_; |
| 116 DISALLOW_COPY_AND_ASSIGN(MockAudioManager); | 116 DISALLOW_COPY_AND_ASSIGN(MockAudioManager); |
| 117 }; | 117 }; |
| 118 | 118 |
| 119 // Test fixture class. | 119 // Test fixture class. |
| 120 class AudioLowLatencyInputOutputTest : public testing::Test { | 120 class AudioLowLatencyInputOutputTest : public testing::Test { |
| 121 protected: | 121 protected: |
| 122 AudioLowLatencyInputOutputTest() {} | 122 AudioLowLatencyInputOutputTest() {} |
| 123 | 123 |
| 124 ~AudioLowLatencyInputOutputTest() override {} | 124 ~AudioLowLatencyInputOutputTest() override {} |
| 125 | 125 |
| 126 AudioManager* audio_manager() { return &mock_audio_manager_; } | 126 media::AudioManager* audio_manager() { return &mock_audio_manager_; } |
| 127 base::MessageLoopForUI* message_loop() { return &message_loop_; } | 127 base::MessageLoopForUI* message_loop() { return &message_loop_; } |
| 128 | 128 |
| 129 private: | 129 private: |
| 130 base::MessageLoopForUI message_loop_; | 130 base::MessageLoopForUI message_loop_; |
| 131 MockAudioManager mock_audio_manager_; | 131 MockAudioManager mock_audio_manager_; |
| 132 | 132 |
| 133 DISALLOW_COPY_AND_ASSIGN(AudioLowLatencyInputOutputTest); | 133 DISALLOW_COPY_AND_ASSIGN(AudioLowLatencyInputOutputTest); |
| 134 }; | 134 }; |
| 135 | 135 |
| 136 // This audio source/sink implementation should be used for manual tests | 136 // This audio source/sink implementation should be used for manual tests |
| 137 // only since delay measurements are stored on an output text file. | 137 // only since delay measurements are stored on an output text file. |
| 138 // All incoming/recorded audio packets are stored in an intermediate media | 138 // All incoming/recorded audio packets are stored in an intermediate media |
| 139 // buffer which the renderer reads from when it needs audio for playout. | 139 // buffer which the renderer reads from when it needs audio for playout. |
| 140 // The total effect is that recorded audio is played out in loop back using | 140 // The total effect is that recorded audio is played out in loop back using |
| 141 // a sync buffer as temporary storage. | 141 // a sync buffer as temporary storage. |
| 142 class FullDuplexAudioSinkSource | 142 class FullDuplexAudioSinkSource |
| 143 : public AudioInputStream::AudioInputCallback, | 143 : public media::AudioInputStream::AudioInputCallback, |
| 144 public AudioOutputStream::AudioSourceCallback { | 144 public media::AudioOutputStream::AudioSourceCallback { |
| 145 public: | 145 public: |
| 146 FullDuplexAudioSinkSource(int sample_rate, | 146 FullDuplexAudioSinkSource(int sample_rate, |
| 147 int samples_per_packet, | 147 int samples_per_packet, |
| 148 int channels) | 148 int channels) |
| 149 : sample_rate_(sample_rate), | 149 : sample_rate_(sample_rate), |
| 150 samples_per_packet_(samples_per_packet), | 150 samples_per_packet_(samples_per_packet), |
| 151 channels_(channels), | 151 channels_(channels), |
| 152 input_elements_to_write_(0), | 152 input_elements_to_write_(0), |
| 153 output_elements_to_write_(0), | 153 output_elements_to_write_(0), |
| 154 previous_write_time_(base::TimeTicks::Now()) { | 154 previous_write_time_(base::TimeTicks::Now()) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 186 state.buffer_delay_ms, | 186 state.buffer_delay_ms, |
| 187 state.input_delay_ms, | 187 state.input_delay_ms, |
| 188 state.output_delay_ms); | 188 state.output_delay_ms); |
| 189 ++elements_written; | 189 ++elements_written; |
| 190 } | 190 } |
| 191 | 191 |
| 192 base::CloseFile(text_file); | 192 base::CloseFile(text_file); |
| 193 } | 193 } |
| 194 | 194 |
| 195 // AudioInputStream::AudioInputCallback. | 195 // AudioInputStream::AudioInputCallback. |
| 196 void OnData(AudioInputStream* stream, | 196 void OnData(media::AudioInputStream* stream, |
| 197 const AudioBus* src, | 197 const media::AudioBus* src, |
| 198 uint32_t hardware_delay_bytes, | 198 uint32_t hardware_delay_bytes, |
| 199 double volume) override { | 199 double volume) override { |
| 200 base::AutoLock lock(lock_); | 200 base::AutoLock lock(lock_); |
| 201 | 201 |
| 202 // Update three components in the AudioDelayState for this recorded | 202 // Update three components in the AudioDelayState for this recorded |
| 203 // audio packet. | 203 // audio packet. |
| 204 const base::TimeTicks now_time = base::TimeTicks::Now(); | 204 const base::TimeTicks now_time = base::TimeTicks::Now(); |
| 205 const int diff = (now_time - previous_write_time_).InMilliseconds(); | 205 const int diff = (now_time - previous_write_time_).InMilliseconds(); |
| 206 previous_write_time_ = now_time; | 206 previous_write_time_ = now_time; |
| 207 if (input_elements_to_write_ < kMaxDelayMeasurements) { | 207 if (input_elements_to_write_ < kMaxDelayMeasurements) { |
| 208 delay_states_[input_elements_to_write_].delta_time_ms = diff; | 208 delay_states_[input_elements_to_write_].delta_time_ms = diff; |
| 209 delay_states_[input_elements_to_write_].buffer_delay_ms = | 209 delay_states_[input_elements_to_write_].buffer_delay_ms = |
| 210 BytesToMilliseconds(buffer_->forward_bytes()); | 210 BytesToMilliseconds(buffer_->forward_bytes()); |
| 211 delay_states_[input_elements_to_write_].input_delay_ms = | 211 delay_states_[input_elements_to_write_].input_delay_ms = |
| 212 BytesToMilliseconds(hardware_delay_bytes); | 212 BytesToMilliseconds(hardware_delay_bytes); |
| 213 ++input_elements_to_write_; | 213 ++input_elements_to_write_; |
| 214 } | 214 } |
| 215 | 215 |
| 216 // TODO(henrika): fix this and use AudioFifo instead. | 216 // TODO(henrika): fix this and use AudioFifo instead. |
| 217 // Store the captured audio packet in a seekable media buffer. | 217 // Store the captured audio packet in a seekable media buffer. |
| 218 // if (!buffer_->Append(src, size)) { | 218 // if (!buffer_->Append(src, size)) { |
| 219 // An attempt to write outside the buffer limits has been made. | 219 // An attempt to write outside the buffer limits has been made. |
| 220 // Double the buffer capacity to ensure that we have a buffer large | 220 // Double the buffer capacity to ensure that we have a buffer large |
| 221 // enough to handle the current sample test scenario. | 221 // enough to handle the current sample test scenario. |
| 222 // buffer_->set_forward_capacity(2 * buffer_->forward_capacity()); | 222 // buffer_->set_forward_capacity(2 * buffer_->forward_capacity()); |
| 223 // buffer_->Clear(); | 223 // buffer_->Clear(); |
| 224 // } | 224 // } |
| 225 } | 225 } |
| 226 | 226 |
| 227 void OnError(AudioInputStream* stream) override {} | 227 void OnError(media::AudioInputStream* stream) override {} |
| 228 | 228 |
| 229 // AudioOutputStream::AudioSourceCallback. | 229 // AudioOutputStream::AudioSourceCallback. |
| 230 int OnMoreData(base::TimeDelta delay, | 230 int OnMoreData(base::TimeDelta delay, |
| 231 base::TimeTicks /* delay_timestamp */, | 231 base::TimeTicks /* delay_timestamp */, |
| 232 int /* prior_frames_skipped */, | 232 int /* prior_frames_skipped */, |
| 233 AudioBus* dest) override { | 233 media::AudioBus* dest) override { |
| 234 base::AutoLock lock(lock_); | 234 base::AutoLock lock(lock_); |
| 235 | 235 |
| 236 // Update one component in the AudioDelayState for the packet | 236 // Update one component in the AudioDelayState for the packet |
| 237 // which is about to be played out. | 237 // which is about to be played out. |
| 238 if (output_elements_to_write_ < kMaxDelayMeasurements) { | 238 if (output_elements_to_write_ < kMaxDelayMeasurements) { |
| 239 delay_states_[output_elements_to_write_].output_delay_ms = | 239 delay_states_[output_elements_to_write_].output_delay_ms = |
| 240 delay.InMilliseconds(); | 240 delay.InMilliseconds(); |
| 241 ++output_elements_to_write_; | 241 ++output_elements_to_write_; |
| 242 } | 242 } |
| 243 | 243 |
| 244 int size; | 244 int size; |
| 245 const uint8_t* source; | 245 const uint8_t* source; |
| 246 // Read the data from the seekable media buffer which contains | 246 // Read the data from the seekable media buffer which contains |
| 247 // captured data at the same size and sample rate as the output side. | 247 // captured data at the same size and sample rate as the output side. |
| 248 if (buffer_->GetCurrentChunk(&source, &size) && size > 0) { | 248 if (buffer_->GetCurrentChunk(&source, &size) && size > 0) { |
| 249 EXPECT_EQ(channels_, dest->channels()); | 249 EXPECT_EQ(channels_, dest->channels()); |
| 250 size = std::min(dest->frames() * frame_size_, size); | 250 size = std::min(dest->frames() * frame_size_, size); |
| 251 EXPECT_EQ(static_cast<size_t>(size) % sizeof(*dest->channel(0)), 0U); | 251 EXPECT_EQ(static_cast<size_t>(size) % sizeof(*dest->channel(0)), 0U); |
| 252 dest->FromInterleaved(source, size / frame_size_, | 252 dest->FromInterleaved(source, size / frame_size_, |
| 253 frame_size_ / channels_); | 253 frame_size_ / channels_); |
| 254 buffer_->Seek(size); | 254 buffer_->Seek(size); |
| 255 return size / frame_size_; | 255 return size / frame_size_; |
| 256 } | 256 } |
| 257 | 257 |
| 258 return 0; | 258 return 0; |
| 259 } | 259 } |
| 260 | 260 |
| 261 void OnError(AudioOutputStream* stream) override {} | 261 void OnError(media::AudioOutputStream* stream) override {} |
| 262 | 262 |
| 263 protected: | 263 protected: |
| 264 // Converts from bytes to milliseconds taking the sample rate and size | 264 // Converts from bytes to milliseconds taking the sample rate and size |
| 265 // of an audio frame into account. | 265 // of an audio frame into account. |
| 266 int BytesToMilliseconds(uint32_t delay_bytes) const { | 266 int BytesToMilliseconds(uint32_t delay_bytes) const { |
| 267 return static_cast<int>((delay_bytes / frame_size_) * frames_to_ms_ + 0.5); | 267 return static_cast<int>((delay_bytes / frame_size_) * frames_to_ms_ + 0.5); |
| 268 } | 268 } |
| 269 | 269 |
| 270 private: | 270 private: |
| 271 base::Lock lock_; | 271 base::Lock lock_; |
| 272 std::unique_ptr<media::SeekableBuffer> buffer_; | 272 std::unique_ptr<media::SeekableBuffer> buffer_; |
| 273 int sample_rate_; | 273 int sample_rate_; |
| 274 int samples_per_packet_; | 274 int samples_per_packet_; |
| 275 int channels_; | 275 int channels_; |
| 276 int frame_size_; | 276 int frame_size_; |
| 277 double frames_to_ms_; | 277 double frames_to_ms_; |
| 278 std::unique_ptr<AudioDelayState[]> delay_states_; | 278 std::unique_ptr<AudioDelayState[]> delay_states_; |
| 279 size_t input_elements_to_write_; | 279 size_t input_elements_to_write_; |
| 280 size_t output_elements_to_write_; | 280 size_t output_elements_to_write_; |
| 281 base::TimeTicks previous_write_time_; | 281 base::TimeTicks previous_write_time_; |
| 282 }; | 282 }; |
| 283 | 283 |
| 284 class AudioInputStreamTraits { | 284 class AudioInputStreamTraits { |
| 285 public: | 285 public: |
| 286 typedef AudioInputStream StreamType; | 286 typedef media::AudioInputStream StreamType; |
| 287 | 287 |
| 288 static AudioParameters GetDefaultAudioStreamParameters( | 288 static media::AudioParameters GetDefaultAudioStreamParameters( |
| 289 AudioManager* audio_manager) { | 289 media::AudioManager* audio_manager) { |
| 290 return AudioDeviceInfoAccessorForTests(audio_manager) | 290 return media::AudioDeviceInfoAccessorForTests(audio_manager) |
| 291 .GetInputStreamParameters(AudioDeviceDescription::kDefaultDeviceId); | 291 .GetInputStreamParameters( |
| 292 media::AudioDeviceDescription::kDefaultDeviceId); | |
| 292 } | 293 } |
| 293 | 294 |
| 294 static StreamType* CreateStream(AudioManager* audio_manager, | 295 static StreamType* CreateStream(media::AudioManager* audio_manager, |
| 295 const AudioParameters& params) { | 296 const media::AudioParameters& params) { |
| 296 return audio_manager->MakeAudioInputStream( | 297 return audio_manager->MakeAudioInputStream( |
| 297 params, AudioDeviceDescription::kDefaultDeviceId, | 298 params, media::AudioDeviceDescription::kDefaultDeviceId, |
| 298 base::Bind(&OnLogMessage)); | 299 base::Bind(&OnLogMessage)); |
| 299 } | 300 } |
| 300 }; | 301 }; |
| 301 | 302 |
| 302 class AudioOutputStreamTraits { | 303 class AudioOutputStreamTraits { |
| 303 public: | 304 public: |
| 304 typedef AudioOutputStream StreamType; | 305 typedef media::AudioOutputStream StreamType; |
| 305 | 306 |
| 306 static AudioParameters GetDefaultAudioStreamParameters( | 307 static media::AudioParameters GetDefaultAudioStreamParameters( |
| 307 AudioManager* audio_manager) { | 308 media::AudioManager* audio_manager) { |
| 308 return AudioDeviceInfoAccessorForTests(audio_manager) | 309 return media::AudioDeviceInfoAccessorForTests(audio_manager) |
| 309 .GetDefaultOutputStreamParameters(); | 310 .GetDefaultOutputStreamParameters(); |
| 310 } | 311 } |
| 311 | 312 |
| 312 static StreamType* CreateStream(AudioManager* audio_manager, | 313 static StreamType* CreateStream(media::AudioManager* audio_manager, |
| 313 const AudioParameters& params) { | 314 const media::AudioParameters& params) { |
| 314 return audio_manager->MakeAudioOutputStream(params, std::string(), | 315 return audio_manager->MakeAudioOutputStream(params, std::string(), |
| 315 base::Bind(&OnLogMessage)); | 316 base::Bind(&OnLogMessage)); |
| 316 } | 317 } |
| 317 }; | 318 }; |
| 318 | 319 |
| 319 // Traits template holding a trait of StreamType. It encapsulates | 320 // Traits template holding a trait of StreamType. It encapsulates |
| 320 // AudioInputStream and AudioOutputStream stream types. | 321 // AudioInputStream and AudioOutputStream stream types. |
| 321 template <typename StreamTraits> | 322 template <typename StreamTraits> |
| 322 class StreamWrapper { | 323 class StreamWrapper { |
| 323 public: | 324 public: |
| 324 typedef typename StreamTraits::StreamType StreamType; | 325 typedef typename StreamTraits::StreamType StreamType; |
| 325 | 326 |
| 326 explicit StreamWrapper(AudioManager* audio_manager) | 327 explicit StreamWrapper(media::AudioManager* audio_manager) |
| 327 : | 328 : audio_manager_(audio_manager), |
| 328 audio_manager_(audio_manager), | 329 format_(media::AudioParameters::AUDIO_PCM_LOW_LATENCY), |
| 329 format_(AudioParameters::AUDIO_PCM_LOW_LATENCY), | |
| 330 #if defined(OS_ANDROID) | 330 #if defined(OS_ANDROID) |
| 331 channel_layout_(CHANNEL_LAYOUT_MONO), | 331 channel_layout_(media::CHANNEL_LAYOUT_MONO), |
| 332 #else | 332 #else |
| 333 channel_layout_(CHANNEL_LAYOUT_STEREO), | 333 channel_layout_(media::CHANNEL_LAYOUT_STEREO), |
| 334 #endif | 334 #endif |
| 335 bits_per_sample_(16) { | 335 bits_per_sample_(16) { |
| 336 // Use the preferred sample rate. | 336 // Use the preferred sample rate. |
| 337 const AudioParameters& params = | 337 const media::AudioParameters& params = |
| 338 StreamTraits::GetDefaultAudioStreamParameters(audio_manager_); | 338 StreamTraits::GetDefaultAudioStreamParameters(audio_manager_); |
| 339 sample_rate_ = params.sample_rate(); | 339 sample_rate_ = params.sample_rate(); |
| 340 | 340 |
| 341 // Use the preferred buffer size. Note that the input side uses the same | 341 // Use the preferred buffer size. Note that the input side uses the same |
| 342 // size as the output side in this implementation. | 342 // size as the output side in this implementation. |
| 343 samples_per_packet_ = params.frames_per_buffer(); | 343 samples_per_packet_ = params.frames_per_buffer(); |
| 344 } | 344 } |
| 345 | 345 |
| 346 virtual ~StreamWrapper() {} | 346 virtual ~StreamWrapper() {} |
| 347 | 347 |
| 348 // Creates an Audio[Input|Output]Stream stream object using default | 348 // Creates an Audio[Input|Output]Stream stream object using default |
| 349 // parameters. | 349 // parameters. |
| 350 StreamType* Create() { | 350 StreamType* Create() { |
| 351 return CreateStream(); | 351 return CreateStream(); |
| 352 } | 352 } |
| 353 | 353 |
| 354 int channels() const { | 354 int channels() const { |
| 355 return ChannelLayoutToChannelCount(channel_layout_); | 355 return ChannelLayoutToChannelCount(channel_layout_); |
| 356 } | 356 } |
| 357 int bits_per_sample() const { return bits_per_sample_; } | 357 int bits_per_sample() const { return bits_per_sample_; } |
| 358 int sample_rate() const { return sample_rate_; } | 358 int sample_rate() const { return sample_rate_; } |
| 359 int samples_per_packet() const { return samples_per_packet_; } | 359 int samples_per_packet() const { return samples_per_packet_; } |
| 360 | 360 |
| 361 private: | 361 private: |
| 362 StreamType* CreateStream() { | 362 StreamType* CreateStream() { |
| 363 StreamType* stream = StreamTraits::CreateStream(audio_manager_, | 363 StreamType* stream = StreamTraits::CreateStream( |
| 364 AudioParameters(format_, channel_layout_, sample_rate_, | 364 audio_manager_, |
| 365 bits_per_sample_, samples_per_packet_)); | 365 media::AudioParameters(format_, channel_layout_, sample_rate_, |
| 366 bits_per_sample_, samples_per_packet_)); | |
| 366 EXPECT_TRUE(stream); | 367 EXPECT_TRUE(stream); |
| 367 return stream; | 368 return stream; |
| 368 } | 369 } |
| 369 | 370 |
| 370 AudioManager* audio_manager_; | 371 media::AudioManager* audio_manager_; |
| 371 AudioParameters::Format format_; | 372 media::AudioParameters::Format format_; |
| 372 ChannelLayout channel_layout_; | 373 media::ChannelLayout channel_layout_; |
| 373 int bits_per_sample_; | 374 int bits_per_sample_; |
| 374 int sample_rate_; | 375 int sample_rate_; |
| 375 int samples_per_packet_; | 376 int samples_per_packet_; |
| 376 }; | 377 }; |
| 377 | 378 |
| 378 typedef StreamWrapper<AudioInputStreamTraits> AudioInputStreamWrapper; | 379 typedef StreamWrapper<AudioInputStreamTraits> AudioInputStreamWrapper; |
| 379 typedef StreamWrapper<AudioOutputStreamTraits> AudioOutputStreamWrapper; | 380 typedef StreamWrapper<AudioOutputStreamTraits> AudioOutputStreamWrapper; |
| 380 | 381 |
| 381 // This test is intended for manual tests and should only be enabled | 382 // This test is intended for manual tests and should only be enabled |
| 382 // when it is required to make a real-time test of audio in full duplex and | 383 // when it is required to make a real-time test of audio in full duplex and |
| 383 // at the same time create a text file which contains measured delay values. | 384 // at the same time create a text file which contains measured delay values. |
| 384 // The file can later be analyzed off line using e.g. MATLAB. | 385 // The file can later be analyzed off line using e.g. MATLAB. |
| 385 // MATLAB example: | 386 // MATLAB example: |
| 386 // D=load('audio_delay_values_ms.txt'); | 387 // D=load('audio_delay_values_ms.txt'); |
| 387 // x=cumsum(D(:,1)); | 388 // x=cumsum(D(:,1)); |
| 388 // plot(x, D(:,2), x, D(:,3), x, D(:,4), x, D(:,2)+D(:,3)+D(:,4)); | 389 // plot(x, D(:,2), x, D(:,3), x, D(:,4), x, D(:,2)+D(:,3)+D(:,4)); |
| 389 // axis([0, max(x), 0, max(D(:,2)+D(:,3)+D(:,4))+10]); | 390 // axis([0, max(x), 0, max(D(:,2)+D(:,3)+D(:,4))+10]); |
| 390 // legend('buffer delay','input delay','output delay','total delay'); | 391 // legend('buffer delay','input delay','output delay','total delay'); |
| 391 // xlabel('time [msec]') | 392 // xlabel('time [msec]') |
| 392 // ylabel('delay [msec]') | 393 // ylabel('delay [msec]') |
| 393 // title('Full-duplex audio delay measurement'); | 394 // title('Full-duplex audio delay measurement'); |
| 394 TEST_F(AudioLowLatencyInputOutputTest, DISABLED_FullDuplexDelayMeasurement) { | 395 TEST_F(AudioLowLatencyInputOutputTest, DISABLED_FullDuplexDelayMeasurement) { |
| 395 AudioDeviceInfoAccessorForTests device_info_accessor(audio_manager()); | 396 media::AudioDeviceInfoAccessorForTests device_info_accessor(audio_manager()); |
| 396 ABORT_AUDIO_TEST_IF_NOT(device_info_accessor.HasAudioInputDevices() && | 397 ABORT_AUDIO_TEST_IF_NOT(device_info_accessor.HasAudioInputDevices() && |
| 397 device_info_accessor.HasAudioOutputDevices()); | 398 device_info_accessor.HasAudioOutputDevices()); |
| 398 | 399 |
| 399 AudioInputStreamWrapper aisw(audio_manager()); | 400 AudioInputStreamWrapper aisw(audio_manager()); |
| 400 AudioInputStream* ais = aisw.Create(); | 401 media::AudioInputStream* ais = aisw.Create(); |
| 401 EXPECT_TRUE(ais); | 402 EXPECT_TRUE(ais); |
| 402 | 403 |
| 403 AudioOutputStreamWrapper aosw(audio_manager()); | 404 AudioOutputStreamWrapper aosw(audio_manager()); |
| 404 AudioOutputStream* aos = aosw.Create(); | 405 media::AudioOutputStream* aos = aosw.Create(); |
| 405 EXPECT_TRUE(aos); | 406 EXPECT_TRUE(aos); |
| 406 | 407 |
| 407 // This test only supports identical parameters in both directions. | 408 // This test only supports identical parameters in both directions. |
| 408 // TODO(henrika): it is possible to cut delay here by using different | 409 // TODO(henrika): it is possible to cut delay here by using different |
| 409 // buffer sizes for input and output. | 410 // buffer sizes for input and output. |
| 410 if (aisw.sample_rate() != aosw.sample_rate() || | 411 if (aisw.sample_rate() != aosw.sample_rate() || |
| 411 aisw.samples_per_packet() != aosw.samples_per_packet() || | 412 aisw.samples_per_packet() != aosw.samples_per_packet() || |
| 412 aisw.channels()!= aosw.channels() || | 413 aisw.channels()!= aosw.channels() || |
| 413 aisw.bits_per_sample() != aosw.bits_per_sample()) { | 414 aisw.bits_per_sample() != aosw.bits_per_sample()) { |
| 414 LOG(ERROR) << "This test requires symmetric input and output parameters. " | 415 LOG(ERROR) << "This test requires symmetric input and output parameters. " |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 445 ais->Stop(); | 446 ais->Stop(); |
| 446 | 447 |
| 447 // All Close() operations that run on the mocked audio thread, | 448 // All Close() operations that run on the mocked audio thread, |
| 448 // should be synchronous and not post additional close tasks to | 449 // should be synchronous and not post additional close tasks to |
| 449 // mocked the audio thread. Hence, there is no need to call | 450 // mocked the audio thread. Hence, there is no need to call |
| 450 // message_loop()->RunUntilIdle() after the Close() methods. | 451 // message_loop()->RunUntilIdle() after the Close() methods. |
| 451 aos->Close(); | 452 aos->Close(); |
| 452 ais->Close(); | 453 ais->Close(); |
| 453 } | 454 } |
| 454 | 455 |
| 455 } // namespace media | 456 } // namespace |
| OLD | NEW |