MercurySoundDriver.cpp

Go to the documentation of this file.
00001 #include <math.h>
00002 #include "MercurySoundDriver.h"
00003 #include "MercurySoundDriverALSA.h"
00004 #include "MercuryLog.h"
00005 
00006 void* MercurySoundDriver::TheadFunctCaller(void* x)
00007 {
00008     MercurySoundDriver* y = (MercurySoundDriver*)x;
00009     y->ThreadLoop();
00010     return 0;
00011 }
00012 
00013 MercurySoundDriver& MercurySoundDriver::GetInstance()
00014 {
00015     static MercurySoundDriver* instance = NULL;
00016     if (!instance)
00017     {
00018         instance = new MercurySoundDriverALSA;
00019         instance->Init();
00020         instance->CreateThread();
00021     }
00022     return *instance;
00023 }
00024 
00025 MercurySoundDriver::MercurySoundDriver()
00026 {
00027 }
00028 
00029 MercurySoundDriver::~MercurySoundDriver()
00030 {
00031     Cleanup();
00032     //halt the thread so we don't try to write to the buffer after it is gone
00033     m_thread.Halt();
00034     delete(m_buffer);
00035 }
00036 
00037 void MercurySoundDriver::CreateThread()
00038 {
00039 #if !defined( NO_THREADS )
00040     printf("make thread\n");
00041     m_thread.Create(MercurySoundDriver::TheadFunctCaller, this);
00042 #endif
00043 }
00044 
00045 void MercurySoundDriver::ThreadLoop()
00046 {
00047     while (true)
00048     {
00049         ProcessPlayingSounds();
00050         Sleep(10);
00051     }
00052 }
00053 
00054 void MercurySoundDriver::Init()
00055 {
00056     m_rate = 44100;
00057     m_bufferSize = 4096;
00058     m_writeSize = 512;
00059     m_channels = 2;
00060     m_sentFrames = 0;
00061     m_front = &m_buffer;
00062     m_back = &m_buffer2;
00063     m_needData = false;
00064 }
00065 
00066 void MercurySoundDriver::ProcessPlayingSounds()
00067 {
00068     m_mutex.Wait();
00069     if (m_needData)
00070     {
00071         unsigned long samples = m_bufferSize*m_channels;
00072         float mixedData[samples];
00073         for (unsigned int i = 0; i < samples; ++i)
00074             mixedData[i] = 0;
00075         for (unsigned long i = 0; i < m_playingSounds.size(); ++i)
00076         {
00077             float* data = m_playingSounds[i]->IsPaused()?NULL:m_playingSounds[i]->ReadData(samples);
00078             if (!data)
00079                 continue;
00080             for (unsigned long i = 0; i < samples; ++i)
00081                 mixedData[i] += data[i];
00082             delete data;
00083         }
00084 
00085         for (unsigned long i = 0; i < samples; ++i)
00086             (*m_back)[i] = lrintf(Clamp(mixedData[i], -1.0f, 1.0f)*32767);
00087 
00088         int16_t** tmp = m_front;
00089         m_front = m_back;
00090         m_back = m_front;
00091 
00092         m_needData = false;
00093     }
00094     m_mutex.UnLock();
00095 }
00096 
00097 void MercurySoundDriver::AddSound(MercurySoundSourceWAV* sound)
00098 {
00099     m_mutex.Wait();
00100     m_playingSounds.push_back(sound);
00101     m_mutex.UnLock();
00102 }
00103 
00104 void MercurySoundDriver::RemoveSound(MercurySoundSourceWAV* sound)
00105 {
00106     m_mutex.Wait();
00107     for (unsigned int i = 0; i < m_playingSounds.size(); ++i)
00108         if (m_playingSounds[i] == sound)
00109             m_playingSounds.remove(i);
00110 //          m_playingSounds.erase( m_playingSounds.begin() + i );
00111     m_mutex.UnLock();
00112 }
00113 
00114 /* 
00115  * Copyright (c) 2007 Joshua Allen
00116  * All rights reserved.
00117  *
00118  * Redistribution and use in source and binary forms, with or
00119  * without modification, are permitted provided that the following
00120  * conditions are met:
00121  *  -   Redistributions of source code must retain the above
00122  *      copyright notice, this list of conditions and the following disclaimer.
00123  *  -   Redistributions in binary form must reproduce the above copyright
00124  *      notice, this list of conditions and the following disclaimer in
00125  *      the documentation and/or other materials provided with the distribution.
00126  *  -   Neither the name of the Mercury Engine nor the names of its
00127  *      contributors may be used to endorse or promote products derived from
00128  *      this software without specific prior written permission.
00129  *
00130  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00131  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00132  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00133  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
00134  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00135  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00136  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00137  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00138  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
00139  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00140  */

Hosted by SourceForge.net Logo