| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "base/android/build_info.h" | 5 #include "base/android/build_info.h" |
| 6 #include "base/basictypes.h" | 6 #include "base/basictypes.h" |
| 7 #include "base/files/file_util.h" | 7 #include "base/files/file_util.h" |
| 8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
| 9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
| 10 #include "base/path_service.h" | 10 #include "base/path_service.h" |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 171 VLOG(0) << "Reading from file: " << file_path.value().c_str(); | 171 VLOG(0) << "Reading from file: " << file_path.value().c_str(); |
| 172 } | 172 } |
| 173 | 173 |
| 174 virtual ~FileAudioSource() {} | 174 virtual ~FileAudioSource() {} |
| 175 | 175 |
| 176 // AudioOutputStream::AudioSourceCallback implementation. | 176 // AudioOutputStream::AudioSourceCallback implementation. |
| 177 | 177 |
| 178 // Use samples read from a data file and fill up the audio buffer | 178 // Use samples read from a data file and fill up the audio buffer |
| 179 // provided to us in the callback. | 179 // provided to us in the callback. |
| 180 virtual int OnMoreData(AudioBus* audio_bus, | 180 virtual int OnMoreData(AudioBus* audio_bus, |
| 181 uint32 total_bytes_delay) OVERRIDE { | 181 uint32 total_bytes_delay) override { |
| 182 bool stop_playing = false; | 182 bool stop_playing = false; |
| 183 int max_size = | 183 int max_size = |
| 184 audio_bus->frames() * audio_bus->channels() * kBytesPerSample; | 184 audio_bus->frames() * audio_bus->channels() * kBytesPerSample; |
| 185 | 185 |
| 186 // Adjust data size and prepare for end signal if file has ended. | 186 // Adjust data size and prepare for end signal if file has ended. |
| 187 if (pos_ + max_size > file_size()) { | 187 if (pos_ + max_size > file_size()) { |
| 188 stop_playing = true; | 188 stop_playing = true; |
| 189 max_size = file_size() - pos_; | 189 max_size = file_size() - pos_; |
| 190 } | 190 } |
| 191 | 191 |
| 192 // File data is stored as interleaved 16-bit values. Copy data samples from | 192 // File data is stored as interleaved 16-bit values. Copy data samples from |
| 193 // the file and deinterleave to match the audio bus format. | 193 // the file and deinterleave to match the audio bus format. |
| 194 // FromInterleaved() will zero out any unfilled frames when there is not | 194 // FromInterleaved() will zero out any unfilled frames when there is not |
| 195 // sufficient data remaining in the file to fill up the complete frame. | 195 // sufficient data remaining in the file to fill up the complete frame. |
| 196 int frames = max_size / (audio_bus->channels() * kBytesPerSample); | 196 int frames = max_size / (audio_bus->channels() * kBytesPerSample); |
| 197 if (max_size) { | 197 if (max_size) { |
| 198 audio_bus->FromInterleaved(file_->data() + pos_, frames, kBytesPerSample); | 198 audio_bus->FromInterleaved(file_->data() + pos_, frames, kBytesPerSample); |
| 199 pos_ += max_size; | 199 pos_ += max_size; |
| 200 } | 200 } |
| 201 | 201 |
| 202 // Set event to ensure that the test can stop when the file has ended. | 202 // Set event to ensure that the test can stop when the file has ended. |
| 203 if (stop_playing) | 203 if (stop_playing) |
| 204 event_->Signal(); | 204 event_->Signal(); |
| 205 | 205 |
| 206 return frames; | 206 return frames; |
| 207 } | 207 } |
| 208 | 208 |
| 209 virtual void OnError(AudioOutputStream* stream) OVERRIDE {} | 209 virtual void OnError(AudioOutputStream* stream) override {} |
| 210 | 210 |
| 211 int file_size() { return file_->data_size(); } | 211 int file_size() { return file_->data_size(); } |
| 212 | 212 |
| 213 private: | 213 private: |
| 214 base::WaitableEvent* event_; | 214 base::WaitableEvent* event_; |
| 215 int pos_; | 215 int pos_; |
| 216 scoped_refptr<DecoderBuffer> file_; | 216 scoped_refptr<DecoderBuffer> file_; |
| 217 | 217 |
| 218 DISALLOW_COPY_AND_ASSIGN(FileAudioSource); | 218 DISALLOW_COPY_AND_ASSIGN(FileAudioSource); |
| 219 }; | 219 }; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 258 buffer_->Seek(chunk_size); | 258 buffer_->Seek(chunk_size); |
| 259 bytes_written += chunk_size; | 259 bytes_written += chunk_size; |
| 260 } | 260 } |
| 261 base::CloseFile(binary_file_); | 261 base::CloseFile(binary_file_); |
| 262 } | 262 } |
| 263 | 263 |
| 264 // AudioInputStream::AudioInputCallback implementation. | 264 // AudioInputStream::AudioInputCallback implementation. |
| 265 virtual void OnData(AudioInputStream* stream, | 265 virtual void OnData(AudioInputStream* stream, |
| 266 const AudioBus* src, | 266 const AudioBus* src, |
| 267 uint32 hardware_delay_bytes, | 267 uint32 hardware_delay_bytes, |
| 268 double volume) OVERRIDE { | 268 double volume) override { |
| 269 const int num_samples = src->frames() * src->channels(); | 269 const int num_samples = src->frames() * src->channels(); |
| 270 scoped_ptr<int16> interleaved(new int16[num_samples]); | 270 scoped_ptr<int16> interleaved(new int16[num_samples]); |
| 271 const int bytes_per_sample = sizeof(*interleaved); | 271 const int bytes_per_sample = sizeof(*interleaved); |
| 272 src->ToInterleaved(src->frames(), bytes_per_sample, interleaved.get()); | 272 src->ToInterleaved(src->frames(), bytes_per_sample, interleaved.get()); |
| 273 | 273 |
| 274 // Store data data in a temporary buffer to avoid making blocking | 274 // Store data data in a temporary buffer to avoid making blocking |
| 275 // fwrite() calls in the audio callback. The complete buffer will be | 275 // fwrite() calls in the audio callback. The complete buffer will be |
| 276 // written to file in the destructor. | 276 // written to file in the destructor. |
| 277 const int size = bytes_per_sample * num_samples; | 277 const int size = bytes_per_sample * num_samples; |
| 278 if (!buffer_->Append((const uint8*)interleaved.get(), size)) | 278 if (!buffer_->Append((const uint8*)interleaved.get(), size)) |
| 279 event_->Signal(); | 279 event_->Signal(); |
| 280 } | 280 } |
| 281 | 281 |
| 282 virtual void OnError(AudioInputStream* stream) OVERRIDE {} | 282 virtual void OnError(AudioInputStream* stream) override {} |
| 283 | 283 |
| 284 private: | 284 private: |
| 285 base::WaitableEvent* event_; | 285 base::WaitableEvent* event_; |
| 286 AudioParameters params_; | 286 AudioParameters params_; |
| 287 scoped_ptr<media::SeekableBuffer> buffer_; | 287 scoped_ptr<media::SeekableBuffer> buffer_; |
| 288 FILE* binary_file_; | 288 FILE* binary_file_; |
| 289 | 289 |
| 290 DISALLOW_COPY_AND_ASSIGN(FileAudioSink); | 290 DISALLOW_COPY_AND_ASSIGN(FileAudioSink); |
| 291 }; | 291 }; |
| 292 | 292 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 306 fifo_.reset(new media::SeekableBuffer(0, 2 * params.GetBytesPerBuffer())); | 306 fifo_.reset(new media::SeekableBuffer(0, 2 * params.GetBytesPerBuffer())); |
| 307 buffer_.reset(new uint8[params_.GetBytesPerBuffer()]); | 307 buffer_.reset(new uint8[params_.GetBytesPerBuffer()]); |
| 308 } | 308 } |
| 309 | 309 |
| 310 virtual ~FullDuplexAudioSinkSource() {} | 310 virtual ~FullDuplexAudioSinkSource() {} |
| 311 | 311 |
| 312 // AudioInputStream::AudioInputCallback implementation | 312 // AudioInputStream::AudioInputCallback implementation |
| 313 virtual void OnData(AudioInputStream* stream, | 313 virtual void OnData(AudioInputStream* stream, |
| 314 const AudioBus* src, | 314 const AudioBus* src, |
| 315 uint32 hardware_delay_bytes, | 315 uint32 hardware_delay_bytes, |
| 316 double volume) OVERRIDE { | 316 double volume) override { |
| 317 const base::TimeTicks now_time = base::TimeTicks::Now(); | 317 const base::TimeTicks now_time = base::TimeTicks::Now(); |
| 318 const int diff = (now_time - previous_time_).InMilliseconds(); | 318 const int diff = (now_time - previous_time_).InMilliseconds(); |
| 319 | 319 |
| 320 EXPECT_EQ(params_.bits_per_sample(), 16); | 320 EXPECT_EQ(params_.bits_per_sample(), 16); |
| 321 const int num_samples = src->frames() * src->channels(); | 321 const int num_samples = src->frames() * src->channels(); |
| 322 scoped_ptr<int16> interleaved(new int16[num_samples]); | 322 scoped_ptr<int16> interleaved(new int16[num_samples]); |
| 323 const int bytes_per_sample = sizeof(*interleaved); | 323 const int bytes_per_sample = sizeof(*interleaved); |
| 324 src->ToInterleaved(src->frames(), bytes_per_sample, interleaved.get()); | 324 src->ToInterleaved(src->frames(), bytes_per_sample, interleaved.get()); |
| 325 const int size = bytes_per_sample * num_samples; | 325 const int size = bytes_per_sample * num_samples; |
| 326 | 326 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 343 return; | 343 return; |
| 344 | 344 |
| 345 // Append new data to the FIFO and extend the size if the max capacity | 345 // Append new data to the FIFO and extend the size if the max capacity |
| 346 // was exceeded. Flush the FIFO when extended just in case. | 346 // was exceeded. Flush the FIFO when extended just in case. |
| 347 if (!fifo_->Append((const uint8*)interleaved.get(), size)) { | 347 if (!fifo_->Append((const uint8*)interleaved.get(), size)) { |
| 348 fifo_->set_forward_capacity(2 * fifo_->forward_capacity()); | 348 fifo_->set_forward_capacity(2 * fifo_->forward_capacity()); |
| 349 fifo_->Clear(); | 349 fifo_->Clear(); |
| 350 } | 350 } |
| 351 } | 351 } |
| 352 | 352 |
| 353 virtual void OnError(AudioInputStream* stream) OVERRIDE {} | 353 virtual void OnError(AudioInputStream* stream) override {} |
| 354 | 354 |
| 355 // AudioOutputStream::AudioSourceCallback implementation | 355 // AudioOutputStream::AudioSourceCallback implementation |
| 356 virtual int OnMoreData(AudioBus* dest, | 356 virtual int OnMoreData(AudioBus* dest, |
| 357 uint32 total_bytes_delay) OVERRIDE { | 357 uint32 total_bytes_delay) override { |
| 358 const int size_in_bytes = | 358 const int size_in_bytes = |
| 359 (params_.bits_per_sample() / 8) * dest->frames() * dest->channels(); | 359 (params_.bits_per_sample() / 8) * dest->frames() * dest->channels(); |
| 360 EXPECT_EQ(size_in_bytes, params_.GetBytesPerBuffer()); | 360 EXPECT_EQ(size_in_bytes, params_.GetBytesPerBuffer()); |
| 361 | 361 |
| 362 base::AutoLock lock(lock_); | 362 base::AutoLock lock(lock_); |
| 363 | 363 |
| 364 // We add an initial delay of ~1 second before loopback starts to ensure | 364 // We add an initial delay of ~1 second before loopback starts to ensure |
| 365 // a stable callback sequences and to avoid initial bursts which might add | 365 // a stable callback sequences and to avoid initial bursts which might add |
| 366 // to the extra FIFO delay. | 366 // to the extra FIFO delay. |
| 367 if (!started_) { | 367 if (!started_) { |
| 368 dest->Zero(); | 368 dest->Zero(); |
| 369 return dest->frames(); | 369 return dest->frames(); |
| 370 } | 370 } |
| 371 | 371 |
| 372 // Fill up destination with zeros if the FIFO does not contain enough | 372 // Fill up destination with zeros if the FIFO does not contain enough |
| 373 // data to fulfill the request. | 373 // data to fulfill the request. |
| 374 if (fifo_->forward_bytes() < size_in_bytes) { | 374 if (fifo_->forward_bytes() < size_in_bytes) { |
| 375 dest->Zero(); | 375 dest->Zero(); |
| 376 } else { | 376 } else { |
| 377 fifo_->Read(buffer_.get(), size_in_bytes); | 377 fifo_->Read(buffer_.get(), size_in_bytes); |
| 378 dest->FromInterleaved( | 378 dest->FromInterleaved( |
| 379 buffer_.get(), dest->frames(), params_.bits_per_sample() / 8); | 379 buffer_.get(), dest->frames(), params_.bits_per_sample() / 8); |
| 380 } | 380 } |
| 381 | 381 |
| 382 return dest->frames(); | 382 return dest->frames(); |
| 383 } | 383 } |
| 384 | 384 |
| 385 virtual void OnError(AudioOutputStream* stream) OVERRIDE {} | 385 virtual void OnError(AudioOutputStream* stream) override {} |
| 386 | 386 |
| 387 private: | 387 private: |
| 388 // Converts from bytes to milliseconds given number of bytes and existing | 388 // Converts from bytes to milliseconds given number of bytes and existing |
| 389 // audio parameters. | 389 // audio parameters. |
| 390 double BytesToMilliseconds(int bytes) const { | 390 double BytesToMilliseconds(int bytes) const { |
| 391 const int frames = bytes / params_.GetBytesPerFrame(); | 391 const int frames = bytes / params_.GetBytesPerFrame(); |
| 392 return (base::TimeDelta::FromMicroseconds( | 392 return (base::TimeDelta::FromMicroseconds( |
| 393 frames * base::Time::kMicrosecondsPerSecond / | 393 frames * base::Time::kMicrosecondsPerSecond / |
| 394 static_cast<double>(params_.sample_rate()))).InMillisecondsF(); | 394 static_cast<double>(params_.sample_rate()))).InMillisecondsF(); |
| 395 } | 395 } |
| (...skipping 571 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 967 base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(20)); | 967 base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(20)); |
| 968 printf("\n"); | 968 printf("\n"); |
| 969 StopAndCloseAudioOutputStreamOnAudioThread(); | 969 StopAndCloseAudioOutputStreamOnAudioThread(); |
| 970 StopAndCloseAudioInputStreamOnAudioThread(); | 970 StopAndCloseAudioInputStreamOnAudioThread(); |
| 971 } | 971 } |
| 972 | 972 |
| 973 INSTANTIATE_TEST_CASE_P(AudioAndroidInputTest, AudioAndroidInputTest, | 973 INSTANTIATE_TEST_CASE_P(AudioAndroidInputTest, AudioAndroidInputTest, |
| 974 testing::ValuesIn(RunAudioRecordInputPathTests())); | 974 testing::ValuesIn(RunAudioRecordInputPathTests())); |
| 975 | 975 |
| 976 } // namespace media | 976 } // namespace media |
| OLD | NEW |