summaryrefslogtreecommitdiffstats
path: root/chrome/browser/media/webrtc_browsertest_audio.cc
blob: 41cbc7eadc98853b277d1bb6afbbefcd8301199f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
// 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_browsertest_audio.h"

#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"

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|.
scoped_ptr<uint8[]> 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;
  }

  size_t wav_file_length = wav_file.GetLength();

  uint8* wav_file_data = new uint8[wav_file_length];
  size_t read_bytes = wav_file.Read(0, reinterpret_cast<char*>(wav_file_data),
                                    wav_file_length);
  if (read_bytes != wav_file_length) {
    CHECK(false) << "Failed to read all bytes of " << wav_filename.value();
    return nullptr;
  }
  *file_length = wav_file_length;
  return scoped_ptr<uint8[]>(wav_file_data);
}

scoped_ptr<media::WavAudioHandler> CreateWavAudioHandler(
    const base::FilePath& wav_filename, const uint8* wav_file_data,
    size_t wav_file_length) {
  base::StringPiece wav_data(reinterpret_cast<const char*>(wav_file_data),
                             wav_file_length);
  scoped_ptr<media::WavAudioHandler> wav_audio_handler(
      new media::WavAudioHandler(wav_data));

  return wav_audio_handler.Pass();
}

}  // 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;
  scoped_ptr<uint8[]> wav_file_data = ReadWavFile(wav_filename, &file_length);
  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->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->num_channels(), wav_audio_handler->sample_rate(),
      wav_audio_handler->bits_per_sample(), wav_audio_handler->total_frames());

  return power_monitor.ReadCurrentPowerAndClip().first;
}

}  // namespace test