OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/audio_debug_file_writer.h" | 5 #include "media/audio/audio_debug_file_writer.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 #include <array> | 8 #include <array> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
11 #include "base/bind.h" | 11 #include "base/bind.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/memory/ptr_util.h" | 13 #include "base/memory/ptr_util.h" |
14 #include "base/sys_byteorder.h" | 14 #include "base/sys_byteorder.h" |
15 #include "media/base/audio_bus.h" | 15 #include "media/base/audio_bus.h" |
| 16 #include "media/base/audio_sample_types.h" |
16 | 17 |
17 namespace media { | 18 namespace media { |
18 | 19 |
19 namespace { | 20 namespace { |
20 | 21 |
21 // Windows WAVE format header | 22 // Windows WAVE format header |
22 // Byte order: Little-endian | 23 // Byte order: Little-endian |
23 // Offset Length Content | 24 // Offset Length Content |
24 // 0 4 "RIFF" | 25 // 0 4 "RIFF" |
25 // 4 4 <file length - 8> | 26 // 4 4 <file length - 8> |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
163 void WriteHeader(); | 164 void WriteHeader(); |
164 | 165 |
165 void CreateRecordingFile(const base::FilePath& file_name); | 166 void CreateRecordingFile(const base::FilePath& file_name); |
166 | 167 |
167 // The file to write to. | 168 // The file to write to. |
168 base::File file_; | 169 base::File file_; |
169 | 170 |
170 // Number of written samples. | 171 // Number of written samples. |
171 uint64_t samples_; | 172 uint64_t samples_; |
172 | 173 |
173 // Input audio parameters required to build wave header. | 174 // Audio parameters required to build wave header. Number of channels and |
| 175 // sample rate are used. |
174 const AudioParameters params_; | 176 const AudioParameters params_; |
175 | 177 |
176 // Intermediate buffer to be written to file. Interleaved 16 bit audio data. | 178 // Intermediate buffer to be written to file. Interleaved 16 bit audio data. |
177 std::unique_ptr<int16_t[]> interleaved_data_; | 179 std::unique_ptr<int16_t[]> interleaved_data_; |
178 int interleaved_data_size_; | 180 int interleaved_data_size_; |
179 | 181 |
180 // The task runner this class operates on. | 182 // The task runner this class operates on. |
181 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; | 183 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
182 }; | 184 }; |
183 | 185 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
223 base::Unretained(file_writer.get()), file_name)); | 225 base::Unretained(file_writer.get()), file_name)); |
224 return file_writer; | 226 return file_writer; |
225 } | 227 } |
226 | 228 |
227 AudioDebugFileWriter::AudioFileWriter::AudioFileWriter( | 229 AudioDebugFileWriter::AudioFileWriter::AudioFileWriter( |
228 const AudioParameters& params, | 230 const AudioParameters& params, |
229 scoped_refptr<base::SingleThreadTaskRunner> task_runner) | 231 scoped_refptr<base::SingleThreadTaskRunner> task_runner) |
230 : samples_(0), | 232 : samples_(0), |
231 params_(params), | 233 params_(params), |
232 interleaved_data_size_(0), | 234 interleaved_data_size_(0), |
233 task_runner_(std::move(task_runner)) { | 235 task_runner_(std::move(task_runner)) {} |
234 DCHECK_EQ(params.bits_per_sample(), kBytesPerSample * 8); | |
235 } | |
236 | 236 |
237 AudioDebugFileWriter::AudioFileWriter::~AudioFileWriter() { | 237 AudioDebugFileWriter::AudioFileWriter::~AudioFileWriter() { |
238 DCHECK(task_runner_->BelongsToCurrentThread()); | 238 DCHECK(task_runner_->BelongsToCurrentThread()); |
239 if (file_.IsValid()) | 239 if (file_.IsValid()) |
240 WriteHeader(); | 240 WriteHeader(); |
241 } | 241 } |
242 | 242 |
243 void AudioDebugFileWriter::AudioFileWriter::Write(const AudioBus* data) { | 243 void AudioDebugFileWriter::AudioFileWriter::Write(const AudioBus* data) { |
244 DCHECK(task_runner_->BelongsToCurrentThread()); | 244 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 245 DCHECK_EQ(params_.channels(), data->channels()); |
245 if (!file_.IsValid()) | 246 if (!file_.IsValid()) |
246 return; | 247 return; |
247 | 248 |
248 // Convert to 16 bit audio and write to file. | 249 // Convert to 16 bit audio and write to file. |
249 int data_size = data->frames() * data->channels(); | 250 int data_size = data->frames() * data->channels(); |
250 if (!interleaved_data_ || interleaved_data_size_ < data_size) { | 251 if (!interleaved_data_ || interleaved_data_size_ < data_size) { |
251 interleaved_data_.reset(new int16_t[data_size]); | 252 interleaved_data_.reset(new int16_t[data_size]); |
252 interleaved_data_size_ = data_size; | 253 interleaved_data_size_ = data_size; |
253 } | 254 } |
254 samples_ += data_size; | 255 samples_ += data_size; |
255 data->ToInterleaved(data->frames(), sizeof(interleaved_data_[0]), | 256 data->ToInterleaved<media::SignedInt16SampleTypeTraits>( |
256 interleaved_data_.get()); | 257 data->frames(), interleaved_data_.get()); |
257 | 258 |
258 #ifndef ARCH_CPU_LITTLE_ENDIAN | 259 #ifndef ARCH_CPU_LITTLE_ENDIAN |
259 static_assert(sizeof(interleaved_data_[0]) == sizeof(uint16_t), | 260 static_assert(sizeof(interleaved_data_[0]) == sizeof(uint16_t), |
260 "Only 2 bytes per channel is supported."); | 261 "Only 2 bytes per channel is supported."); |
261 for (int i = 0; i < data_size; ++i) | 262 for (int i = 0; i < data_size; ++i) |
262 interleaved_data_[i] = base::ByteSwapToLE16(interleaved_data_[i]); | 263 interleaved_data_[i] = base::ByteSwapToLE16(interleaved_data_[i]); |
263 #endif | 264 #endif |
264 | 265 |
265 file_.WriteAtCurrentPos(reinterpret_cast<char*>(interleaved_data_.get()), | 266 file_.WriteAtCurrentPos(reinterpret_cast<char*>(interleaved_data_.get()), |
266 data_size * sizeof(interleaved_data_[0])); | 267 data_size * sizeof(interleaved_data_[0])); |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
342 | 343 |
343 bool AudioDebugFileWriter::WillWrite() { | 344 bool AudioDebugFileWriter::WillWrite() { |
344 // Note that if this is called from any place other than | 345 // Note that if this is called from any place other than |
345 // |client_sequence_checker_| then there is a data race here, but it's fine, | 346 // |client_sequence_checker_| then there is a data race here, but it's fine, |
346 // because Write() will check for |file_writer_|. So, we are not very precise | 347 // because Write() will check for |file_writer_|. So, we are not very precise |
347 // here, but it's fine: we can afford missing some data or scheduling some | 348 // here, but it's fine: we can afford missing some data or scheduling some |
348 // no-op writes. | 349 // no-op writes. |
349 return !!file_writer_; | 350 return !!file_writer_; |
350 } | 351 } |
351 | 352 |
| 353 const base::FilePath::CharType* AudioDebugFileWriter::GetFileNameExtension() { |
| 354 return FILE_PATH_LITERAL("wav"); |
| 355 } |
| 356 |
352 } // namspace media | 357 } // namspace media |
OLD | NEW |