blob: 500fbec5af6c464aa1aa562412b9268a89aeee7d [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/media/webrtc/webrtc_browsertest_audio.h"
#include <stddef.h>
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "media/audio/audio_power_monitor.h"
#include "media/audio/sounds/wav_audio_handler.h"
#include "media/base/audio_bus.h"
#include "media/base/audio_parameters.h"
namespace {
// Opens |wav_filename|, reads it and loads it as a wav file. This function will
// bluntly trigger CHECKs if we can't read the file or if it's malformed. The
// caller takes ownership of the returned data. The size of the data is stored
// in |read_length|.
std::unique_ptr<char[]> ReadWavFile(const base::FilePath& wav_filename,
size_t* file_length) {
base::File wav_file(
wav_filename, base::File::FLAG_OPEN | base::File::FLAG_READ);
if (!wav_file.IsValid()) {
CHECK(false) << "Failed to read " << wav_filename.value();
return nullptr;
}
int64_t wav_file_length64 = wav_file.GetLength();
if (wav_file_length64 < 0) {
PLOG(ERROR) << "GetLength " << wav_file.GetPlatformFile();
return nullptr;
}
if (wav_file_length64 > std::numeric_limits<int>::max()) {
LOG(ERROR) << "File is too big: " << wav_filename.value();
return nullptr;
}
int wav_file_length = static_cast<int>(wav_file_length64);
if (!wav_file_length) {
LOG(ERROR) << "Input file is empty: " << wav_filename.value();
return nullptr;
}
std::unique_ptr<char[]> data(new char[wav_file_length]);
int read_bytes = wav_file.Read(0, data.get(), wav_file_length);
if (read_bytes != wav_file_length) {
LOG(ERROR) << "Failed to read all bytes of " << wav_filename.value();
return nullptr;
}
*file_length = wav_file_length;
return data;
}
} // namespace
namespace test {
float ComputeAudioEnergyForWavFile(const base::FilePath& wav_filename,
media::AudioParameters* file_parameters) {
// Read the file, and put its data in a scoped_ptr so it gets deleted later.
size_t file_length = 0;
std::unique_ptr<char[]> wav_file_data =
ReadWavFile(wav_filename, &file_length);
auto wav_audio_handler = media::WavAudioHandler::Create(
base::StringPiece(wav_file_data.get(), file_length));
std::unique_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);
CHECK_EQ(bytes_written, wav_audio_handler->data().size())
<< "Expected to write entire file into bus.";
// 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->sample_rate(),
file_duration);
power_monitor.Scan(*audio_bus, audio_bus->frames());
file_parameters->Reset(
media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
media::GuessChannelLayout(wav_audio_handler->num_channels()),
wav_audio_handler->sample_rate(), wav_audio_handler->total_frames());
file_parameters->set_channels_for_discrete(wav_audio_handler->num_channels());
return power_monitor.ReadCurrentPowerAndClip().first;
}
} // namespace test