普通文本  |  151行  |  4.35 KB

// 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