| 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 // MSVC++ requires this to be set before any other includes to get M_PI. | 4 // MSVC++ requires this to be set before any other includes to get M_PI. |
| 5 #define _USE_MATH_DEFINES | 5 #define _USE_MATH_DEFINES |
| 6 #include <cmath> | 6 #include <cmath> |
| 7 | 7 |
| 8 #include "media/audio/simple_sources.h" | 8 #include "media/audio/simple_sources.h" |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| 11 | 11 |
| 12 #include "base/files/file.h" | 12 #include "base/files/file.h" |
| 13 #include "base/lazy_instance.h" | 13 #include "base/lazy_instance.h" |
| 14 #include "base/logging.h" | 14 #include "base/logging.h" |
| 15 #include "media/audio/sounds/wav_audio_handler.h" | 15 #include "media/audio/sounds/wav_audio_handler.h" |
| 16 #include "media/base/audio_bus.h" | 16 #include "media/base/audio_bus.h" |
| 17 | 17 |
| 18 namespace media { | 18 namespace media { |
| 19 | 19 |
| 20 // Opens |wav_filename|, reads it and loads it as a wav file. This function will | 20 // Opens |wav_filename|, reads it and loads it as a wav file. This function will |
| 21 // bluntly trigger CHECKs if we can't read the file or if it's malformed. The | 21 // return a null pointer if we can't read the file or if it's malformed. The |
| 22 // caller takes ownership of the returned data. The size of the data is stored | 22 // caller takes ownership of the returned data. The size of the data is stored |
| 23 // in |read_length|. | 23 // in |read_length|. |
| 24 static scoped_ptr<uint8[]> ReadWavFile(const base::FilePath& wav_filename, | 24 static scoped_ptr<uint8[]> ReadWavFile(const base::FilePath& wav_filename, |
| 25 size_t* file_length) { | 25 size_t* file_length) { |
| 26 base::File wav_file( | 26 base::File wav_file( |
| 27 wav_filename, base::File::FLAG_OPEN | base::File::FLAG_READ); | 27 wav_filename, base::File::FLAG_OPEN | base::File::FLAG_READ); |
| 28 CHECK(wav_file.IsValid()) | 28 if (!wav_file.IsValid()) { |
| 29 << "Failed to read " << wav_filename.value() | 29 LOG(ERROR) << "Failed to read " << wav_filename.value() |
| 30 << " as input to the fake device."; | 30 << " as input to the fake device."; |
| 31 return nullptr; |
| 32 } |
| 31 | 33 |
| 32 size_t wav_file_length = wav_file.GetLength(); | 34 size_t wav_file_length = wav_file.GetLength(); |
| 33 CHECK_GT(wav_file_length, 0u) | 35 if (wav_file_length == 0u) { |
| 34 << "Input file to fake device is empty: " << wav_filename.value(); | 36 LOG(ERROR) << "Input file to fake device is empty: " |
| 37 << wav_filename.value(); |
| 38 return nullptr; |
| 39 } |
| 35 | 40 |
| 36 uint8* wav_file_data = new uint8[wav_file_length]; | 41 uint8* wav_file_data = new uint8[wav_file_length]; |
| 37 size_t read_bytes = wav_file.Read(0, reinterpret_cast<char*>(wav_file_data), | 42 size_t read_bytes = wav_file.Read(0, reinterpret_cast<char*>(wav_file_data), |
| 38 wav_file_length); | 43 wav_file_length); |
| 39 CHECK_EQ(read_bytes, wav_file_length) | 44 if (read_bytes != wav_file_length) { |
| 40 << "Failed to read all bytes of " << wav_filename.value(); | 45 LOG(ERROR) << "Failed to read all bytes of " << wav_filename.value(); |
| 46 return nullptr; |
| 47 } |
| 41 *file_length = wav_file_length; | 48 *file_length = wav_file_length; |
| 42 return scoped_ptr<uint8[]>(wav_file_data); | 49 return scoped_ptr<uint8[]>(wav_file_data); |
| 43 } | 50 } |
| 44 | 51 |
| 45 // Opens |wav_filename|, reads it and loads it as a wav file. This function will | 52 // Opens |wav_filename|, reads it and loads it as a wav file. This function will |
| 46 // bluntly trigger CHECKs if we can't read the file or if it's malformed. | 53 // bluntly trigger CHECKs if we can't read the file or if it's malformed. |
| 47 static scoped_ptr<WavAudioHandler> CreateWavAudioHandler( | 54 static scoped_ptr<WavAudioHandler> CreateWavAudioHandler( |
| 48 const base::FilePath& wav_filename, const uint8* wav_file_data, | 55 const base::FilePath& wav_filename, const uint8* wav_file_data, |
| 49 size_t wav_file_length, const AudioParameters& expected_params) { | 56 size_t wav_file_length, const AudioParameters& expected_params) { |
| 50 base::StringPiece wav_data(reinterpret_cast<const char*>(wav_file_data), | 57 base::StringPiece wav_data(reinterpret_cast<const char*>(wav_file_data), |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 145 | 152 |
| 146 void SineWaveAudioSource::Reset() { | 153 void SineWaveAudioSource::Reset() { |
| 147 base::AutoLock auto_lock(time_lock_); | 154 base::AutoLock auto_lock(time_lock_); |
| 148 time_state_ = 0; | 155 time_state_ = 0; |
| 149 } | 156 } |
| 150 | 157 |
| 151 FileSource::FileSource(const AudioParameters& params, | 158 FileSource::FileSource(const AudioParameters& params, |
| 152 const base::FilePath& path_to_wav_file) | 159 const base::FilePath& path_to_wav_file) |
| 153 : params_(params), | 160 : params_(params), |
| 154 path_to_wav_file_(path_to_wav_file), | 161 path_to_wav_file_(path_to_wav_file), |
| 155 wav_file_read_pos_(0) { | 162 wav_file_read_pos_(0), |
| 163 load_failed_(false) { |
| 156 } | 164 } |
| 157 | 165 |
| 158 FileSource::~FileSource() { | 166 FileSource::~FileSource() { |
| 159 } | 167 } |
| 160 | 168 |
| 161 void FileSource::LoadWavFile(const base::FilePath& path_to_wav_file) { | 169 void FileSource::LoadWavFile(const base::FilePath& path_to_wav_file) { |
| 170 // Don't try again if we already failed. |
| 171 if (load_failed_) |
| 172 return; |
| 173 |
| 162 // Read the file, and put its data in a scoped_ptr so it gets deleted later. | 174 // Read the file, and put its data in a scoped_ptr so it gets deleted later. |
| 163 size_t file_length = 0; | 175 size_t file_length = 0; |
| 164 wav_file_data_ = ReadWavFile(path_to_wav_file, &file_length); | 176 wav_file_data_ = ReadWavFile(path_to_wav_file, &file_length); |
| 177 if (!wav_file_data_) { |
| 178 load_failed_ = true; |
| 179 return; |
| 180 } |
| 181 |
| 165 wav_audio_handler_ = CreateWavAudioHandler( | 182 wav_audio_handler_ = CreateWavAudioHandler( |
| 166 path_to_wav_file, wav_file_data_.get(), file_length, params_); | 183 path_to_wav_file, wav_file_data_.get(), file_length, params_); |
| 167 | 184 |
| 168 // Hook us up so we pull in data from the file into the converter. We need to | 185 // Hook us up so we pull in data from the file into the converter. We need to |
| 169 // modify the wav file's audio parameters since we'll be reading small slices | 186 // modify the wav file's audio parameters since we'll be reading small slices |
| 170 // of it at a time and not the whole thing (like 10 ms at a time). | 187 // of it at a time and not the whole thing (like 10 ms at a time). |
| 171 AudioParameters file_audio_slice( | 188 AudioParameters file_audio_slice( |
| 172 wav_audio_handler_->params().format(), | 189 wav_audio_handler_->params().format(), |
| 173 wav_audio_handler_->params().channel_layout(), | 190 wav_audio_handler_->params().channel_layout(), |
| 174 wav_audio_handler_->params().sample_rate(), | 191 wav_audio_handler_->params().sample_rate(), |
| 175 wav_audio_handler_->params().bits_per_sample(), | 192 wav_audio_handler_->params().bits_per_sample(), |
| 176 params_.frames_per_buffer()); | 193 params_.frames_per_buffer()); |
| 177 | 194 |
| 178 file_audio_converter_.reset( | 195 file_audio_converter_.reset( |
| 179 new AudioConverter(file_audio_slice, params_, false)); | 196 new AudioConverter(file_audio_slice, params_, false)); |
| 180 file_audio_converter_->AddInput(this); | 197 file_audio_converter_->AddInput(this); |
| 181 } | 198 } |
| 182 | 199 |
| 183 int FileSource::OnMoreData(AudioBus* audio_bus, uint32 total_bytes_delay) { | 200 int FileSource::OnMoreData(AudioBus* audio_bus, uint32 total_bytes_delay) { |
| 184 // Load the file if we haven't already. This load needs to happen on the | 201 // Load the file if we haven't already. This load needs to happen on the |
| 185 // audio thread, otherwise we'll run on the UI thread on Mac for instance. | 202 // audio thread, otherwise we'll run on the UI thread on Mac for instance. |
| 186 // This will massively delay the first OnMoreData, but we'll catch up. | 203 // This will massively delay the first OnMoreData, but we'll catch up. |
| 187 if (!wav_audio_handler_) | 204 if (!wav_audio_handler_) |
| 188 LoadWavFile(path_to_wav_file_); | 205 LoadWavFile(path_to_wav_file_); |
| 206 if (load_failed_) |
| 207 return 0; |
| 189 | 208 |
| 190 DCHECK(wav_audio_handler_.get()); | 209 DCHECK(wav_audio_handler_.get()); |
| 191 | 210 |
| 192 // Stop playing if we've played out the whole file. | 211 // Stop playing if we've played out the whole file. |
| 193 if (wav_audio_handler_->AtEnd(wav_file_read_pos_)) | 212 if (wav_audio_handler_->AtEnd(wav_file_read_pos_)) |
| 194 return 0; | 213 return 0; |
| 195 | 214 |
| 196 // This pulls data from ProvideInput. | 215 // This pulls data from ProvideInput. |
| 197 file_audio_converter_->Convert(audio_bus); | 216 file_audio_converter_->Convert(audio_bus); |
| 198 return audio_bus->frames(); | 217 return audio_bus->frames(); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 277 } | 296 } |
| 278 | 297 |
| 279 void BeepingSource::OnError(AudioOutputStream* stream) { | 298 void BeepingSource::OnError(AudioOutputStream* stream) { |
| 280 } | 299 } |
| 281 | 300 |
| 282 void BeepingSource::BeepOnce() { | 301 void BeepingSource::BeepOnce() { |
| 283 g_beep_context.Pointer()->SetBeepOnce(true); | 302 g_beep_context.Pointer()->SetBeepOnce(true); |
| 284 } | 303 } |
| 285 | 304 |
| 286 } // namespace media | 305 } // namespace media |
| OLD | NEW |