sounds_manager.cc revision 0f1bc08d4cfcc34181b0b5cbf065c40f687bf740
1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "media/audio/sounds/sounds_manager.h"
6
7#include "base/command_line.h"
8#include "base/compiler_specific.h"
9#include "base/logging.h"
10#include "base/memory/linked_ptr.h"
11#include "base/memory/ref_counted.h"
12#include "base/message_loop/message_loop_proxy.h"
13#include "media/audio/audio_manager.h"
14#include "media/audio/sounds/audio_stream_handler.h"
15#include "media/base/media_switches.h"
16
17namespace media {
18
19namespace {
20
21SoundsManager* g_instance = NULL;
22
23// SoundsManagerImpl ---------------------------------------------------
24
25class SoundsManagerImpl : public SoundsManager {
26 public:
27  SoundsManagerImpl();
28  virtual ~SoundsManagerImpl();
29
30  // SoundsManager implementation:
31  virtual bool Initialize(
32      const std::vector<base::StringPiece>& resources) OVERRIDE;
33  virtual bool Play(Sound sound) OVERRIDE;
34  virtual base::TimeDelta GetDuration(Sound sound) OVERRIDE;
35
36 private:
37  std::vector<linked_ptr<AudioStreamHandler> > handlers_;
38  scoped_refptr<base::MessageLoopProxy> message_loop_;
39
40  DISALLOW_COPY_AND_ASSIGN(SoundsManagerImpl);
41};
42
43SoundsManagerImpl::SoundsManagerImpl()
44    : handlers_(SOUND_COUNT),
45      message_loop_(AudioManager::Get()->GetMessageLoop()) {
46}
47
48SoundsManagerImpl::~SoundsManagerImpl() {
49  DCHECK(CalledOnValidThread());
50}
51
52bool SoundsManagerImpl::Initialize(
53    const std::vector<base::StringPiece>& resources) {
54  if (resources.size() != static_cast<size_t>(SOUND_COUNT)) {
55    LOG(ERROR) << "Incorrect num of sounds.";
56    return false;
57  }
58  for (size_t i = 0; i < resources.size(); ++i) {
59    handlers_[i].reset(new AudioStreamHandler(resources[i]));
60    if (!handlers_[i]->IsInitialized()) {
61      LOG(WARNING) << "Can't initialize AudioStreamHandler for sound "
62                   << i << ".";
63      return false;
64    }
65  }
66  return true;
67}
68
69bool SoundsManagerImpl::Play(Sound sound) {
70  DCHECK(CalledOnValidThread());
71  DCHECK(sound < SOUND_COUNT);
72  if (!handlers_[sound].get() || !handlers_[sound]->IsInitialized())
73    return false;
74  return handlers_[sound]->Play();
75}
76
77base::TimeDelta SoundsManagerImpl::GetDuration(Sound sound) {
78  DCHECK(CalledOnValidThread());
79  if (sound >= SOUND_COUNT ||
80      !handlers_[sound].get() ||
81      !handlers_[sound]->IsInitialized()) {
82    return base::TimeDelta();
83  }
84  const WavAudioHandler& wav_audio = handlers_[sound]->wav_audio_handler();
85  const int64 size = wav_audio.size();
86  const int64 rate = wav_audio.byte_rate();
87  return base::TimeDelta::FromMicroseconds(size * 1000000 / rate);
88}
89
90// SoundsManagerStub ---------------------------------------------------
91
92class SoundsManagerStub : public SoundsManager {
93 public:
94  SoundsManagerStub();
95  virtual ~SoundsManagerStub();
96
97  // SoundsManager implementation:
98  virtual bool Initialize(
99      const std::vector<base::StringPiece>& resources) OVERRIDE;
100  virtual bool Play(Sound sound) OVERRIDE;
101  virtual base::TimeDelta GetDuration(Sound sound) OVERRIDE;
102
103 private:
104  DISALLOW_COPY_AND_ASSIGN(SoundsManagerStub);
105};
106
107SoundsManagerStub::SoundsManagerStub() {
108}
109
110SoundsManagerStub::~SoundsManagerStub() {
111  DCHECK(CalledOnValidThread());
112}
113
114bool SoundsManagerStub::Initialize(
115    const std::vector<base::StringPiece>& /* resources */) {
116  DCHECK(CalledOnValidThread());
117  return false;
118}
119
120bool SoundsManagerStub::Play(Sound /* sound */) {
121  DCHECK(CalledOnValidThread());
122  return false;
123}
124
125base::TimeDelta SoundsManagerStub::GetDuration(Sound /* sound */) {
126  DCHECK(CalledOnValidThread());
127  return base::TimeDelta();
128}
129
130}  // namespace
131
132SoundsManager::SoundsManager() {
133}
134
135SoundsManager::~SoundsManager() {
136  DCHECK(CalledOnValidThread());
137}
138
139// static
140void SoundsManager::Create() {
141  CHECK(!g_instance) << "SoundsManager::Create() is called twice";
142  const bool enabled = !CommandLine::ForCurrentProcess()->HasSwitch(
143      ::switches::kDisableSystemSoundsManager);
144  if (enabled)
145    g_instance = new SoundsManagerImpl();
146  else
147    g_instance = new SoundsManagerStub();
148}
149
150// static
151void SoundsManager::Shutdown() {
152  CHECK(g_instance) << "SoundsManager::Shutdown() is called "
153                    << "without previous call to Create()";
154  delete g_instance;
155  g_instance = NULL;
156}
157
158// static
159SoundsManager* SoundsManager::Get() {
160  CHECK(g_instance) << "SoundsManager::Get() is called before Create()";
161  return g_instance;
162}
163
164}  // namespace media
165