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 "media/audio/fake_audio_input_stream.h" | 5 #include "media/audio/fake_audio_input_stream.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/files/file.h" | 9 #include "base/files/file.h" |
10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 // Opens |wav_filename|, reads it and loads it as a wav file. This function will | 59 // Opens |wav_filename|, reads it and loads it as a wav file. This function will |
60 // bluntly trigger CHECKs if we can't read the file or if it's malformed. The | 60 // bluntly trigger CHECKs if we can't read the file or if it's malformed. The |
61 // caller takes ownership of the returned data. The size of the data is stored | 61 // caller takes ownership of the returned data. The size of the data is stored |
62 // in |read_length|. | 62 // in |read_length|. |
63 scoped_ptr<uint8[]> ReadWavFile(const base::FilePath& wav_filename, | 63 scoped_ptr<uint8[]> ReadWavFile(const base::FilePath& wav_filename, |
64 size_t* file_length) { | 64 size_t* file_length) { |
65 base::File wav_file( | 65 base::File wav_file( |
66 wav_filename, base::File::FLAG_OPEN | base::File::FLAG_READ); | 66 wav_filename, base::File::FLAG_OPEN | base::File::FLAG_READ); |
67 if (!wav_file.IsValid()) { | 67 if (!wav_file.IsValid()) { |
68 CHECK(false) << "Failed to read " << wav_filename.value() << " as input to " | 68 CHECK(false) << "Failed to read " << wav_filename.value() << " as input to " |
69 << "the fake device."; | 69 << "the fake device."; |
70 return nullptr; | 70 return nullptr; |
71 } | 71 } |
72 | 72 |
73 size_t wav_file_length = wav_file.GetLength(); | 73 size_t wav_file_length = wav_file.GetLength(); |
| 74 CHECK_GT(wav_file_length, 0u) |
| 75 << "Input file to fake device is empty: " << wav_filename.value(); |
74 | 76 |
75 uint8* wav_file_data = new uint8[wav_file_length]; | 77 uint8* wav_file_data = new uint8[wav_file_length]; |
76 size_t read_bytes = wav_file.Read(0, reinterpret_cast<char*>(wav_file_data), | 78 size_t read_bytes = wav_file.Read(0, reinterpret_cast<char*>(wav_file_data), |
77 wav_file_length); | 79 wav_file_length); |
78 if (read_bytes != wav_file_length) { | 80 if (read_bytes != wav_file_length) { |
79 CHECK(false) << "Failed to read all bytes of " << wav_filename.value(); | 81 CHECK(false) << "Failed to read all bytes of " << wav_filename.value(); |
80 return nullptr; | 82 return nullptr; |
81 } | 83 } |
82 *file_length = wav_file_length; | 84 *file_length = wav_file_length; |
83 return scoped_ptr<uint8[]>(wav_file_data); | 85 return scoped_ptr<uint8[]>(wav_file_data); |
84 } | 86 } |
85 | 87 |
86 // Opens |wav_filename|, reads it and loads it as a Wav file. This function will | 88 // Opens |wav_filename|, reads it and loads it as a Wav file. This function will |
87 // bluntly trigger CHECKs if the file doesn't have the sampling frequency, bits | 89 // bluntly trigger CHECKs if we can't read the file or if it's malformed. |
88 // per sample or number of channels as specified in |expected_params|. We also | |
89 // trigger CHECKs if we can't read the file or if it's malformed. | |
90 scoped_ptr<media::WavAudioHandler> CreateWavAudioHandler( | 90 scoped_ptr<media::WavAudioHandler> CreateWavAudioHandler( |
91 const base::FilePath& wav_filename, const uint8* wav_file_data, | 91 const base::FilePath& wav_filename, const uint8* wav_file_data, |
92 size_t wav_file_length, const AudioParameters& expected_params) { | 92 size_t wav_file_length, const AudioParameters& expected_params) { |
93 base::StringPiece wav_data(reinterpret_cast<const char*>(wav_file_data), | 93 base::StringPiece wav_data(reinterpret_cast<const char*>(wav_file_data), |
94 wav_file_length); | 94 wav_file_length); |
95 scoped_ptr<media::WavAudioHandler> wav_audio_handler( | 95 scoped_ptr<media::WavAudioHandler> wav_audio_handler( |
96 new media::WavAudioHandler(wav_data)); | 96 new media::WavAudioHandler(wav_data)); |
97 | |
98 // Ensure the input file matches what the audio bus wants, otherwise bail out. | |
99 CHECK_EQ(wav_audio_handler->params().channels(), | |
100 expected_params.channels()) | |
101 << "Failed to read " << wav_filename.value() << " to fake device."; | |
102 CHECK_EQ(wav_audio_handler->params().sample_rate(), | |
103 expected_params.sample_rate()) | |
104 << "Failed to read " << wav_filename.value() << " to fake device."; | |
105 CHECK_EQ(wav_audio_handler->params().bits_per_sample(), | |
106 expected_params.bits_per_sample()) | |
107 << "Failed to read " << wav_filename.value() << " to fake device."; | |
108 | |
109 return wav_audio_handler.Pass(); | 97 return wav_audio_handler.Pass(); |
110 } | 98 } |
111 | 99 |
112 static base::LazyInstance<BeepContext> g_beep_context = | 100 static base::LazyInstance<BeepContext> g_beep_context = |
113 LAZY_INSTANCE_INITIALIZER; | 101 LAZY_INSTANCE_INITIALIZER; |
114 | 102 |
115 } // namespace | 103 } // namespace |
116 | 104 |
117 AudioInputStream* FakeAudioInputStream::MakeFakeStream( | 105 AudioInputStream* FakeAudioInputStream::MakeFakeStream( |
118 AudioManagerBase* manager, | 106 AudioManagerBase* manager, |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
201 void FakeAudioInputStream::OpenInFileMode(const base::FilePath& wav_filename) { | 189 void FakeAudioInputStream::OpenInFileMode(const base::FilePath& wav_filename) { |
202 CHECK(!wav_filename.empty()) | 190 CHECK(!wav_filename.empty()) |
203 << "You must pass the file to use as argument to --" | 191 << "You must pass the file to use as argument to --" |
204 << switches::kUseFileForFakeAudioCapture << "."; | 192 << switches::kUseFileForFakeAudioCapture << "."; |
205 | 193 |
206 // Read the file, and put its data in a scoped_ptr so it gets deleted later. | 194 // Read the file, and put its data in a scoped_ptr so it gets deleted later. |
207 size_t file_length = 0; | 195 size_t file_length = 0; |
208 wav_file_data_ = ReadWavFile(wav_filename, &file_length); | 196 wav_file_data_ = ReadWavFile(wav_filename, &file_length); |
209 wav_audio_handler_ = CreateWavAudioHandler( | 197 wav_audio_handler_ = CreateWavAudioHandler( |
210 wav_filename, wav_file_data_.get(), file_length, params_); | 198 wav_filename, wav_file_data_.get(), file_length, params_); |
| 199 |
| 200 // Hook us up so we pull in data from the file into the converter. We need to |
| 201 // modify the wav file's audio parameters since we'll be reading small slices |
| 202 // of it at a time and not the whole thing (like 10 ms at a time). |
| 203 AudioParameters file_audio_slice( |
| 204 wav_audio_handler_->params().format(), |
| 205 wav_audio_handler_->params().channel_layout(), |
| 206 wav_audio_handler_->params().sample_rate(), |
| 207 wav_audio_handler_->params().bits_per_sample(), |
| 208 params_.frames_per_buffer()); |
| 209 |
| 210 file_audio_converter_.reset( |
| 211 new AudioConverter(file_audio_slice, params_, false)); |
| 212 file_audio_converter_->AddInput(this); |
211 } | 213 } |
212 | 214 |
213 bool FakeAudioInputStream::PlayingFromFile() { | 215 bool FakeAudioInputStream::PlayingFromFile() { |
214 return wav_audio_handler_.get() != nullptr; | 216 return wav_audio_handler_.get() != nullptr; |
215 } | 217 } |
216 | 218 |
217 void FakeAudioInputStream::PlayFile() { | 219 void FakeAudioInputStream::PlayFile() { |
218 // Stop playing if we've played out the whole file. | 220 // Stop playing if we've played out the whole file. |
219 if (wav_audio_handler_->AtEnd(wav_file_read_pos_)) | 221 if (wav_audio_handler_->AtEnd(wav_file_read_pos_)) |
220 return; | 222 return; |
221 | 223 |
222 // Unfilled frames will be zeroed by CopyTo. | 224 file_audio_converter_->Convert(audio_bus_.get()); |
223 size_t bytes_written; | |
224 wav_audio_handler_->CopyTo(audio_bus_.get(), wav_file_read_pos_, | |
225 &bytes_written); | |
226 wav_file_read_pos_ += bytes_written; | |
227 callback_->OnData(this, audio_bus_.get(), buffer_size_, 1.0); | 225 callback_->OnData(this, audio_bus_.get(), buffer_size_, 1.0); |
228 } | 226 } |
229 | 227 |
230 void FakeAudioInputStream::PlayBeep() { | 228 void FakeAudioInputStream::PlayBeep() { |
231 // Accumulate the time from the last beep. | 229 // Accumulate the time from the last beep. |
232 interval_from_last_beep_ += TimeTicks::Now() - last_callback_time_; | 230 interval_from_last_beep_ += TimeTicks::Now() - last_callback_time_; |
233 | 231 |
234 memset(buffer_.get(), 0, buffer_size_); | 232 memset(buffer_.get(), 0, buffer_size_); |
235 bool should_beep = false; | 233 bool should_beep = false; |
236 { | 234 { |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
314 bool FakeAudioInputStream::GetAutomaticGainControl() { | 312 bool FakeAudioInputStream::GetAutomaticGainControl() { |
315 return false; | 313 return false; |
316 } | 314 } |
317 | 315 |
318 // static | 316 // static |
319 void FakeAudioInputStream::BeepOnce() { | 317 void FakeAudioInputStream::BeepOnce() { |
320 BeepContext* beep_context = g_beep_context.Pointer(); | 318 BeepContext* beep_context = g_beep_context.Pointer(); |
321 beep_context->SetBeepOnce(true); | 319 beep_context->SetBeepOnce(true); |
322 } | 320 } |
323 | 321 |
| 322 double FakeAudioInputStream::ProvideInput(AudioBus* audio_bus_into_converter, |
| 323 base::TimeDelta buffer_delay) { |
| 324 // Unfilled frames will be zeroed by CopyTo. |
| 325 size_t bytes_written; |
| 326 wav_audio_handler_->CopyTo(audio_bus_into_converter, wav_file_read_pos_, |
| 327 &bytes_written); |
| 328 wav_file_read_pos_ += bytes_written; |
| 329 return 1.0; |
| 330 }; |
| 331 |
324 } // namespace media | 332 } // namespace media |
OLD | NEW |