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.
5 #include "media/audio/sounds/sounds_manager.h"
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"
21 SoundsManager* g_instance = NULL;
23 // SoundsManagerImpl ---------------------------------------------------
25 class SoundsManagerImpl : public SoundsManager {
28 virtual ~SoundsManagerImpl();
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;
37 std::vector<linked_ptr<AudioStreamHandler> > handlers_;
38 scoped_refptr<base::MessageLoopProxy> message_loop_;
40 DISALLOW_COPY_AND_ASSIGN(SoundsManagerImpl);
43 SoundsManagerImpl::SoundsManagerImpl()
44 : handlers_(SOUND_COUNT),
45 message_loop_(AudioManager::Get()->GetMessageLoop()) {
48 SoundsManagerImpl::~SoundsManagerImpl() {
49 DCHECK(CalledOnValidThread());
52 bool 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.";
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 "
69 bool SoundsManagerImpl::Play(Sound sound) {
70 DCHECK(CalledOnValidThread());
71 DCHECK(sound < SOUND_COUNT);
72 if (!handlers_[sound].get() || !handlers_[sound]->IsInitialized())
74 return handlers_[sound]->Play();
77 base::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();
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);
90 // SoundsManagerStub ---------------------------------------------------
92 class SoundsManagerStub : public SoundsManager {
95 virtual ~SoundsManagerStub();
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;
104 DISALLOW_COPY_AND_ASSIGN(SoundsManagerStub);
107 SoundsManagerStub::SoundsManagerStub() {
110 SoundsManagerStub::~SoundsManagerStub() {
111 DCHECK(CalledOnValidThread());
114 bool SoundsManagerStub::Initialize(
115 const std::vector<base::StringPiece>& /* resources */) {
116 DCHECK(CalledOnValidThread());
120 bool SoundsManagerStub::Play(Sound /* sound */) {
121 DCHECK(CalledOnValidThread());
125 base::TimeDelta SoundsManagerStub::GetDuration(Sound /* sound */) {
126 DCHECK(CalledOnValidThread());
127 return base::TimeDelta();
132 SoundsManager::SoundsManager() {
135 SoundsManager::~SoundsManager() {
136 DCHECK(CalledOnValidThread());
140 void SoundsManager::Create() {
141 CHECK(!g_instance) << "SoundsManager::Create() is called twice";
142 const bool enabled = !CommandLine::ForCurrentProcess()->HasSwitch(
143 ::switches::kDisableSystemSoundsManager);
145 g_instance = new SoundsManagerImpl();
147 g_instance = new SoundsManagerStub();
151 void SoundsManager::Shutdown() {
152 CHECK(g_instance) << "SoundsManager::Shutdown() is called "
153 << "without previous call to Create()";
159 SoundsManager* SoundsManager::Get() {
160 CHECK(g_instance) << "SoundsManager::Get() is called before Create()";