Soundsys.cpp 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269
  1. //---------------------------------------------------------------------------
  2. // soundsys.cpp - This file is the sound system code
  3. //
  4. //---------------------------------------------------------------------------//
  5. // Copyright (C) Microsoft Corporation. All rights reserved. //
  6. //===========================================================================//
  7. //---------------------------------------------------------------------------
  8. // Include files
  9. #ifndef SOUNDSYS_H
  10. #include "soundsys.h"
  11. #endif
  12. #ifndef SOUNDS_H
  13. #include "sounds.h"
  14. #endif
  15. #ifndef CAMERA_H
  16. #include "camera.h"
  17. #endif
  18. //---------------------------------------------------------------------------
  19. // static globals
  20. bool useSound = TRUE;
  21. bool useMusic = TRUE;
  22. long DigitalMasterVolume = 0;
  23. long MusicVolume = 0;
  24. long sfxVolume = 0;
  25. long RadioVolume = 0;
  26. long BettyVolume = 0;
  27. #define MAX_SENSOR_UPDATE_TIME (5.0f) //Seconds
  28. float SoundSystem::digitalMasterVolume = 0.99f;
  29. float SoundSystem::SFXVolume = 0.6f;
  30. float SoundSystem::musicVolume = 0.4f;
  31. float SoundSystem::radioVolume = 0.6f;
  32. float SoundSystem::bettyVolume = 0.7f;
  33. long SoundSystem::largestSensorContact = -1;
  34. #define FALLOFF_DISTANCE (1500.0f)
  35. //---------------------------------------------------------------------------
  36. // class SoundSystem
  37. //---------------------------------------------------------------------------
  38. void SoundSystem::destroy (void)
  39. {
  40. if (soundHeap)
  41. {
  42. soundHeap->destroy();
  43. delete soundHeap;
  44. soundHeap = NULL;
  45. }
  46. }
  47. //---------------------------------------------------------------------------
  48. long SoundSystem::init (char *soundFileName)
  49. {
  50. if (useSound)
  51. {
  52. FullPathFileName soundName;
  53. soundName.init(soundPath,soundFileName,".snd");
  54. FitIniFile soundFile;
  55. long result = soundFile.open(soundName);
  56. gosASSERT(result == NO_ERR);
  57. result = soundFile.seekBlock("SoundSetup");
  58. gosASSERT(result == NO_ERR);
  59. result = soundFile.readIdULong("soundHeapSize",soundHeapSize);
  60. gosASSERT(result == NO_ERR);
  61. result = soundFile.readIdFloat("MaxSoundDistance",maxSoundDistance);
  62. gosASSERT(result == NO_ERR);
  63. soundHeap = new UserHeap;
  64. gosASSERT(soundHeap != NULL);
  65. result = soundHeap->init(soundHeapSize,"SOUND");
  66. gosASSERT(result == NO_ERR);
  67. //-----------------------------------------------------------------------
  68. // Startup the Sound packet File with the sound Blocks in it.
  69. // This works by sound ID. The sound ID is the packet number.
  70. // When ordered to play a sample, the sound system check to see if that
  71. // sound ID is in the cache. If not, it is loaded. If there is no more
  72. // room, any idle sounds are flushed in order of priority.
  73. soundDataFile = new PacketFile;
  74. gosASSERT(soundDataFile != NULL);
  75. FullPathFileName soundDataPath;
  76. soundDataPath.init(CDsoundPath,soundFileName,".pak");
  77. result = soundDataFile->open(soundDataPath);
  78. gosASSERT(result == NO_ERR);
  79. bettyDataFile = new PacketFile;
  80. gosASSERT(bettyDataFile != NULL);
  81. FullPathFileName bettyDataPath;
  82. bettyDataPath.init(CDsoundPath,"Betty",".pak");
  83. result = bettyDataFile->open(bettyDataPath);
  84. gosASSERT(result == NO_ERR);
  85. numBettySamples = bettyDataFile->getNumPackets();
  86. supportDataFile = new PacketFile;
  87. gosASSERT(supportDataFile != NULL);
  88. FullPathFileName supportDataPath;
  89. supportDataPath.init(CDsoundPath,"support",".pak");
  90. result = supportDataFile->open(supportDataPath);
  91. gosASSERT(result == NO_ERR);
  92. numSupportSamples = supportDataFile->getNumPackets();
  93. //-----------------------------------------------------------------------
  94. // Load all of the sound Bite data. Do not load actual packet unless
  95. // preload field is TRUE.
  96. result = soundFile.seekBlock("SoundBites");
  97. gosASSERT(result == NO_ERR);
  98. result = soundFile.readIdULong("numBites",numSoundBites);
  99. gosASSERT(result == NO_ERR);
  100. //-----------------------------------------------------------------------
  101. // Preallocate SoundBites
  102. sounds = (SoundBite *)soundHeap->Malloc(sizeof(SoundBite) * numSoundBites);
  103. gosASSERT(sounds != NULL);
  104. memset(sounds,0,sizeof(SoundBite) * numSoundBites);
  105. for (long i=0;i<(long)numSoundBites;i++)
  106. {
  107. char biteBlock[20];
  108. sprintf(biteBlock,"SoundBite%d",i);
  109. result = soundFile.seekBlock(biteBlock);
  110. gosASSERT(result == NO_ERR);
  111. result = soundFile.readIdULong("priority",sounds[i].priority);
  112. gosASSERT(result == NO_ERR);
  113. result = soundFile.readIdULong("cache",sounds[i].cacheStatus);
  114. gosASSERT(result == NO_ERR);
  115. result = soundFile.readIdULong("soundId",sounds[i].soundId);
  116. gosASSERT(result == NO_ERR);
  117. preloadSoundBite(i); //ALWAYS Preload!!!!!!!!!!!!!
  118. result = soundFile.readIdFloat("volume",sounds[i].volume);
  119. gosASSERT(result == NO_ERR);
  120. }
  121. //---------------------------------------------------------------
  122. // Load the digital Music Data Strings
  123. result = soundFile.seekBlock("DigitalMusic");
  124. gosASSERT(result == NO_ERR);
  125. result = soundFile.readIdLong("NumDMS",numDMS);
  126. gosASSERT(result == NO_ERR);
  127. result = soundFile.readIdFloat("StreamFadeDownTime",streamFadeDownTime);
  128. gosASSERT(result == NO_ERR);
  129. result = soundFile.readIdULong("StreamBitDepth",digitalStreamBitDepth);
  130. gosASSERT(result == NO_ERR);
  131. result = soundFile.readIdULong("StreamChannels",digitalStreamChannels);
  132. gosASSERT(result == NO_ERR);
  133. digitalMusicIds = (char **)soundHeap->Malloc(sizeof(char *) * numDMS);
  134. gosASSERT(digitalMusicIds != NULL);
  135. digitalMusicLoopFlags = (bool *)soundHeap->Malloc(sizeof(bool)*numDMS);
  136. gosASSERT(digitalMusicLoopFlags != NULL);
  137. digitalMusicVolume = (float *)soundHeap->Malloc(sizeof(float) * numDMS);
  138. for (i=0;i<numDMS;i++)
  139. {
  140. char digitalMSId[20];
  141. sprintf(digitalMSId,"DMS%d",i);
  142. char digitalMSBId[20];
  143. sprintf(digitalMSBId,"DMSLoop%d",i);
  144. char digitalMSVId[25];
  145. sprintf(digitalMSVId,"DMSVolume%d",i);
  146. digitalMusicIds[i] = (char *)soundHeap->Malloc(30);
  147. result = soundFile.readIdString(digitalMSId,digitalMusicIds[i],29);
  148. gosASSERT(result == NO_ERR);
  149. result = soundFile.readIdBoolean(digitalMSBId,digitalMusicLoopFlags[i]);
  150. gosASSERT(result == NO_ERR);
  151. result = soundFile.readIdFloat(digitalMSVId,digitalMusicVolume[i]);
  152. if (result != NO_ERR)
  153. digitalMusicVolume[i] = 1.0f;
  154. }
  155. soundFile.close();
  156. for (i=0;i<MAX_DIGITAL_SAMPLES+4;i++)
  157. {
  158. gosAudio_AllocateChannelSliders(i,gosAudio_Volume | gosAudio_Panning);
  159. }
  160. }
  161. digitalMasterVolume = float(DigitalMasterVolume) / 256.0f;
  162. SFXVolume = float(sfxVolume) / 256.0f;
  163. musicVolume = float(MusicVolume) / 256.0f;
  164. radioVolume = float(RadioVolume) / 256.0f;
  165. bettyVolume = float(BettyVolume) / 256.0f;
  166. stream1Id = stream2Id = 0;
  167. return(NO_ERR);
  168. }
  169. //////////////////////////////////////////////////////////////////
  170. //
  171. // wave_ParseWaveMemory
  172. // Parses a chunk of memory into the header and samples.
  173. // This is done by looking for the "fmt " and "data"
  174. // fields in the memory.
  175. //
  176. //////////////////////////////////////////////////////////////////
  177. bool wave_ParseWaveMemory(MemoryPtr lpChunkOfMemory, MC2_WAVEFORMATEX** lplpWaveHeader, MemoryPtr* lplpWaveSamples,DWORD *lpcbWaveSize)
  178. {
  179. DWORD *pdw;
  180. DWORD *pdwEnd;
  181. DWORD dwRiff;
  182. DWORD dwType;
  183. DWORD dwLength;
  184. // Set defaults to NULL or zero
  185. if (*lplpWaveHeader)
  186. *lplpWaveHeader = NULL;
  187. if (*lplpWaveSamples)
  188. *lplpWaveSamples = NULL;
  189. if (lpcbWaveSize)
  190. *lpcbWaveSize = 0;
  191. // Set up DWORD pointers to the start of the chunk
  192. // of memory.
  193. pdw = (DWORD *)lpChunkOfMemory;
  194. // Get the type and length of the chunk of memory
  195. dwRiff = *pdw++;
  196. dwLength = *pdw++;
  197. dwType = *pdw++;
  198. // Using the mmioFOURCC macro (part of Windows SDK), ensure
  199. // that this is a RIFF WAVE chunk of memory
  200. if (dwRiff != 0x46464952)
  201. return FALSE; // not even RIFF
  202. if (dwType != 0x45564157)
  203. return FALSE; // not a WAV
  204. // Find the pointer to the end of the chunk of memory
  205. pdwEnd = (DWORD *)((BYTE *)pdw + dwLength-4);
  206. // Run through the bytes looking for the tags
  207. while (pdw < pdwEnd)
  208. {
  209. dwType = *pdw++;
  210. dwLength = *pdw++;
  211. switch (dwType)
  212. {
  213. // Found the format part
  214. case 0x20746d66:
  215. if (*lplpWaveHeader == NULL)
  216. {
  217. if (dwLength < sizeof(MC2_WAVEFORMATEX))
  218. return FALSE; // something's wrong! Not a WAV
  219. // Set the lplpWaveHeader to point to this part of
  220. // the memory chunk
  221. *lplpWaveHeader = (MC2_WAVEFORMATEX*)pdw;
  222. // Check to see if the other two items have been
  223. // filled out yet (the bits and the size of the
  224. // bits). If so, then this chunk of memory has
  225. // been parsed out and we can exit
  226. if ((!lplpWaveSamples || *lplpWaveSamples) &&
  227. (!lpcbWaveSize || *lpcbWaveSize))
  228. {
  229. return TRUE;
  230. }
  231. }
  232. break;
  233. // Found the samples
  234. case 0x61746164:
  235. if ((lplpWaveSamples && !*lplpWaveSamples) ||
  236. (lpcbWaveSize && !*lpcbWaveSize))
  237. {
  238. // Point the samples pointer to this part of the
  239. // chunk of memory.
  240. if (*lplpWaveSamples == NULL)
  241. *lplpWaveSamples = (MemoryPtr)pdw;
  242. // Set the size of the wave
  243. if (lpcbWaveSize) *lpcbWaveSize = dwLength;
  244. // Make sure we have our header pointer set up.
  245. // If we do, we can exit
  246. if (lplpWaveHeader)
  247. return TRUE;
  248. }
  249. break;
  250. } // End case
  251. // Move the pointer through the chunk of memory
  252. pdw = (DWORD *)((BYTE *)pdw + ((dwLength+1)&~1));
  253. }
  254. // Failed! If we made it here, we did not get all the peices
  255. // of the wave
  256. return FALSE;
  257. }
  258. //---------------------------------------------------------------------------
  259. void SoundSystem::preloadSoundBite (long soundId)
  260. {
  261. long result = soundDataFile->seekPacket(soundId);
  262. if (result != NO_ERR)
  263. return;
  264. //-------------------------------------------------------------
  265. // If there is a packet in this spot, load it.
  266. // First, check if there is enough room in the sound heap
  267. // and if not, free up any samples whose cache status says dump.
  268. unsigned long packetSize = soundDataFile->getPacketSize();
  269. if (packetSize > 0)
  270. {
  271. SoundBite *thisSoundBite = (SoundBite *)(&(sounds[soundId]));
  272. thisSoundBite->resourceHandle = 0;
  273. if (thisSoundBite->biteSize == 0 || thisSoundBite->biteData == NULL)
  274. {
  275. thisSoundBite->biteSize = packetSize;
  276. thisSoundBite->biteData = (MemoryPtr)soundHeap->Malloc(packetSize);
  277. if (!thisSoundBite->biteData)
  278. return;
  279. }
  280. soundDataFile->readPacket(soundId,thisSoundBite->biteData);
  281. //--------------------------------------------------------------------
  282. // Hand GOS sound the data it needs to create the resource Handle
  283. gosAudio_Format soundFormat;
  284. soundFormat.wFormatTag = 1; //PCM
  285. MC2_WAVEFORMATEX *waveFormat = NULL;
  286. MemoryPtr dataOffset = NULL;
  287. DWORD length = 0;
  288. DWORD bitsPerSec = 0;
  289. wave_ParseWaveMemory(thisSoundBite->biteData,&waveFormat,&dataOffset,&length);
  290. if (waveFormat && dataOffset)
  291. {
  292. bitsPerSec = waveFormat->nBlockAlign / waveFormat->nChannels * 8;
  293. soundFormat.nChannels = waveFormat->nChannels;
  294. soundFormat.nSamplesPerSec = waveFormat->nSamplesPerSec;
  295. soundFormat.nAvgBytesPerSec = waveFormat->nAvgBytesPerSec;
  296. soundFormat.nBlockAlign = waveFormat->nBlockAlign;
  297. soundFormat.wBitsPerSample = bitsPerSec;
  298. soundFormat.cbSize = 0;
  299. gosAudio_CreateResource(&thisSoundBite->resourceHandle,gosAudio_UserMemory, NULL, &soundFormat,dataOffset,length);
  300. }
  301. else
  302. {
  303. thisSoundBite->resourceHandle = 0;
  304. }
  305. }
  306. }
  307. //---------------------------------------------------------------------------
  308. void SoundSystem::update (void)
  309. {
  310. if (useSound && (isRaining != oldRaining))
  311. {
  312. //Play the isRaining SoundEffect at the soundEffect level in a loop.
  313. if (isRaining && (isRaining < numSoundBites))
  314. {
  315. long ourChannel = FIRE_CHANNEL;
  316. gosAudio_SetChannelSlider(ourChannel,gosAudio_Panning, 0.0);
  317. float vol = sounds[isRaining].volume;
  318. gosAudio_SetChannelSlider(ourChannel,gosAudio_Volume, (digitalMasterVolume * vol * SFXVolume));
  319. channelSampleId[ourChannel] = isRaining;
  320. channelInUse[ourChannel] = TRUE;
  321. if (sounds[isRaining].biteData)
  322. {
  323. gosAudio_AssignResourceToChannel( ourChannel, sounds[isRaining].resourceHandle );
  324. gosAudio_SetChannelPlayMode( ourChannel, gosAudio_Loop );
  325. }
  326. oldRaining = isRaining;
  327. }
  328. else
  329. {
  330. //Stop the sound Effect by fading it to zero!
  331. oldRaining = isRaining;
  332. gosAudio_PlayMode sampleStatus = gosAudio_GetChannelPlayMode(FIRE_CHANNEL);
  333. if ( sampleStatus == gosAudio_PlayOnce || sampleStatus == gosAudio_Loop )
  334. {
  335. fadeDown[FIRE_CHANNEL] = TRUE;
  336. }
  337. }
  338. }
  339. if (useSound && bettySoundBite)
  340. {
  341. //---------------------------------------------------
  342. // Check if betty is done. If so, whack the memory
  343. gosAudio_PlayMode sampleStatus = gosAudio_GetChannelPlayMode(BETTY_CHANNEL);
  344. if (sampleStatus != gosAudio_PlayOnce)
  345. {
  346. gosAudio_DestroyResource(&bettyHandle);
  347. soundHeap->Free(bettySoundBite);
  348. bettySoundBite = NULL;
  349. }
  350. }
  351. if (useSound && supportSoundBite)
  352. {
  353. //---------------------------------------------------
  354. // Check if betty is done. If so, whack the memory
  355. gosAudio_PlayMode sampleStatus = gosAudio_GetChannelPlayMode(SUPPORT_CHANNEL);
  356. if (sampleStatus != gosAudio_PlayOnce)
  357. {
  358. gosAudio_DestroyResource(&supportHandle);
  359. soundHeap->Free(supportSoundBite);
  360. supportSoundBite = NULL;
  361. }
  362. }
  363. if (useSound && stream3Handle)
  364. {
  365. gosAudio_PlayMode sampleStatus = gosAudio_GetChannelPlayMode(STREAM3CHANNEL);
  366. if (!stream3Active && (sampleStatus != gosAudio_PlayOnce))
  367. {
  368. stream3Active = true;
  369. gosAudio_SetChannelPlayMode( STREAM3CHANNEL, gosAudio_PlayOnce );
  370. }
  371. sampleStatus = gosAudio_GetChannelPlayMode(STREAM3CHANNEL);
  372. if (stream3Active && sampleStatus != gosAudio_PlayOnce)
  373. {
  374. gosAudio_DestroyResource(&stream3Handle);
  375. stream3Handle = 0;
  376. stream3Active = false;
  377. }
  378. }
  379. if ((largestSensorContact > -1) && (sensorBeepUpdateTime > MAX_SENSOR_UPDATE_TIME))
  380. {
  381. playDigitalSample(SENSOR2);
  382. sensorBeepUpdateTime = 0.0f;
  383. }
  384. //Start the music change we requested playing!!
  385. // This avoids the stupid sound bug of starting more then one stream per frame!!
  386. if (stream1Handle && !stream1Active)
  387. {
  388. stream1Active = true;
  389. gosAudio_SetChannelPlayMode( STREAM1CHANNEL, digitalMusicLoopFlags[currentMusicId] ? gosAudio_Loop : gosAudio_PlayOnce);
  390. }
  391. if (stream2Handle && !stream2Active)
  392. {
  393. stream2Active = true;
  394. gosAudio_SetChannelPlayMode( STREAM2CHANNEL, digitalMusicLoopFlags[currentMusicId] ? gosAudio_Loop : gosAudio_PlayOnce);
  395. }
  396. if (useMusic && (stream1Active || stream2Active))
  397. {
  398. if (stream1Active && (stream1Time != 0.0))
  399. {
  400. if (stream1Time < 0.0)
  401. {
  402. //------------------------------------------
  403. // We are fading Down.
  404. stream1Time += frameLength;
  405. if (stream1Time >= 0.0)
  406. {
  407. stream1Time = 0.0;
  408. if (stream1Handle)
  409. gosAudio_DestroyResource(&stream1Handle);
  410. stream1Handle = NULL;
  411. stream1Active = FALSE;
  412. }
  413. else
  414. {
  415. float volLevel = fabs(stream1Time) / streamFadeDownTime;
  416. if (volLevel < 0.0)
  417. volLevel = 0.0;
  418. if (volLevel > 1.0)
  419. volLevel = 1.0;
  420. gosAudio_SetChannelSlider(STREAM1CHANNEL, gosAudio_Volume, digitalMasterVolume * volLevel * musicVolume * digitalMusicVolume[currentMusicId]);
  421. }
  422. }
  423. else if (stream1Time > 0.0)
  424. {
  425. //------------------------------------------
  426. // We are fading Up.
  427. stream1Time -= frameLength;
  428. if (stream1Time <= 0.0)
  429. {
  430. stream1Time = 0.0;
  431. gosAudio_SetChannelSlider(STREAM1CHANNEL, gosAudio_Volume, digitalMasterVolume * musicVolume * digitalMusicVolume[currentMusicId]);
  432. }
  433. else
  434. {
  435. float volLevel = (streamFadeDownTime - fabs(stream1Time)) / streamFadeDownTime;
  436. if (volLevel < 0.0)
  437. volLevel = 0.0;
  438. if (volLevel > 1.0)
  439. volLevel = 1.0;
  440. gosAudio_SetChannelSlider(STREAM1CHANNEL, gosAudio_Volume, digitalMasterVolume * volLevel * musicVolume * digitalMusicVolume[currentMusicId]);
  441. }
  442. }
  443. }
  444. if (stream2Active && (stream2Time != 0.0))
  445. {
  446. if (stream2Time < 0.0)
  447. {
  448. //------------------------------------------
  449. // We are fading Down.
  450. stream2Time += frameLength;
  451. if (stream2Time >= 0.0)
  452. {
  453. stream2Time = 0.0;
  454. if (stream2Handle)
  455. gosAudio_DestroyResource(&stream2Handle);
  456. stream2Handle = NULL;
  457. stream2Active = FALSE;
  458. }
  459. else
  460. {
  461. float volLevel = fabs(stream2Time) / streamFadeDownTime;
  462. if (volLevel < 0.0)
  463. volLevel = 0.0;
  464. if (volLevel > 1.0)
  465. volLevel = 1.0;
  466. gosAudio_SetChannelSlider(STREAM2CHANNEL, gosAudio_Volume, digitalMasterVolume * volLevel * musicVolume * digitalMusicVolume[currentMusicId]);
  467. }
  468. }
  469. else if (stream2Time > 0.0)
  470. {
  471. //------------------------------------------
  472. // We are fading Up.
  473. stream2Time -= frameLength;
  474. if (stream2Time <= 0.0)
  475. {
  476. stream2Time = 0.0;
  477. gosAudio_SetChannelSlider(STREAM2CHANNEL, gosAudio_Volume, digitalMasterVolume * musicVolume * digitalMusicVolume[currentMusicId]);
  478. }
  479. else
  480. {
  481. float volLevel = (streamFadeDownTime - fabs(stream2Time)) / streamFadeDownTime;
  482. if (volLevel < 0.0)
  483. volLevel = 0.0;
  484. if (volLevel > 1.0)
  485. volLevel = 1.0;
  486. gosAudio_SetChannelSlider(STREAM2CHANNEL, gosAudio_Volume, digitalMasterVolume * volLevel * musicVolume * digitalMusicVolume[currentMusicId]);
  487. }
  488. }
  489. }
  490. if (stream1Active && stream1Handle && (gosAudio_GetChannelPlayMode(STREAM1CHANNEL) == gosAudio_Stop))
  491. {
  492. if (stream1Handle)
  493. gosAudio_DestroyResource(&stream1Handle);
  494. stream1Handle = NULL;
  495. stream1Time = 0.0;
  496. stream1Active = FALSE;
  497. }
  498. if (stream2Active && stream2Handle && (gosAudio_GetChannelPlayMode(STREAM2CHANNEL) == gosAudio_Stop))
  499. {
  500. if (stream2Handle)
  501. gosAudio_DestroyResource(&stream2Handle);
  502. stream2Handle = NULL;
  503. stream2Time = 0.0;
  504. stream2Active = FALSE;
  505. }
  506. if (!stream1Active && !stream2Active)
  507. currentMusicId = -1;
  508. }
  509. if (useSound)
  510. {
  511. //-----------------------------------------------
  512. // Check all samples to see if one should end.
  513. for (long i=0;i<MAX_DIGITAL_SAMPLES;i++)
  514. {
  515. gosAudio_PlayMode sampleStatus = gosAudio_GetChannelPlayMode(i);
  516. if (sampleStatus == gosAudio_PlayOnce)
  517. {
  518. if (fadeDown[i])
  519. {
  520. float vol;
  521. gosAudio_GetChannelSlider(i, gosAudio_Volume, &vol);
  522. if (vol <= 0.1f)
  523. vol = 0.1f;
  524. gosAudio_SetChannelSlider(i, gosAudio_Volume, vol-0.1f);
  525. gosAudio_GetChannelSlider(i, gosAudio_Volume, &vol);
  526. if (vol == 0.0f)
  527. {
  528. fadeDown[i] = FALSE;
  529. gosAudio_SetChannelPlayMode(i, gosAudio_Stop);
  530. }
  531. }
  532. }
  533. else
  534. {
  535. fadeDown[i] = FALSE;
  536. channelSampleId[i] = -1;
  537. channelInUse[i] = FALSE;
  538. }
  539. }
  540. }
  541. if (!gamePaused)
  542. sensorBeepUpdateTime += frameLength;
  543. }
  544. //---------------------------------------------------------------------------
  545. long SoundSystem::playDigitalMusic (long musicId)
  546. {
  547. //-------------------------------------------------------------------
  548. // Make sure we have a real music filename.
  549. if (useMusic)
  550. {
  551. if ((musicId >= 0) && (musicId < numDMS) && (strncmp(digitalMusicIds[musicId],"NONE",4) != 0))
  552. {
  553. if (musicId == currentMusicId)
  554. return(-1);
  555. if (useSound)
  556. {
  557. //---------------------------------------------------------------------------------------------
  558. // Just start tune. No fade necessary. Set fadeTime to 0.0 to tell update to leave it alone.
  559. // Use Stream1 by default.
  560. FullPathFileName digitalStream;
  561. digitalStream.init(soundPath,digitalMusicIds[musicId],".wav");
  562. //---------------------------------------------
  563. // Gotta check if music file is there
  564. // new sound system can't handle it if its not.
  565. if (fileExists(digitalStream))
  566. {
  567. if (!stream1Active && !stream2Active)
  568. {
  569. if (stream1Handle)
  570. {
  571. gosAudio_DestroyResource(&stream1Handle);
  572. stream1Handle = 0;
  573. }
  574. gosAudio_CreateResource(&stream1Handle, gosAudio_StreamedFile, (const char *) digitalStream);
  575. stream1Time = streamFadeDownTime;
  576. gosAudio_SetChannelSlider( STREAM1CHANNEL, gosAudio_Volume, 0.0f );
  577. gosAudio_SetChannelSlider( STREAM1CHANNEL, gosAudio_Panning,0.0f );
  578. gosAudio_AssignResourceToChannel( STREAM1CHANNEL, stream1Handle );
  579. currentMusicId = musicId;
  580. stream1Id = musicId;
  581. }
  582. else if (!stream2Active)
  583. {
  584. if (stream2Handle)
  585. {
  586. gosAudio_DestroyResource( &stream2Handle );
  587. stream2Handle = 0;
  588. }
  589. gosAudio_CreateResource( &stream2Handle, gosAudio_StreamedFile, (const char *) digitalStream );
  590. //Need to check if stream1 ever got all the way faded up!
  591. if (stream1Time > 0.0f)
  592. stream1Time = -stream1Time;
  593. else
  594. stream1Time = -streamFadeDownTime;
  595. stream2Time = streamFadeDownTime;
  596. gosAudio_SetChannelSlider( STREAM2CHANNEL, gosAudio_Volume, 0.0f );
  597. gosAudio_SetChannelSlider( STREAM2CHANNEL, gosAudio_Panning,0.0f );
  598. gosAudio_AssignResourceToChannel( STREAM2CHANNEL, stream2Handle );
  599. currentMusicId = musicId;
  600. stream2Id = musicId;
  601. }
  602. else if (!stream1Active)
  603. {
  604. if (stream1Handle)
  605. {
  606. gosAudio_DestroyResource(&stream1Handle);
  607. stream1Handle = 0;
  608. }
  609. gosAudio_CreateResource(&stream1Handle, gosAudio_StreamedFile, (const char *) digitalStream);
  610. stream1Time = streamFadeDownTime;
  611. //Need to check if stream2 ever got all the way faded up!
  612. if (stream2Time > 0.0f)
  613. stream2Time = -stream2Time;
  614. else
  615. stream2Time = -streamFadeDownTime;
  616. gosAudio_SetChannelSlider( STREAM1CHANNEL, gosAudio_Volume, 0.0f );
  617. gosAudio_SetChannelSlider( STREAM1CHANNEL, gosAudio_Panning,0.0f );
  618. gosAudio_AssignResourceToChannel( STREAM1CHANNEL, stream1Handle );
  619. currentMusicId = musicId;
  620. stream1Id = musicId;
  621. }
  622. else
  623. {
  624. return(-1);
  625. }
  626. }
  627. }
  628. }
  629. }
  630. return(NO_ERR);
  631. }
  632. //---------------------------------------------------------------------------
  633. long SoundSystem::playDigitalStream (const char *streamName)
  634. {
  635. //-------------------------------------------------------------------
  636. // Make sure we have a real music filename.
  637. if (useSound)
  638. {
  639. char actualName[1024];
  640. _splitpath(streamName,NULL,NULL,actualName,NULL);
  641. //---------------------------------------------------------------------------------------------
  642. // Just start tune. No fade necessary. Set fadeTime to 0.0 to tell update to leave it alone.
  643. // Use Stream1 by default.
  644. FullPathFileName digitalStream;
  645. digitalStream.init(soundPath,actualName,".wav");
  646. //---------------------------------------------
  647. // Gotta check if music file is there
  648. // new sound system can't handle it if its not.
  649. if (fileExists(digitalStream))
  650. {
  651. if (!stream3Active)
  652. {
  653. if (stream3Handle)
  654. {
  655. gosAudio_DestroyResource(&stream3Handle);
  656. stream3Handle = 0;
  657. }
  658. gosAudio_CreateResource(&stream3Handle, gosAudio_StreamedFile, (const char *) digitalStream);
  659. stream3Active = false;
  660. gosAudio_AssignResourceToChannel( STREAM3CHANNEL, stream3Handle );
  661. gosAudio_SetChannelSlider( STREAM3CHANNEL,gosAudio_Volume, digitalMasterVolume * bettyVolume );
  662. gosAudio_SetChannelSlider( STREAM3CHANNEL, gosAudio_Panning,0.0f );
  663. }
  664. else
  665. {
  666. return(-1);
  667. }
  668. }
  669. }
  670. return(NO_ERR);
  671. }
  672. //---------------------------------------------------------------------------
  673. long SoundSystem::playBettySample (unsigned long bettySampleId)
  674. {
  675. if (useSound && (bettySoundBite == NULL)) //Playing Betty takes precedence
  676. {
  677. if (bettySampleId >= numBettySamples)
  678. return(-1);
  679. long ourChannel = BETTY_CHANNEL;
  680. gosAudio_SetChannelSlider( ourChannel, gosAudio_Panning, 0.0f );
  681. float vol = 1.0;
  682. gosAudio_SetChannelSlider( ourChannel, gosAudio_Volume, digitalMasterVolume * vol * bettyVolume );
  683. gosAudio_SetChannelSlider( RADIO_CHANNEL, gosAudio_Volume, digitalMasterVolume * vol * radioVolume * 0.5f );
  684. lastBettyId = bettySampleId;
  685. channelInUse[ourChannel] = TRUE;
  686. long result = bettyDataFile->seekPacket(bettySampleId);
  687. if (result != NO_ERR)
  688. return(-1);
  689. long bettySize = bettyDataFile->getPacketSize();
  690. bettySoundBite = (MemoryPtr)soundHeap->Malloc(bettySize);
  691. gosASSERT(bettySoundBite != NULL);
  692. bettyDataFile->readPacket(bettySampleId,bettySoundBite);
  693. //--------------------------------------------------------------------
  694. // Hand GOS sound the data it needs to create the resource Handle
  695. gosAudio_Format soundFormat;
  696. soundFormat.wFormatTag = 1; //PCM
  697. MC2_WAVEFORMATEX *waveFormat = NULL;
  698. MemoryPtr dataOffset = NULL;
  699. DWORD length = 0;
  700. DWORD bitsPerSec = 0;
  701. wave_ParseWaveMemory(bettySoundBite,&waveFormat,&dataOffset,&length);
  702. bitsPerSec = waveFormat->nBlockAlign / waveFormat->nChannels * 8;
  703. soundFormat.nChannels = waveFormat->nChannels;
  704. soundFormat.nSamplesPerSec = waveFormat->nSamplesPerSec;
  705. soundFormat.nAvgBytesPerSec = waveFormat->nAvgBytesPerSec;
  706. soundFormat.nBlockAlign = waveFormat->nBlockAlign;
  707. soundFormat.wBitsPerSample = bitsPerSec;
  708. soundFormat.cbSize = 0;
  709. gosAudio_CreateResource(&bettyHandle,gosAudio_UserMemory, NULL, &soundFormat,dataOffset,length);
  710. gosAudio_AssignResourceToChannel( ourChannel, bettyHandle );
  711. gosAudio_SetChannelPlayMode(ourChannel, gosAudio_PlayOnce);
  712. return(BETTY_CHANNEL);
  713. }
  714. return(-1);
  715. }
  716. //---------------------------------------------------------------------------
  717. long SoundSystem::playSupportSample (unsigned long supportSampleId, char* fileName)
  718. {
  719. if (useSound && (supportSoundBite == NULL)) //Playing Support takes precedence
  720. {
  721. if (!fileName)
  722. {
  723. if (supportSampleId >= numSupportSamples)
  724. return(-1);
  725. }
  726. long ourChannel = SUPPORT_CHANNEL;
  727. if (fileName)
  728. {
  729. playDigitalStream(fileName);
  730. return (STREAM3CHANNEL);
  731. }
  732. else
  733. {
  734. gosAudio_SetChannelSlider( ourChannel, gosAudio_Panning, 0.0f );
  735. float vol = 1.0;
  736. gosAudio_SetChannelSlider( ourChannel, gosAudio_Volume, digitalMasterVolume * vol * bettyVolume );
  737. lastSupportId = supportSampleId;
  738. channelInUse[ourChannel] = TRUE;
  739. long result = supportDataFile->seekPacket(supportSampleId);
  740. if (result != NO_ERR)
  741. return(-1);
  742. long supportSize = supportDataFile->getPacketSize();
  743. if (supportSize > 0)
  744. {
  745. supportSoundBite = (MemoryPtr)soundHeap->Malloc(supportSize);
  746. gosASSERT(supportSoundBite != NULL);
  747. }
  748. else
  749. {
  750. return -1; //Sound Bite does NOT exist!!
  751. }
  752. supportDataFile->readPacket(supportSampleId,supportSoundBite);
  753. }
  754. //--------------------------------------------------------------------
  755. // Hand GOS sound the data it needs to create the resource Handle
  756. gosAudio_Format soundFormat;
  757. soundFormat.wFormatTag = 1; //PCM
  758. MC2_WAVEFORMATEX *waveFormat = NULL;
  759. MemoryPtr dataOffset = NULL;
  760. DWORD length = 0;
  761. DWORD bitsPerSec = 0;
  762. wave_ParseWaveMemory(supportSoundBite,&waveFormat,&dataOffset,&length);
  763. bitsPerSec = waveFormat->nBlockAlign / waveFormat->nChannels * 8;
  764. soundFormat.nChannels = waveFormat->nChannels;
  765. soundFormat.nSamplesPerSec = waveFormat->nSamplesPerSec;
  766. soundFormat.nAvgBytesPerSec = waveFormat->nAvgBytesPerSec;
  767. soundFormat.nBlockAlign = waveFormat->nBlockAlign;
  768. soundFormat.wBitsPerSample = bitsPerSec;
  769. soundFormat.cbSize = 0;
  770. gosAudio_CreateResource(&supportHandle,gosAudio_UserMemory, NULL, &soundFormat,dataOffset,length);
  771. gosAudio_AssignResourceToChannel( ourChannel, supportHandle );
  772. gosAudio_SetChannelPlayMode(ourChannel, gosAudio_PlayOnce);
  773. return(SUPPORT_CHANNEL);
  774. }
  775. return(-1);
  776. }
  777. //---------------------------------------------------------------------------
  778. bool SoundSystem::isPlayingSample (long sampleId)
  779. {
  780. for (long i=0;i<MAX_DIGITAL_SAMPLES;i++)
  781. {
  782. if ((sampleId == channelSampleId[i]))
  783. return TRUE;
  784. }
  785. return FALSE;
  786. }
  787. //---------------------------------------------------------------------------
  788. bool SoundSystem::isChannelPlaying (long channelId)
  789. {
  790. if ((channelId < 0) || (channelId > MAX_DIGITAL_SAMPLES))
  791. return(FALSE);
  792. gosAudio_PlayMode sampleStatus = gosAudio_GetChannelPlayMode(channelId);
  793. if (sampleStatus == gosAudio_PlayOnce || sampleStatus == gosAudio_Loop)
  794. return(TRUE);
  795. return FALSE;
  796. }
  797. //---------------------------------------------------------------------------
  798. bool SoundSystem::isPlayingVoiceOver (void)
  799. {
  800. if (stream3Handle)
  801. return true;
  802. return false;
  803. }
  804. //---------------------------------------------------------------------------
  805. bool SoundSystem::isDigitalMusicPlaying (void)
  806. {
  807. if (stream2Handle || stream1Handle)
  808. return true;
  809. return false;
  810. }
  811. //---------------------------------------------------------------------------
  812. long SoundSystem::findOpenChannel (long start, long end)
  813. {
  814. long channel = start;
  815. while (channelInUse[channel] && (channel < end))
  816. channel++;
  817. if (channel == end)
  818. return(-1);
  819. return(channel);
  820. }
  821. //---------------------------------------------------------------------------
  822. long SoundSystem::playDigitalSample (unsigned long sampleId, Stuff::Vector3D pos, bool allowDupes)
  823. {
  824. if (useSound && allowDupes || (!isPlayingSample(sampleId) && !allowDupes))
  825. {
  826. if (sampleId >= numSoundBites)
  827. return(-1);
  828. long ourChannel = findOpenChannel(1,SUPPORT_CHANNEL);
  829. if (ourChannel != -1)
  830. {
  831. float distanceVolume = 1.0f;
  832. float panVolume = 0.0f;
  833. if (eye && (pos.z != -9999.0f))
  834. {
  835. Stuff::Vector3D distance;
  836. distance.Subtract(eye->getPosition(),pos);
  837. float dist = distance.GetApproximateLength();
  838. if (dist < FALLOFF_DISTANCE)
  839. distanceVolume = (FALLOFF_DISTANCE - dist) / FALLOFF_DISTANCE;
  840. else
  841. return -1; //Do not play sound. TOO far away!!
  842. //Figure out where in stereo field to play.
  843. OppRotate(distance,eye->getRotation().y);
  844. panVolume = distance.x / (FALLOFF_DISTANCE * 0.5f);
  845. if (panVolume > 1.0f)
  846. panVolume = 1.0f;
  847. else if (panVolume < -1.0f)
  848. panVolume = -1.0f;
  849. }
  850. float vol = sounds[sampleId].volume * distanceVolume;
  851. if (vol > 1.0f)
  852. vol = 1.0f;
  853. else if (vol <= 0.0f) //No VOlume. DON't PLAY!
  854. return -1;
  855. gosAudio_SetChannelSlider(ourChannel,gosAudio_Panning, panVolume);
  856. gosAudio_SetChannelSlider(ourChannel,gosAudio_Volume, (digitalMasterVolume * vol * SFXVolume)) ;
  857. channelSampleId[ourChannel] = sampleId;
  858. channelInUse[ourChannel] = TRUE;
  859. if (sounds[sampleId].biteData && sounds[sampleId].resourceHandle)
  860. {
  861. gosAudio_AssignResourceToChannel( ourChannel, sounds[sampleId].resourceHandle );
  862. gosAudio_SetChannelPlayMode(ourChannel, gosAudio_PlayOnce);
  863. }
  864. return(ourChannel);
  865. }
  866. }
  867. return(-1);
  868. }
  869. //---------------------------------------------------------------------------
  870. void SoundSystem::stopDigitalSample (unsigned long sampleHandleNumber)
  871. {
  872. if (useSound)
  873. {
  874. gosAudio_PlayMode
  875. sampleStatus = gosAudio_GetChannelPlayMode(sampleHandleNumber);
  876. if ( sampleStatus == gosAudio_PlayOnce || sampleStatus == gosAudio_Loop )
  877. {
  878. fadeDown[sampleHandleNumber] = TRUE;
  879. }
  880. }
  881. }
  882. //---------------------------------------------------------------------------
  883. void SoundSystem::stopDigitalMusic (void)
  884. {
  885. if (useSound && useMusic)
  886. {
  887. if (stream1Active && stream1Handle)
  888. {
  889. if (stream1Handle)
  890. gosAudio_DestroyResource(&stream1Handle);
  891. stream1Handle = NULL;
  892. stream1Time = 0.0;
  893. stream1Active = FALSE;
  894. }
  895. if (stream2Active && stream2Handle)
  896. {
  897. if (stream2Handle)
  898. gosAudio_DestroyResource(&stream2Handle);
  899. stream2Handle = NULL;
  900. stream2Time = 0.0;
  901. stream2Active = FALSE;
  902. }
  903. currentMusicId = -1;
  904. }
  905. }
  906. //---------------------------------------------------------------------------
  907. void SoundSystem::stopSupportSample (void)
  908. {
  909. if (stream3Handle)
  910. {
  911. gosAudio_DestroyResource(&stream3Handle);
  912. stream3Handle = 0;
  913. stream3Active = false;
  914. }
  915. }
  916. //---------------------------------------------------------------------------
  917. void SoundSystem::stopBettySample (void)
  918. {
  919. if (bettyHandle)
  920. {
  921. gosAudio_SetChannelPlayMode(BETTY_CHANNEL, gosAudio_Stop);
  922. gosAudio_DestroyResource(&bettyHandle);
  923. soundHeap->Free(bettySoundBite);
  924. bettySoundBite = NULL;
  925. bettyHandle = NULL;
  926. }
  927. }
  928. //---------------------------------------------------------------------------
  929. void SoundSystem::setDigitalMasterVolume (byte volume)
  930. {
  931. if (useSound)
  932. {
  933. DigitalMasterVolume = volume;
  934. digitalMasterVolume = float(DigitalMasterVolume) / 256.0f;
  935. }
  936. }
  937. //---------------------------------------------------------------------------
  938. long SoundSystem::getDigitalMasterVolume (void)
  939. {
  940. if (useSound)
  941. {
  942. return DigitalMasterVolume;
  943. }
  944. return(0);
  945. }
  946. //---------------------------------------------------------------------------
  947. void SoundSystem::setSFXVolume(unsigned char volume)
  948. {
  949. if (useSound)
  950. {
  951. sfxVolume = volume;
  952. SFXVolume = float(sfxVolume) / 256.0f;
  953. }
  954. }
  955. //---------------------------------------------------------------------------
  956. unsigned char SoundSystem::getSFXVolume(void)
  957. {
  958. if (useSound)
  959. {
  960. return sfxVolume;
  961. }
  962. return(0);
  963. }
  964. //---------------------------------------------------------------------------
  965. void SoundSystem::setRadioVolume(unsigned char volume)
  966. {
  967. if (useSound)
  968. {
  969. RadioVolume = volume;
  970. radioVolume = float(RadioVolume) / 256.0f;
  971. }
  972. }
  973. //---------------------------------------------------------------------------
  974. unsigned char SoundSystem::getRadioVolume(void)
  975. {
  976. if (useSound)
  977. {
  978. return RadioVolume;
  979. }
  980. return(0);
  981. }
  982. //---------------------------------------------------------------------------
  983. void SoundSystem::setMusicVolume(unsigned char volume)
  984. {
  985. if (useSound)
  986. {
  987. MusicVolume = volume;
  988. musicVolume = float(MusicVolume) / 256.0f;
  989. if (useMusic)
  990. {
  991. if (stream1Active && stream1Handle)
  992. {
  993. gosAudio_SetChannelSlider( STREAM1CHANNEL,gosAudio_Volume, (digitalMasterVolume * musicVolume) );
  994. }
  995. if (stream2Active && stream2Handle)
  996. {
  997. gosAudio_SetChannelSlider( STREAM2CHANNEL,gosAudio_Volume, (digitalMasterVolume * musicVolume) );
  998. }
  999. }
  1000. }
  1001. }
  1002. //---------------------------------------------------------------------------
  1003. unsigned char SoundSystem::getMusicVolume(void)
  1004. {
  1005. if (useSound)
  1006. {
  1007. return MusicVolume;
  1008. }
  1009. return(0);
  1010. }
  1011. //---------------------------------------------------------------------------
  1012. void SoundSystem::setBettyVolume(unsigned char volume)
  1013. {
  1014. if (useSound)
  1015. {
  1016. BettyVolume = volume;
  1017. bettyVolume = float(BettyVolume) / 256.0f;
  1018. }
  1019. }
  1020. //---------------------------------------------------------------------------
  1021. unsigned char SoundSystem::getBettyVolume(void)
  1022. {
  1023. if (useSound)
  1024. {
  1025. return BettyVolume;
  1026. }
  1027. return(0);
  1028. }
  1029. //---------------------------------------------------------------------------
  1030. void SoundSystem::stopABLMusic (void)
  1031. {
  1032. stopDigitalMusic();
  1033. }
  1034. //---------------------------------------------------------------------------
  1035. void SoundSystem::playABLSFX (long sfxId)
  1036. {
  1037. playDigitalSample(sfxId);
  1038. }
  1039. //---------------------------------------------------------------------------
  1040. void SoundSystem::playABLDigitalMusic (long musicId)
  1041. {
  1042. // PAUSE(("Switching to Tune %d. Playing Tune %d.",musicId,currentMusicId));
  1043. playDigitalMusic(musicId);
  1044. }
  1045. //---------------------------------------------------------------------------