Home | History | Annotate | Download | only in sounds
      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