// Copyright 2013 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 "media/audio/sounds/sounds_manager.h" #include "base/command_line.h" #include "base/compiler_specific.h" #include "base/logging.h" #include "base/memory/linked_ptr.h" #include "base/memory/ref_counted.h" #include "base/message_loop/message_loop_proxy.h" #include "media/audio/audio_manager.h" #include "media/audio/sounds/audio_stream_handler.h" #include "media/base/media_switches.h" namespace media { namespace { SoundsManager* g_instance = NULL; // SoundsManagerImpl --------------------------------------------------- class SoundsManagerImpl : public SoundsManager { public: SoundsManagerImpl(); virtual ~SoundsManagerImpl(); // SoundsManager implementation: virtual bool Initialize(SoundKey key, const base::StringPiece& data) OVERRIDE; virtual bool Play(SoundKey key) OVERRIDE; virtual base::TimeDelta GetDuration(SoundKey key) OVERRIDE; private: base::hash_map<SoundKey, linked_ptr<AudioStreamHandler> > handlers_; scoped_refptr<base::MessageLoopProxy> message_loop_; DISALLOW_COPY_AND_ASSIGN(SoundsManagerImpl); }; SoundsManagerImpl::SoundsManagerImpl() : message_loop_(AudioManager::Get()->GetMessageLoop()) {} SoundsManagerImpl::~SoundsManagerImpl() { DCHECK(CalledOnValidThread()); } bool SoundsManagerImpl::Initialize(SoundKey key, const base::StringPiece& data) { if (handlers_.find(key) != handlers_.end() && handlers_[key]->IsInitialized()) return true; linked_ptr<AudioStreamHandler> handler(new AudioStreamHandler(data)); if (!handler->IsInitialized()) { LOG(WARNING) << "Can't initialize AudioStreamHandler for key=" << key; return false; } handlers_[key] = handler; return true; } bool SoundsManagerImpl::Play(SoundKey key) { DCHECK(CalledOnValidThread()); if (handlers_.find(key) == handlers_.end() || !handlers_[key]->IsInitialized()) { return false; } return handlers_[key]->Play(); } base::TimeDelta SoundsManagerImpl::GetDuration(SoundKey key) { DCHECK(CalledOnValidThread()); if (handlers_.find(key) == handlers_.end() || !handlers_[key]->IsInitialized()) { return base::TimeDelta(); } const WavAudioHandler& wav_audio = handlers_[key]->wav_audio_handler(); const int64 size = wav_audio.size(); const int64 rate = wav_audio.byte_rate(); return base::TimeDelta::FromMicroseconds(size * 1000000 / rate); } // SoundsManagerStub --------------------------------------------------- class SoundsManagerStub : public SoundsManager { public: SoundsManagerStub(); virtual ~SoundsManagerStub(); // SoundsManager implementation: virtual bool Initialize(SoundKey key, const base::StringPiece& data) OVERRIDE; virtual bool Play(SoundKey key) OVERRIDE; virtual base::TimeDelta GetDuration(SoundKey key) OVERRIDE; private: DISALLOW_COPY_AND_ASSIGN(SoundsManagerStub); }; SoundsManagerStub::SoundsManagerStub() {} SoundsManagerStub::~SoundsManagerStub() { DCHECK(CalledOnValidThread()); } bool SoundsManagerStub::Initialize(SoundKey /* key */, const base::StringPiece& /* data */) { DCHECK(CalledOnValidThread()); return false; } bool SoundsManagerStub::Play(SoundKey /* key */) { DCHECK(CalledOnValidThread()); return false; } base::TimeDelta SoundsManagerStub::GetDuration(SoundKey /* key */) { DCHECK(CalledOnValidThread()); return base::TimeDelta(); } } // namespace SoundsManager::SoundsManager() {} SoundsManager::~SoundsManager() { DCHECK(CalledOnValidThread()); } // static void SoundsManager::Create() { CHECK(!g_instance) << "SoundsManager::Create() is called twice"; const bool enabled = !CommandLine::ForCurrentProcess()->HasSwitch( ::switches::kDisableSystemSoundsManager); if (enabled) g_instance = new SoundsManagerImpl(); else g_instance = new SoundsManagerStub(); } // static void SoundsManager::Shutdown() { CHECK(g_instance) << "SoundsManager::Shutdown() is called " << "without previous call to Create()"; delete g_instance; g_instance = NULL; } // static SoundsManager* SoundsManager::Get() { CHECK(g_instance) << "SoundsManager::Get() is called before Create()"; return g_instance; } } // namespace media