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 namespace { |
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 // return a null pointer 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 scoped_ptr<char[]> ReadWavFile(const base::FilePath& wav_filename, |
25 size_t* file_length) { | 25 size_t* read_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 if (!wav_file.IsValid()) { | 28 if (!wav_file.IsValid()) { |
29 LOG(ERROR) << "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; | 31 return nullptr; |
32 } | 32 } |
33 | 33 |
34 size_t wav_file_length = wav_file.GetLength(); | 34 size_t wav_file_length = wav_file.GetLength(); |
35 if (wav_file_length == 0u) { | 35 if (wav_file_length == 0u) { |
36 LOG(ERROR) << "Input file to fake device is empty: " | 36 LOG(ERROR) << "Input file to fake device is empty: " |
37 << wav_filename.value(); | 37 << wav_filename.value(); |
38 return nullptr; | 38 return nullptr; |
39 } | 39 } |
40 | 40 |
41 uint8* wav_file_data = new uint8[wav_file_length]; | 41 scoped_ptr<char[]> data(new char[wav_file_length]); |
42 size_t read_bytes = wav_file.Read(0, reinterpret_cast<char*>(wav_file_data), | 42 size_t read_bytes = wav_file.Read(0, data.get(), wav_file_length); |
43 wav_file_length); | |
44 if (read_bytes != wav_file_length) { | 43 if (read_bytes != wav_file_length) { |
45 LOG(ERROR) << "Failed to read all bytes of " << wav_filename.value(); | 44 LOG(ERROR) << "Failed to read all bytes of " << wav_filename.value(); |
46 return nullptr; | 45 return nullptr; |
47 } | 46 } |
48 *file_length = wav_file_length; | 47 *read_length = wav_file_length; |
49 return scoped_ptr<uint8[]>(wav_file_data); | 48 return data; |
50 } | |
51 | |
52 // Opens |wav_filename|, reads it and loads it as a wav file. This function will | |
53 // bluntly trigger CHECKs if we can't read the file or if it's malformed. | |
54 static scoped_ptr<WavAudioHandler> CreateWavAudioHandler( | |
55 const base::FilePath& wav_filename, const uint8* wav_file_data, | |
56 size_t wav_file_length, const AudioParameters& expected_params) { | |
57 base::StringPiece wav_data(reinterpret_cast<const char*>(wav_file_data), | |
58 wav_file_length); | |
59 scoped_ptr<WavAudioHandler> wav_audio_handler(new WavAudioHandler(wav_data)); | |
60 return wav_audio_handler.Pass(); | |
61 } | 49 } |
62 | 50 |
63 // These values are based on experiments for local-to-local | 51 // These values are based on experiments for local-to-local |
64 // PeerConnection to demonstrate audio/video synchronization. | 52 // PeerConnection to demonstrate audio/video synchronization. |
65 static const int kBeepDurationMilliseconds = 20; | 53 static const int kBeepDurationMilliseconds = 20; |
66 static const int kBeepFrequency = 400; | 54 static const int kBeepFrequency = 400; |
67 | 55 |
68 // Intervals between two automatic beeps. | 56 // Intervals between two automatic beeps. |
69 static const int kAutomaticBeepIntervalInMs = 500; | 57 static const int kAutomaticBeepIntervalInMs = 500; |
70 | 58 |
(...skipping 23 matching lines...) Expand all Loading... |
94 } | 82 } |
95 | 83 |
96 private: | 84 private: |
97 mutable base::Lock lock_; | 85 mutable base::Lock lock_; |
98 bool beep_once_; | 86 bool beep_once_; |
99 bool automatic_beep_; | 87 bool automatic_beep_; |
100 }; | 88 }; |
101 | 89 |
102 static base::LazyInstance<BeepContext>::Leaky g_beep_context = | 90 static base::LazyInstance<BeepContext>::Leaky g_beep_context = |
103 LAZY_INSTANCE_INITIALIZER; | 91 LAZY_INSTANCE_INITIALIZER; |
| 92 } // namespace |
104 | 93 |
105 ////////////////////////////////////////////////////////////////////////////// | 94 ////////////////////////////////////////////////////////////////////////////// |
106 // SineWaveAudioSource implementation. | 95 // SineWaveAudioSource implementation. |
107 | 96 |
108 SineWaveAudioSource::SineWaveAudioSource(int channels, | 97 SineWaveAudioSource::SineWaveAudioSource(int channels, |
109 double freq, double sample_freq) | 98 double freq, double sample_freq) |
110 : channels_(channels), | 99 : channels_(channels), |
111 f_(freq / sample_freq), | 100 f_(freq / sample_freq), |
112 time_state_(0), | 101 time_state_(0), |
113 cap_(0), | 102 cap_(0), |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
164 } | 153 } |
165 | 154 |
166 FileSource::~FileSource() { | 155 FileSource::~FileSource() { |
167 } | 156 } |
168 | 157 |
169 void FileSource::LoadWavFile(const base::FilePath& path_to_wav_file) { | 158 void FileSource::LoadWavFile(const base::FilePath& path_to_wav_file) { |
170 // Don't try again if we already failed. | 159 // Don't try again if we already failed. |
171 if (load_failed_) | 160 if (load_failed_) |
172 return; | 161 return; |
173 | 162 |
174 // Read the file, and put its data in a scoped_ptr so it gets deleted later. | 163 // Read the file, and put its data in a scoped_ptr so it gets deleted when |
175 size_t file_length = 0; | 164 // this class destructs. This data must be valid for the lifetime of |
176 wav_file_data_ = ReadWavFile(path_to_wav_file, &file_length); | 165 // |wav_audio_handler_|. |
177 if (!wav_file_data_) { | 166 size_t length = 0u; |
| 167 raw_wav_data_ = ReadWavFile(path_to_wav_file, &length); |
| 168 if (!raw_wav_data_) { |
178 load_failed_ = true; | 169 load_failed_ = true; |
179 return; | 170 return; |
180 } | 171 } |
181 | 172 |
182 wav_audio_handler_ = CreateWavAudioHandler( | 173 // Attempt to create a handler with this data. If the data is invalid, return. |
183 path_to_wav_file, wav_file_data_.get(), file_length, params_); | 174 wav_audio_handler_ = |
| 175 WavAudioHandler::Create(base::StringPiece(raw_wav_data_.get(), length)); |
| 176 if (!wav_audio_handler_) { |
| 177 LOG(ERROR) << "WAV data could be read but is not valid"; |
| 178 load_failed_ = true; |
| 179 return; |
| 180 } |
184 | 181 |
185 // Hook us up so we pull in data from the file into the converter. We need to | 182 // Hook us up so we pull in data from the file into the converter. We need to |
186 // modify the wav file's audio parameters since we'll be reading small slices | 183 // modify the wav file's audio parameters since we'll be reading small slices |
187 // of it at a time and not the whole thing (like 10 ms at a time). | 184 // of it at a time and not the whole thing (like 10 ms at a time). |
188 AudioParameters file_audio_slice( | 185 AudioParameters file_audio_slice( |
189 AudioParameters::AUDIO_PCM_LOW_LATENCY, | 186 AudioParameters::AUDIO_PCM_LOW_LATENCY, |
190 GuessChannelLayout(wav_audio_handler_->num_channels()), | 187 GuessChannelLayout(wav_audio_handler_->num_channels()), |
191 wav_audio_handler_->sample_rate(), wav_audio_handler_->bits_per_sample(), | 188 wav_audio_handler_->sample_rate(), wav_audio_handler_->bits_per_sample(), |
192 params_.frames_per_buffer()); | 189 params_.frames_per_buffer()); |
193 | 190 |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
295 } | 292 } |
296 | 293 |
297 void BeepingSource::OnError(AudioOutputStream* stream) { | 294 void BeepingSource::OnError(AudioOutputStream* stream) { |
298 } | 295 } |
299 | 296 |
300 void BeepingSource::BeepOnce() { | 297 void BeepingSource::BeepOnce() { |
301 g_beep_context.Pointer()->SetBeepOnce(true); | 298 g_beep_context.Pointer()->SetBeepOnce(true); |
302 } | 299 } |
303 | 300 |
304 } // namespace media | 301 } // namespace media |
OLD | NEW |