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 |