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 17 namespace media { 18 19 namespace { 20 21 SoundsManager* g_instance = NULL; 22 23 // SoundsManagerImpl --------------------------------------------------- 24 25 class SoundsManagerImpl : public SoundsManager { 26 public: 27 SoundsManagerImpl(); 28 virtual ~SoundsManagerImpl(); 29 30 // SoundsManager implementation: 31 virtual bool Initialize(SoundKey key, 32 const base::StringPiece& data) OVERRIDE; 33 virtual bool Play(SoundKey key) OVERRIDE; 34 virtual base::TimeDelta GetDuration(SoundKey key) OVERRIDE; 35 36 private: 37 base::hash_map<SoundKey, linked_ptr<AudioStreamHandler> > handlers_; 38 scoped_refptr<base::MessageLoopProxy> message_loop_; 39 40 DISALLOW_COPY_AND_ASSIGN(SoundsManagerImpl); 41 }; 42 43 SoundsManagerImpl::SoundsManagerImpl() 44 : message_loop_(AudioManager::Get()->GetMessageLoop()) {} 45 46 SoundsManagerImpl::~SoundsManagerImpl() { DCHECK(CalledOnValidThread()); } 47 48 bool SoundsManagerImpl::Initialize(SoundKey key, 49 const base::StringPiece& data) { 50 if (handlers_.find(key) != handlers_.end() && handlers_[key]->IsInitialized()) 51 return true; 52 linked_ptr<AudioStreamHandler> handler(new AudioStreamHandler(data)); 53 if (!handler->IsInitialized()) { 54 LOG(WARNING) << "Can't initialize AudioStreamHandler for key=" << key; 55 return false; 56 } 57 handlers_[key] = handler; 58 return true; 59 } 60 61 bool SoundsManagerImpl::Play(SoundKey key) { 62 DCHECK(CalledOnValidThread()); 63 if (handlers_.find(key) == handlers_.end() || 64 !handlers_[key]->IsInitialized()) { 65 return false; 66 } 67 return handlers_[key]->Play(); 68 } 69 70 base::TimeDelta SoundsManagerImpl::GetDuration(SoundKey key) { 71 DCHECK(CalledOnValidThread()); 72 if (handlers_.find(key) == handlers_.end() || 73 !handlers_[key]->IsInitialized()) { 74 return base::TimeDelta(); 75 } 76 const WavAudioHandler& wav_audio = handlers_[key]->wav_audio_handler(); 77 const int64 size = wav_audio.size(); 78 const int64 rate = wav_audio.byte_rate(); 79 return base::TimeDelta::FromMicroseconds(size * 1000000 / rate); 80 } 81 82 // SoundsManagerStub --------------------------------------------------- 83 84 class SoundsManagerStub : public SoundsManager { 85 public: 86 SoundsManagerStub(); 87 virtual ~SoundsManagerStub(); 88 89 // SoundsManager implementation: 90 virtual bool Initialize(SoundKey key, 91 const base::StringPiece& data) OVERRIDE; 92 virtual bool Play(SoundKey key) OVERRIDE; 93 virtual base::TimeDelta GetDuration(SoundKey key) OVERRIDE; 94 95 private: 96 DISALLOW_COPY_AND_ASSIGN(SoundsManagerStub); 97 }; 98 99 SoundsManagerStub::SoundsManagerStub() {} 100 101 SoundsManagerStub::~SoundsManagerStub() { DCHECK(CalledOnValidThread()); } 102 103 bool SoundsManagerStub::Initialize(SoundKey /* key */, 104 const base::StringPiece& /* data */) { 105 DCHECK(CalledOnValidThread()); 106 return false; 107 } 108 109 bool SoundsManagerStub::Play(SoundKey /* key */) { 110 DCHECK(CalledOnValidThread()); 111 return false; 112 } 113 114 base::TimeDelta SoundsManagerStub::GetDuration(SoundKey /* key */) { 115 DCHECK(CalledOnValidThread()); 116 return base::TimeDelta(); 117 } 118 119 } // namespace 120 121 SoundsManager::SoundsManager() {} 122 123 SoundsManager::~SoundsManager() { DCHECK(CalledOnValidThread()); } 124 125 // static 126 void SoundsManager::Create() { 127 CHECK(!g_instance) << "SoundsManager::Create() is called twice"; 128 const bool enabled = !CommandLine::ForCurrentProcess()->HasSwitch( 129 ::switches::kDisableSystemSoundsManager); 130 if (enabled) 131 g_instance = new SoundsManagerImpl(); 132 else 133 g_instance = new SoundsManagerStub(); 134 } 135 136 // static 137 void SoundsManager::Shutdown() { 138 CHECK(g_instance) << "SoundsManager::Shutdown() is called " 139 << "without previous call to Create()"; 140 delete g_instance; 141 g_instance = NULL; 142 } 143 144 // static 145 SoundsManager* SoundsManager::Get() { 146 CHECK(g_instance) << "SoundsManager::Get() is called before Create()"; 147 return g_instance; 148 } 149 150 } // namespace media 151