00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00022 #include "Sound.h"
00023 #include <string>
00024
00025 using namespace std;
00026
00028 static const string TOK_BEGIN_SOUND_CLASSES("BEGIN CLASSES\n");
00029 static const string TOK_END_SOUND_CLASSES("END CLASSES");
00030 static const string TOK_BEGIN_SAMPLES("BEGIN SAMPLES\n");
00031 static const string TOK_END_SAMPLES("END SAMPLES");
00032
00033 static const float VOL_STEP(0.005f);
00034
00035 Sound* Sound::s_pObj;
00036 float Sound::s_masterSongVol(1.0f);
00037 float Sound::s_masterSFXVol(1.0f);
00038 int Sound::s_songHandle;
00039
00052 void Sound::init(istream &in)
00053 {
00054 s_pObj = &Sound::getObj();
00055
00056 assert(s_pObj->m_sound.Create(sys_getWindowHandle()) == NDXERR_OK);
00057
00058
00059 ostringstream dump;
00060 dump << in.rdbuf();
00061 string rawdata = dump.str();
00062
00063 size_t start = rawdata.find(TOK_BEGIN_SOUND_CLASSES)+TOK_BEGIN_SOUND_CLASSES.size();
00064 size_t len = rawdata.find(TOK_END_SOUND_CLASSES) - start;
00065 istringstream classData(rawdata.substr(start, len));
00066
00067 string line;
00068 while(getline(classData, line))
00069 {
00070
00071
00072 istringstream is(line);
00073 int classNum;
00074 string s;
00075 int bc;
00076 is >> classNum >> s >> bc;
00077 s_pObj->m_sndClass[classNum].push_back(sampleFromWAV(const_cast<LPSTR>(s.data()), bc));
00078
00079 for( int i=0; i<NUM_CLASSES; i++ )
00080 s_pObj->lastRandomSelected.push_back(-1);
00081 }
00082
00083
00084 start = rawdata.find(TOK_BEGIN_SAMPLES)+TOK_BEGIN_SAMPLES.size();
00085 len = rawdata.find(TOK_END_SAMPLES) - start;
00086 istringstream samples(rawdata.substr(start, len));
00087
00088 while(getline(samples, line))
00089 {
00090
00091
00092 istringstream is(line);
00093 string s;
00094 int bc;
00095 is >> s >> bc;
00096 s_pObj->m_samples.push_back(sampleFromWAV(const_cast<LPSTR>(s.data()), bc));
00097 }
00098
00099 s_pObj->currentMusic = -1;
00100 }
00101
00108 NDX_Sample* Sound::sampleFromWAV(LPSTR fn, int bufCount)
00109 {
00110 NDX_Sample *s = new NDX_Sample();
00111 if( (s->LoadWAV(&s_pObj->m_sound, fn, bufCount)) != NDXERR_OK )
00112 throw Error(string("Sound::Unable to load: ")+string(fn));
00113 return s;
00114 }
00115
00119 void Sound::shutdown()
00120 {
00121 vector<NDX_Sample*>::iterator iter;
00122 for(int i=0; i<NUM_CLASSES; ++i)
00123 {
00124 for(iter = s_pObj->m_sndClass[i].begin(); iter != s_pObj->m_sndClass[i].end(); ++iter)
00125 {
00126 (*iter)->StopAll();
00127 delete *iter;
00128 }
00129 }
00130 for(iter = s_pObj->m_samples.begin(); iter != s_pObj->m_samples.end(); ++iter)
00131 {
00132 (*iter)->StopAll();
00133 delete *iter;
00134 }
00135 s_pObj->releaseObj();
00136 }
00137
00141 void Sound::playRandomSound(int soundClass, float volume)
00142 {
00144 int N = (int)s_pObj->m_sndClass[soundClass].size();
00145 size_t idx = sys_localRandInt() % N;
00146
00147 if( N>1 && idx==s_pObj->lastRandomSelected[soundClass] )
00148 idx = (idx+1) % N;
00149 s_pObj->lastRandomSelected[soundClass] = (int)idx;
00150
00151 s_pObj->m_sndClass[soundClass][idx]->Play(NDX_CALCVOLUME(volume));
00152 }
00153
00154 void Sound::play(int sample, float volume)
00155 {
00156 s_pObj-> m_samples[sample]->Play(NDX_CALCVOLUME(volume));
00157 }
00158
00159
00160 void Sound::playMusic(int sample, float volume)
00161 {
00162 if( s_pObj->currentMusic!=-1 ) s_pObj->stop(s_pObj->currentMusic);
00163 s_pObj->m_samples[sample]->Loop(NDX_CALCVOLUME(s_masterSongVol), &s_songHandle);
00164 s_pObj->currentMusic = sample;
00165 }
00166
00167 void Sound::loop(int sample, float volume)
00168 {
00169 s_pObj->m_samples[sample]->Loop(NDX_CALCVOLUME(volume));
00170 }
00171
00172 void Sound::stop(int sample)
00173 {
00174 s_pObj->m_samples[sample]->StopAll();
00175 }
00176
00177 const vector<NDX_Sample*>& Sound::samples()
00178 {
00179 return s_pObj->m_samples;
00180 }
00181
00182 void Sound::increaseSongVol()
00183 {
00184 if(s_masterSongVol < 1.0f)
00185 {
00186 s_masterSongVol += VOL_STEP;
00187 s_pObj->m_samples[s_pObj->currentMusic]->SetVolume(s_songHandle, NDX_CALCVOLUME(s_masterSongVol));
00188 }
00189 }
00190
00191 void Sound::decreaseSongVol()
00192 {
00193 if(s_masterSongVol > 0.0f)
00194 {
00195 s_masterSongVol -= VOL_STEP;
00196 s_pObj->m_samples[s_pObj->currentMusic]->SetVolume(s_songHandle, NDX_CALCVOLUME(s_masterSongVol));
00197 }
00198 }
00199
00200 void Sound::increaseSFXVol()
00201 {
00202 if(s_masterSFXVol < 1.0f)
00203 s_masterSFXVol += VOL_STEP;
00204 }
00205
00206 void Sound::decreaseSFXVol()
00207 {
00208 if(s_masterSFXVol > 0.0f)
00209 s_masterSFXVol -= VOL_STEP;
00210
00211 }
00212
00213 float Sound::getMasterSFXVol()
00214 {
00215 return s_masterSFXVol;
00216 }
00217
00218 float Sound::getMasterSongVol()
00219 {
00220 return s_masterSongVol;
00221 }