blob: e93dc6588dde598ef27263eaa4f351b543a5d808 [file] [log] [blame]
// 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