summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorslan <slan@chromium.org>2015-04-20 12:39:14 -0700
committerCommit bot <commit-bot@chromium.org>2015-04-20 19:39:25 +0000
commit43a1d72b243b3762cf04af4cf75aa53744a31f8a (patch)
tree84aecdef8159374ab55ef679336de608b4520964
parent901d507acf54e758902e3f857640f74938a429ac (diff)
downloadchromium_src-43a1d72b243b3762cf04af4cf75aa53744a31f8a.zip
chromium_src-43a1d72b243b3762cf04af4cf75aa53744a31f8a.tar.gz
chromium_src-43a1d72b243b3762cf04af4cf75aa53744a31f8a.tar.bz2
WavAudioHandler no longer keeps state with AudioParameters.
Keeping internal state with AudioParameters was causing ambiguity among callers of WavAudioHandler, particularly in longer wav files, where the total number of frames exceeded default buffer lengths (1024 frames in many cases). Construction of AudioParameters, which is intended to describe an audio stream rather than an audio file, has been moved outside of WavAudioHandler, and replaced by explicit accessors for parameters describing the wav audio chunk. Context (Google internal): https://eureka-internal-review.git.corp.google.com/#/c/21997/ BUG=b/16680624 Review URL: https://codereview.chromium.org/1063633008 Cr-Commit-Position: refs/heads/master@{#325894}
-rw-r--r--chrome/browser/media/webrtc_browsertest_audio.cc19
-rw-r--r--media/audio/simple_sources.cc9
-rw-r--r--media/audio/sounds/audio_stream_handler.cc19
-rw-r--r--media/audio/sounds/sounds_manager.cc2
-rw-r--r--media/audio/sounds/wav_audio_handler.cc30
-rw-r--r--media/audio/sounds/wav_audio_handler.h19
-rw-r--r--media/audio/sounds/wav_audio_handler_unittest.cc12
7 files changed, 60 insertions, 50 deletions
diff --git a/chrome/browser/media/webrtc_browsertest_audio.cc b/chrome/browser/media/webrtc_browsertest_audio.cc
index 6dc07aa..41cbc7ea 100644
--- a/chrome/browser/media/webrtc_browsertest_audio.cc
+++ b/chrome/browser/media/webrtc_browsertest_audio.cc
@@ -6,6 +6,7 @@
#include "base/files/file.h"
#include "base/files/file_path.h"
+#include "media/audio/audio_parameters.h"
#include "media/audio/audio_power_monitor.h"
#include "media/audio/sounds/wav_audio_handler.h"
#include "media/base/audio_bus.h"
@@ -60,10 +61,9 @@ float ComputeAudioEnergyForWavFile(const base::FilePath& wav_filename,
scoped_ptr<media::WavAudioHandler> wav_audio_handler = CreateWavAudioHandler(
wav_filename, wav_file_data.get(), file_length);
- scoped_ptr<media::AudioBus> audio_bus =
- media::AudioBus::Create(wav_audio_handler->params());
- base::TimeDelta file_duration =
- wav_audio_handler->params().GetBufferDuration();
+ scoped_ptr<media::AudioBus> audio_bus = media::AudioBus::Create(
+ wav_audio_handler->num_channels(), wav_audio_handler->total_frames());
+ base::TimeDelta file_duration = wav_audio_handler->GetDuration();
size_t bytes_written;
wav_audio_handler->CopyTo(audio_bus.get(), 0, &bytes_written);
@@ -72,11 +72,16 @@ float ComputeAudioEnergyForWavFile(const base::FilePath& wav_filename,
// Set the filter coefficient to the whole file's duration; this will make the
// power monitor take the entire file into account.
- media::AudioPowerMonitor power_monitor(
- wav_audio_handler->params().sample_rate(), file_duration);
+ media::AudioPowerMonitor power_monitor(wav_audio_handler->sample_rate(),
+ file_duration);
power_monitor.Scan(*audio_bus, audio_bus->frames());
- *file_parameters = wav_audio_handler->params();
+ file_parameters->Reset(
+ media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
+ media::GuessChannelLayout(wav_audio_handler->num_channels()),
+ wav_audio_handler->num_channels(), wav_audio_handler->sample_rate(),
+ wav_audio_handler->bits_per_sample(), wav_audio_handler->total_frames());
+
return power_monitor.ReadCurrentPowerAndClip().first;
}
diff --git a/media/audio/simple_sources.cc b/media/audio/simple_sources.cc
index caf4c4c..877f9fd 100644
--- a/media/audio/simple_sources.cc
+++ b/media/audio/simple_sources.cc
@@ -186,10 +186,9 @@ void FileSource::LoadWavFile(const base::FilePath& path_to_wav_file) {
// modify the wav file's audio parameters since we'll be reading small slices
// of it at a time and not the whole thing (like 10 ms at a time).
AudioParameters file_audio_slice(
- wav_audio_handler_->params().format(),
- wav_audio_handler_->params().channel_layout(),
- wav_audio_handler_->params().sample_rate(),
- wav_audio_handler_->params().bits_per_sample(),
+ AudioParameters::AUDIO_PCM_LOW_LATENCY,
+ GuessChannelLayout(wav_audio_handler_->num_channels()),
+ wav_audio_handler_->sample_rate(), wav_audio_handler_->bits_per_sample(),
params_.frames_per_buffer());
file_audio_converter_.reset(
@@ -225,7 +224,7 @@ double FileSource::ProvideInput(AudioBus* audio_bus_into_converter,
&bytes_written);
wav_file_read_pos_ += bytes_written;
return 1.0;
-};
+}
void FileSource::OnError(AudioOutputStream* stream) {
}
diff --git a/media/audio/sounds/audio_stream_handler.cc b/media/audio/sounds/audio_stream_handler.cc
index ac9c87b..28758b2 100644
--- a/media/audio/sounds/audio_stream_handler.cc
+++ b/media/audio/sounds/audio_stream_handler.cc
@@ -36,7 +36,7 @@ AudioOutputStream::AudioSourceCallback* g_audio_source_for_testing = NULL;
class AudioStreamHandler::AudioStreamContainer
: public AudioOutputStream::AudioSourceCallback {
public:
- AudioStreamContainer(const WavAudioHandler& wav_audio)
+ explicit AudioStreamContainer(const WavAudioHandler& wav_audio)
: started_(false),
stream_(NULL),
cursor_(0),
@@ -51,12 +51,11 @@ class AudioStreamHandler::AudioStreamContainer
DCHECK(AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread());
if (!stream_) {
- const AudioParameters& p = wav_audio_.params();
- const AudioParameters params(AudioParameters::AUDIO_PCM_LOW_LATENCY,
- p.channel_layout(),
- p.sample_rate(),
- p.bits_per_sample(),
- kDefaultFrameCount);
+ const AudioParameters params(
+ AudioParameters::AUDIO_PCM_LOW_LATENCY,
+ GuessChannelLayout(wav_audio_.num_channels()),
+ wav_audio_.sample_rate(), wav_audio_.bits_per_sample(),
+ kDefaultFrameCount);
stream_ = AudioManager::Get()->MakeAudioOutputStreamProxy(params,
std::string());
if (!stream_ || !stream_->Open()) {
@@ -162,7 +161,11 @@ AudioStreamHandler::AudioStreamHandler(const base::StringPiece& wav_data)
LOG(ERROR) << "Can't get access to audio manager.";
return;
}
- if (!wav_audio_.params().IsValid()) {
+ const AudioParameters params(
+ AudioParameters::AUDIO_PCM_LOW_LATENCY,
+ GuessChannelLayout(wav_audio_.num_channels()), wav_audio_.sample_rate(),
+ wav_audio_.bits_per_sample(), kDefaultFrameCount);
+ if (!params.IsValid()) {
LOG(ERROR) << "Audio params are invalid.";
return;
}
diff --git a/media/audio/sounds/sounds_manager.cc b/media/audio/sounds/sounds_manager.cc
index 58ca238..72a7a3b 100644
--- a/media/audio/sounds/sounds_manager.cc
+++ b/media/audio/sounds/sounds_manager.cc
@@ -73,7 +73,7 @@ base::TimeDelta SoundsManagerImpl::GetDuration(SoundKey key) {
return base::TimeDelta();
}
const WavAudioHandler& wav_audio = handlers_[key]->wav_audio_handler();
- return wav_audio.params().GetBufferDuration();
+ return wav_audio.GetDuration();
}
} // namespace
diff --git a/media/audio/sounds/wav_audio_handler.cc b/media/audio/sounds/wav_audio_handler.cc
index b87baa8..c980839 100644
--- a/media/audio/sounds/wav_audio_handler.cc
+++ b/media/audio/sounds/wav_audio_handler.cc
@@ -55,9 +55,7 @@ T ReadInt(const base::StringPiece& data, size_t offset) {
namespace media {
WavAudioHandler::WavAudioHandler(const base::StringPiece& wav_data)
- : num_channels_(0),
- sample_rate_(0),
- bits_per_sample_(0) {
+ : num_channels_(0), sample_rate_(0), bits_per_sample_(0), total_frames_(0) {
CHECK_LE(kWavFileHeaderSize, wav_data.size()) << "wav data is too small";
CHECK(wav_data.starts_with(kChunkId) &&
memcmp(wav_data.data() + 8, kFormat, 4) == 0)
@@ -72,12 +70,7 @@ WavAudioHandler::WavAudioHandler(const base::StringPiece& wav_data)
offset += length;
}
- const int frame_count = data_.size() * 8 / num_channels_ / bits_per_sample_;
- params_ = AudioParameters(AudioParameters::AUDIO_PCM_LOW_LATENCY,
- GuessChannelLayout(num_channels_),
- sample_rate_,
- bits_per_sample_,
- frame_count);
+ total_frames_ = data_.size() * 8 / num_channels_ / bits_per_sample_;
}
WavAudioHandler::~WavAudioHandler() {}
@@ -91,24 +84,29 @@ bool WavAudioHandler::CopyTo(AudioBus* bus,
size_t* bytes_written) const {
if (!bus)
return false;
- if (bus->channels() != params_.channels()) {
- DVLOG(1) << "Number of channel mismatch.";
+ if (bus->channels() != num_channels_) {
+ DVLOG(1) << "Number of channels mismatch.";
return false;
}
if (AtEnd(cursor)) {
bus->Zero();
return true;
}
- const int remaining_frames =
- (data_.size() - cursor) / params_.GetBytesPerFrame();
+ const int bytes_per_frame = num_channels_ * bits_per_sample_ / 8;
+ const int remaining_frames = (data_.size() - cursor) / bytes_per_frame;
const int frames = std::min(bus->frames(), remaining_frames);
- bus->FromInterleaved(data_.data() + cursor, frames,
- params_.bits_per_sample() / 8);
- *bytes_written = frames * params_.GetBytesPerFrame();
+
+ bus->FromInterleaved(data_.data() + cursor, frames, bits_per_sample_ / 8);
+ *bytes_written = frames * bytes_per_frame;
bus->ZeroFramesPartial(frames, bus->frames() - frames);
return true;
}
+base::TimeDelta WavAudioHandler::GetDuration() const {
+ return base::TimeDelta::FromSecondsD(total_frames_ /
+ static_cast<double>(sample_rate_));
+}
+
int WavAudioHandler::ParseSubChunk(const base::StringPiece& data) {
if (data.size() < kChunkHeaderSize)
return data.size();
diff --git a/media/audio/sounds/wav_audio_handler.h b/media/audio/sounds/wav_audio_handler.h
index 82b5cc5..6e404fa 100644
--- a/media/audio/sounds/wav_audio_handler.h
+++ b/media/audio/sounds/wav_audio_handler.h
@@ -7,7 +7,6 @@
#include "base/strings/string_piece.h"
#include "base/time/time.h"
-#include "media/audio/audio_parameters.h"
#include "media/base/media_export.h"
namespace media {
@@ -29,8 +28,15 @@ class MEDIA_EXPORT WavAudioHandler {
// |bytes_written|. |bytes_written| should not be NULL.
bool CopyTo(AudioBus* bus, size_t cursor, size_t* bytes_written) const;
- const AudioParameters& params() const { return params_; }
+ // Accessors.
const base::StringPiece& data() const { return data_; }
+ uint16_t num_channels() const { return num_channels_; }
+ uint32_t sample_rate() const { return sample_rate_; }
+ uint16_t bits_per_sample() const { return bits_per_sample_; }
+ uint32_t total_frames() const { return total_frames_; }
+
+ // Returns the duration of the entire audio chunk.
+ base::TimeDelta GetDuration() const;
private:
// Parses a chunk of wav format data. Returns the length of the chunk.
@@ -45,11 +51,10 @@ class MEDIA_EXPORT WavAudioHandler {
// Data part of the |wav_data_|.
base::StringPiece data_;
- AudioParameters params_;
-
- uint16 num_channels_;
- uint32 sample_rate_;
- uint16 bits_per_sample_;
+ uint16_t num_channels_;
+ uint32_t sample_rate_;
+ uint16_t bits_per_sample_;
+ uint32_t total_frames_;
};
} // namespace media
diff --git a/media/audio/sounds/wav_audio_handler_unittest.cc b/media/audio/sounds/wav_audio_handler_unittest.cc
index 6098b93..d4ec83a 100644
--- a/media/audio/sounds/wav_audio_handler_unittest.cc
+++ b/media/audio/sounds/wav_audio_handler_unittest.cc
@@ -16,18 +16,18 @@ namespace media {
TEST(WavAudioHandlerTest, SampleDataTest) {
WavAudioHandler handler(base::StringPiece(kTestAudioData,
arraysize(kTestAudioData)));
- const AudioParameters& params = handler.params();
- ASSERT_EQ(2, params.channels());
- ASSERT_EQ(16, params.bits_per_sample());
- ASSERT_EQ(48000, params.sample_rate());
- ASSERT_EQ(192000, params.GetBytesPerSecond());
+ ASSERT_EQ(2u, handler.num_channels());
+ ASSERT_EQ(16u, handler.bits_per_sample());
+ ASSERT_EQ(48000u, handler.sample_rate());
+ ASSERT_EQ(1u, handler.total_frames());
+ ASSERT_EQ(20u, handler.GetDuration().InMicroseconds());
ASSERT_EQ(4U, handler.data().size());
const char kData[] = "\x01\x00\x01\x00";
ASSERT_EQ(base::StringPiece(kData, arraysize(kData) - 1), handler.data());
scoped_ptr<AudioBus> bus = AudioBus::Create(
- params.channels(), handler.data().size() / params.channels());
+ handler.num_channels(), handler.data().size() / handler.num_channels());
size_t bytes_written;
ASSERT_TRUE(handler.CopyTo(bus.get(), 0, &bytes_written));