1 /* 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #ifndef WEBRTC_SOUND_AUTOMATICALLYCHOSENSOUNDSYSTEM_H_ 12 #define WEBRTC_SOUND_AUTOMATICALLYCHOSENSOUNDSYSTEM_H_ 13 14 #include "webrtc/sound/soundsysteminterface.h" 15 #include "webrtc/sound/soundsystemproxy.h" 16 #include "webrtc/base/common.h" 17 #include "webrtc/base/logging.h" 18 #include "webrtc/base/scoped_ptr.h" 19 20 namespace rtc { 21 22 // A function type that creates an instance of a sound system implementation. 23 typedef SoundSystemInterface *(*SoundSystemCreator)(); 24 25 // An AutomaticallyChosenSoundSystem is a sound system proxy that defers to 26 // an instance of the first sound system implementation in a list that 27 // successfully initializes. 28 template <const SoundSystemCreator kSoundSystemCreators[], int kNumSoundSystems> 29 class AutomaticallyChosenSoundSystem : public SoundSystemProxy { 30 public: 31 // Chooses and initializes the underlying sound system. 32 virtual bool Init(); 33 // Terminates the underlying sound system implementation, but caches it for 34 // future re-use. 35 virtual void Terminate(); 36 37 virtual const char *GetName() const; 38 39 private: 40 rtc::scoped_ptr<SoundSystemInterface> sound_systems_[kNumSoundSystems]; 41 }; 42 43 template <const SoundSystemCreator kSoundSystemCreators[], int kNumSoundSystems> 44 bool AutomaticallyChosenSoundSystem<kSoundSystemCreators, Init()45 kNumSoundSystems>::Init() { 46 if (wrapped_) { 47 return true; 48 } 49 for (int i = 0; i < kNumSoundSystems; ++i) { 50 if (!sound_systems_[i].get()) { 51 sound_systems_[i].reset((*kSoundSystemCreators[i])()); 52 } 53 if (sound_systems_[i]->Init()) { 54 // This is the first sound system in the list to successfully 55 // initialize, so we're done. 56 wrapped_ = sound_systems_[i].get(); 57 break; 58 } 59 // Else it failed to initialize, so try the remaining ones. 60 } 61 if (!wrapped_) { 62 LOG(LS_ERROR) << "Failed to find a usable sound system"; 63 return false; 64 } 65 LOG(LS_INFO) << "Selected " << wrapped_->GetName() << " sound system"; 66 return true; 67 } 68 69 template <const SoundSystemCreator kSoundSystemCreators[], int kNumSoundSystems> 70 void AutomaticallyChosenSoundSystem<kSoundSystemCreators, Terminate()71 kNumSoundSystems>::Terminate() { 72 if (!wrapped_) { 73 return; 74 } 75 wrapped_->Terminate(); 76 wrapped_ = NULL; 77 // We do not free the scoped_ptrs because we may be re-init'ed soon. 78 } 79 80 template <const SoundSystemCreator kSoundSystemCreators[], int kNumSoundSystems> 81 const char *AutomaticallyChosenSoundSystem<kSoundSystemCreators, GetName()82 kNumSoundSystems>::GetName() const { 83 return wrapped_ ? wrapped_->GetName() : "automatic"; 84 } 85 86 } // namespace rtc 87 88 #endif // WEBRTC_SOUND_AUTOMATICALLYCHOSENSOUNDSYSTEM_H_ 89