1 /* 2 * Copyright (C) 2010 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 14 * its contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include "config.h" 30 31 #if ENABLE(WEB_AUDIO) 32 33 #include "core/platform/audio/HRTFDatabaseLoader.h" 34 35 #include "core/platform/audio/HRTFDatabase.h" 36 #include "wtf/MainThread.h" 37 38 namespace WebCore { 39 40 // Singleton 41 HRTFDatabaseLoader::LoaderMap* HRTFDatabaseLoader::s_loaderMap = 0; 42 43 PassRefPtr<HRTFDatabaseLoader> HRTFDatabaseLoader::createAndLoadAsynchronouslyIfNecessary(float sampleRate) 44 { 45 ASSERT(isMainThread()); 46 47 RefPtr<HRTFDatabaseLoader> loader; 48 49 if (!s_loaderMap) 50 s_loaderMap = adoptPtr(new LoaderMap()).leakPtr(); 51 52 loader = s_loaderMap->get(sampleRate); 53 if (loader) { 54 ASSERT(sampleRate == loader->databaseSampleRate()); 55 return loader; 56 } 57 58 loader = adoptRef(new HRTFDatabaseLoader(sampleRate)); 59 s_loaderMap->add(sampleRate, loader.get()); 60 61 loader->loadAsynchronously(); 62 63 return loader; 64 } 65 66 HRTFDatabaseLoader::HRTFDatabaseLoader(float sampleRate) 67 : m_databaseLoaderThread(0) 68 , m_databaseSampleRate(sampleRate) 69 { 70 ASSERT(isMainThread()); 71 } 72 73 HRTFDatabaseLoader::~HRTFDatabaseLoader() 74 { 75 ASSERT(isMainThread()); 76 77 waitForLoaderThreadCompletion(); 78 m_hrtfDatabase.clear(); 79 80 // Remove ourself from the map. 81 if (s_loaderMap) 82 s_loaderMap->remove(m_databaseSampleRate); 83 } 84 85 // Asynchronously load the database in this thread. 86 static void databaseLoaderEntry(void* threadData) 87 { 88 HRTFDatabaseLoader* loader = reinterpret_cast<HRTFDatabaseLoader*>(threadData); 89 ASSERT(loader); 90 loader->load(); 91 } 92 93 void HRTFDatabaseLoader::load() 94 { 95 ASSERT(!isMainThread()); 96 if (!m_hrtfDatabase.get()) { 97 // Load the default HRTF database. 98 m_hrtfDatabase = HRTFDatabase::create(m_databaseSampleRate); 99 } 100 } 101 102 void HRTFDatabaseLoader::loadAsynchronously() 103 { 104 ASSERT(isMainThread()); 105 106 MutexLocker locker(m_threadLock); 107 108 if (!m_hrtfDatabase.get() && !m_databaseLoaderThread) { 109 // Start the asynchronous database loading process. 110 m_databaseLoaderThread = createThread(databaseLoaderEntry, this, "HRTF database loader"); 111 } 112 } 113 114 bool HRTFDatabaseLoader::isLoaded() const 115 { 116 return m_hrtfDatabase.get(); 117 } 118 119 void HRTFDatabaseLoader::waitForLoaderThreadCompletion() 120 { 121 MutexLocker locker(m_threadLock); 122 123 // waitForThreadCompletion() should not be called twice for the same thread. 124 if (m_databaseLoaderThread) 125 waitForThreadCompletion(m_databaseLoaderThread); 126 m_databaseLoaderThread = 0; 127 } 128 129 } // namespace WebCore 130 131 #endif // ENABLE(WEB_AUDIO) 132