| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805 |
- /*
- ** Command & Conquer Renegade(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** This program is free software: you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation, either version 3 of the License, or
- ** (at your option) any later version.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- /***********************************************************************************************
- *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
- ***********************************************************************************************
- * *
- * Project Name : WWAudio *
- * *
- * $Archive:: /Commando/Code/WWAudio/WWAudio.cpp $*
- * *
- * Author:: Patrick Smith *
- * *
- * $Modtime:: 1/30/02 2:47p $*
- * *
- * $Revision:: 76 $*
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include "always.h"
- #include <Windows.H>
- #include "WWAudio.H"
- #include "WWDebug.H"
- #include "Utils.H"
- #include "RealCRC.H"
- #include "SoundBuffer.H"
- #include "AudibleSound.H"
- #include "Sound3D.H"
- #include "RawFile.H"
- #include "WW3D.H"
- #include "SoundScene.H"
- #include "SoundPseudo3D.H"
- #include "FFactory.H"
- #include "Registry.H"
- #include "Threads.H"
- #include "LogicalSound.h"
- #include "LogicalListener.h"
- #include "definitionclassids.h"
- #include "wwmemlog.h"
- #include "wwprofile.h"
- #include "Ini.h"
- #ifdef G_CODE_BASE
- #include "..\wwlib\argv.h"
- #endif
- ////////////////////////////////////////////////////////////////////////////////////////////////
- // Static member initialization
- ////////////////////////////////////////////////////////////////////////////////////////////////
- WWAudioClass *WWAudioClass::_theInstance = NULL;
- HANDLE WWAudioClass::_TimerSyncEvent = NULL;
- ////////////////////////////////////////////////////////////////////////////////////////////////
- // Registry value names
- ////////////////////////////////////////////////////////////////////////////////////////////////
- const char *VALUE_NAME_IS_STEREO = "stereo";
- const char *VALUE_NAME_BITS = "bits";
- const char *VALUE_NAME_HERTZ = "hertz";
- const char *VALUE_NAME_DEVICE_NAME = "device name";
- const char *VALUE_NAME_MUSIC_ENABLED = "music enabled";
- const char *VALUE_NAME_SOUND_ENABLED = "sound enabled";
- const char *VALUE_NAME_DIALOG_ENABLED = "dialog enabled";
- const char *VALUE_NAME_CINEMATIC_ENABLED = "cinematic enabled";
- const char *VALUE_NAME_MUSIC_VOL = "music volume";
- const char *VALUE_NAME_SOUND_VOL = "sound volume";
- const char *VALUE_NAME_DIALOG_VOL = "dialog volume";
- const char *VALUE_NAME_CINEMATIC_VOL = "cinematic volume";
- const char *VALUE_NAME_SPEAKER_TYPE = "speaker type";
- const int MAX_VIRTUAL_CHANNELS = 100;
- ////////////////////////////////////////////////////////////////////////////////////////////////
- // INI names
- ////////////////////////////////////////////////////////////////////////////////////////////////
- const char *WWAUDIO_INI_FILENAME = "WWAudio.ini";
- const char *WWAUDIO_INI_RELATIVE_PATHNAME = "Data\\WWAudio.ini";
- const char *INI_DEFAULT_VOLUME_SECTION = "Default Volume";
- const char *INI_MUSIC_VOLUME_ENTRY = "MUSIC_VOLUME";
- const char *INI_SOUND_VOLUME_ENTRY = "SOUND_VOLUME";
- const char *INI_DIALOG_VOLUME_ENTRY = "DIALOG_VOLUME";
- const char *INI_CINEMATIC_VOLUME_ENTRY = "CINEMATIC_VOLUME";
- ////////////////////////////////////////////////////////////////////////////////////////////////
- // Local inlines
- ////////////////////////////////////////////////////////////////////////////////////////////////
- __inline bool
- WWAudioClass::Is_OK_To_Give_Handle (const AudibleSoundClass &sound_obj)
- {
- bool is_ok = false;
- AudibleSoundClass::SOUND_TYPE type = sound_obj.Get_Type ();
- if (m_AreNewSoundsEnabled) {
- if (((type == AudibleSoundClass::TYPE_SOUND_EFFECT) && m_AreSoundEffectsEnabled) ||
- ((type == AudibleSoundClass::TYPE_MUSIC) && m_IsMusicEnabled) ||
- ((type == AudibleSoundClass::TYPE_DIALOG) && m_IsDialogEnabled) ||
- ((type == AudibleSoundClass::TYPE_CINEMATIC) && m_IsCinematicSoundEnabled))
- {
- is_ok = true;
- }
- }
- return is_ok;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////
- //
- // WWAudioClass
- //
- // 1/25/2002 12:13PM ST. Added the 'lite' flag which causes us to go through the motions of
- // creating the object (including theInstance) so it exists but disables
- // the call that initialises Miles and doesn't create a sound scene.
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- WWAudioClass::WWAudioClass (bool lite)
- : m_Driver2D (NULL),
- m_Driver3D (NULL),
- m_PlaybackRate (44100),
- m_PlaybackBits (16),
- m_PlaybackStereo (true),
- m_SpeakerType (0),
- m_ReverbFilter (INVALID_MILES_HANDLE),
- m_UpdateTimer (-1),
- m_Driver3DPseudo (NULL),
- m_MusicVolume (DEF_MUSIC_VOL),
- m_SoundVolume (DEF_SFX_VOL),
- m_RealMusicVolume (DEF_MUSIC_VOL),
- m_RealSoundVolume (DEF_SFX_VOL),
- m_MaxCacheSize (DEF_CACHE_SIZE * 1024),
- m_CurrentCacheSize (0),
- m_Max2DSamples (DEF_2D_SAMPLE_COUNT),
- m_Max3DSamples (DEF_3D_SAMPLE_COUNT),
- m_Max2DBufferSize (DEF_MAX_2D_BUFFER_SIZE),
- m_Max3DBufferSize (DEF_MAX_3D_BUFFER_SIZE),
- m_SoundScene (NULL),
- m_IsMusicEnabled (true),
- m_IsDialogEnabled (true),
- m_IsCinematicSoundEnabled (true),
- m_AreSoundEffectsEnabled (true),
- m_FileFactory (NULL),
- m_EffectsLevel (0),
- m_CurrPage (PAGE_PRIMARY),
- m_AreNewSoundsEnabled (true),
- m_BackgroundMusic (NULL),
- m_ReverbRoomType (ENVIRONMENT_GENERIC),
- m_NonDialogFadeTime (DEF_FADE_TIME),
- m_FadeType (FADE_NONE),
- m_FadeTimer (0),
- m_CachedIsMusicEnabled (true),
- m_CachedIsDialogEnabled (true),
- m_CachedIsCinematicSoundEnabled (true),
- m_CachedAreSoundEffectsEnabled (true),
- AudioIni (NULL)
- {
- ::InitializeCriticalSection (&MMSLockClass::_MSSLockCriticalSection);
- m_ForceDisable = lite;
- //
- // Start Miles Sound System
- //
- if (!lite) {
- AIL_startup ();
- }
- _theInstance = this;
- _TimerSyncEvent = ::CreateEvent (NULL, TRUE, FALSE, "WWAUDIO_TIMER_SYNC");
- //
- // Set some default values
- //
- Set_Sound_Effects_Volume ();
- Set_Music_Volume ();
- //
- // Allocate the virtual channels
- //
- for (int index = 0; index < MAX_VIRTUAL_CHANNELS; index ++) {
- m_VirtualChannels.Add (NULL);
- }
- // Create a new sound scene to manage our 3D sounds...
- if (!lite) {
- m_SoundScene = new SoundSceneClass;
- }
- m_Max3DBufferSize = m_Max3DBufferSize * 2.0F;
- return;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////
- //
- // ~WWAudioClass
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- WWAudioClass::~WWAudioClass (void)
- {
- //
- // Stop the background music
- //
- Set_Background_Music (NULL);
- //
- // Make sure the delayed-release thread is terminated
- // before we exit (otherwise the process will crash).
- //
- WWAudioThreadsClass::End_Delayed_Release_Thread ();
- Shutdown ();
- _theInstance = NULL;
- ::CloseHandle(_TimerSyncEvent);
- _TimerSyncEvent = NULL;
- ::DeleteCriticalSection (&MMSLockClass::_MSSLockCriticalSection);
- //
- // Free the list of logical "types".
- //
- Reset_Logical_Types ();
- if (AudioIni != NULL) delete AudioIni;
- return;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Flush_Cache
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::Flush_Cache (void)
- {
- // Loop through all the hash indicies
- for (int hash_index = 0; hash_index < MAX_CACHE_HASH; hash_index ++) {
- // Loop through all the buffers at this hash index and free them all
- for (int index = 0; index < m_CachedBuffers[hash_index].Count (); index ++) {
- CACHE_ENTRY_STRUCT &info = m_CachedBuffers[hash_index][index];
- // Free the buffer data
- SAFE_FREE (info.string_id);
- REF_PTR_RELEASE (info.buffer);
- }
- // Remove all the entries for this hash index
- m_CachedBuffers[hash_index].Delete_All ();
- }
- m_CurrentCacheSize = 0;
- return;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Open_2D_Device
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- WWAudioClass::DRIVER_TYPE_2D
- WWAudioClass::Open_2D_Device (LPWAVEFORMAT format)
- {
- MMSLockClass lock;
- //
- // Store the playback settings for future reference
- //
- m_PlaybackRate = format->nSamplesPerSec;
- m_PlaybackBits = (format->nAvgBytesPerSec << 3) / (format->nChannels * format->nSamplesPerSec);
- m_PlaybackStereo = bool(format->nChannels > 1);
- //
- // Assume we will open the DirectSound driver
- //
- DRIVER_TYPE_2D type = DRIVER2D_DSOUND;
- // First close the current 2D device and take
- // all the sound handles away from the sound objects.
- Close_2D_Device ();
- AIL_set_preference (AIL_LOCK_PROTECTION, NO);
- // Try to use DirectSound if possible
- S32 success = ::AIL_set_preference (DIG_USE_WAVEOUT, FALSE);
- //WWASSERT (success == AIL_NO_ERROR); // This assert fires if there is no sound card.
- // Open the driver
- success = ::AIL_waveOutOpen (&m_Driver2D, NULL, 0, format);
- // Do we need to switch from direct sound to waveout?
- if ((success == AIL_NO_ERROR) &&
- (m_Driver2D != NULL) &&
- (m_Driver2D->emulated_ds == TRUE)) {
- ::AIL_waveOutClose (m_Driver2D);
- success = 2;
- WWDEBUG_SAY (("WWAudio: Detected 2D DirectSound emulation, switching to WaveOut.\r\n"));
- }
- // If we couldn't open the direct sound device, then use the
- // default wave out device
- if (success != AIL_NO_ERROR) {
- // Try to use the default wave out driver
- success = ::AIL_set_preference (DIG_USE_WAVEOUT, TRUE);
- //WWASSERT (success == AIL_NO_ERROR); // This assert fires if there is no sound card.
- // Open the driver
- success = ::AIL_waveOutOpen (&m_Driver2D, NULL, 0, format);
- type = (success == AIL_NO_ERROR) ? DRIVER2D_WAVEOUT : DRIVER2D_ERROR;
- }
- // Allocate all the available handles if we were successful
- if (success == AIL_NO_ERROR) {
- Allocate_2D_Handles ();
- ReAssign_2D_Handles ();
- } else {
- Close_2D_Device ();
- WWDEBUG_SAY (("WWAudio: Error initializing 2D device.\r\n"));
- }
- // Return the opened device type
- return type;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Open_2D_Device
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- WWAudioClass::DRIVER_TYPE_2D
- WWAudioClass::Open_2D_Device
- (
- bool stereo,
- int bits,
- int hertz
- )
- {
- // Build a wave format structure from the params
- PCMWAVEFORMAT wave_format = { 0 };
- wave_format.wf.wFormatTag = WAVE_FORMAT_PCM;
- wave_format.wf.nChannels = stereo ? 2 : 1;
- wave_format.wf.nSamplesPerSec = hertz;
- wave_format.wf.nAvgBytesPerSec = (wave_format.wf.nChannels * wave_format.wf.nSamplesPerSec * bits) >> 3;
- wave_format.wf.nBlockAlign = (wave_format.wf.nChannels * bits) >> 3;
- wave_format.wBitsPerSample = bits;
- DRIVER_TYPE_2D type = DRIVER2D_ERROR;
- while (((type = Open_2D_Device ((LPWAVEFORMAT)&wave_format)) == DRIVER2D_ERROR) &&
- (wave_format.wf.nSamplesPerSec >= 11025)) {
- //
- // Cut the playback rate in half and try again
- //
- wave_format.wf.nSamplesPerSec = wave_format.wf.nSamplesPerSec >> 1;
- wave_format.wf.nAvgBytesPerSec = (wave_format.wf.nChannels * wave_format.wf.nSamplesPerSec * bits) >> 3;
- wave_format.wf.nBlockAlign = (wave_format.wf.nChannels * bits) >> 3;
- }
- // Pass this structure onto the function that actually opens the device
- return type;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Close_2D_Device
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- bool
- WWAudioClass::Close_2D_Device (void)
- {
- MMSLockClass lock;
- //
- // Note: We MUST close the 3D device when we close the 2D device...
- //
- Close_3D_Device ();
- //
- // Free any 2D sound handles
- //
- Remove_2D_Sound_Handles ();
- Release_2D_Handles ();
- //
- // Do we have an open driver handle to close?
- //
- bool retval = false;
- if (m_Driver2D != NULL) {
- //
- // Close the driver
- //
- ::AIL_waveOutClose (m_Driver2D);
- m_Driver2D = NULL;
- retval = true;
- }
- return retval;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Close_3D_Device
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- bool
- WWAudioClass::Close_3D_Device (void)
- {
- MMSLockClass lock;
- bool retval = false;
- //
- // Remove all the handles
- //
- Remove_3D_Sound_Handles ();
- Release_3D_Handles ();
- //
- // Do we have an open driver handle to close?
- //
- if (m_Driver3D != NULL) {
- ::AIL_close_3D_provider (m_Driver3D);
- m_Driver3D = NULL;
- retval = true;
- }
- return retval;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Get_Sound_Buffer
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- SoundBufferClass *
- WWAudioClass::Get_Sound_Buffer (const char *filename, bool is_3d)
- {
- WWPROFILE ("Get_Sound_Buffer");
- //
- // Try to find the buffer in our cache, otherwise create a new buffer.
- //
- SoundBufferClass *buffer = Find_Cached_Buffer (filename);
- if (buffer == NULL) {
- FileClass *file = Get_File (filename);
- if (file != NULL && file->Is_Available ()) {
- buffer = Create_Sound_Buffer (*file, filename, is_3d);
- } else {
- static int count = 0;
- if ( ++count < 10 ) {
- WWDEBUG_SAY(( "Sound \"%s\" not found\r\n", filename ));
- }
- }
- Return_File (file);
- }
- return buffer;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Get_Sound_Buffer
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- SoundBufferClass *
- WWAudioClass::Get_Sound_Buffer (FileClass &file, const char *string_id, bool is_3d)
- {
- WWMEMLOG(MEM_SOUND);
- //
- // Try to find the buffer in our cache, otherwise create a new buffer.
- //
- SoundBufferClass *buffer = Find_Cached_Buffer (string_id);
- if (buffer == NULL) {
- buffer = Create_Sound_Buffer (file, string_id, is_3d);
- }
- return buffer;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Find_Cached_Buffer
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- SoundBufferClass *
- WWAudioClass::Find_Cached_Buffer (const char *string_id)
- {
- WWPROFILE ("Find_Cached_Buffer");
- SoundBufferClass *sound_buffer = NULL;
- // Param OK?
- WWASSERT (string_id != NULL);
- if (string_id != NULL) {
- //
- // Determine which index in our hash table to use
- //
- int hash_index = ::CRC_Stringi (string_id) & CACHE_HASH_MASK;
- //
- // Loop through all the buffers at this hash index and try to find
- // one that matches the requested name
- //
- for (int index = 0; index < m_CachedBuffers[hash_index].Count (); index ++) {
- //
- // Is this the sound buffer we were looking for?
- //
- CACHE_ENTRY_STRUCT &info = m_CachedBuffers[hash_index][index];
- if (::lstrcmpi (info.string_id, string_id) == 0) {
- sound_buffer = info.buffer;
- sound_buffer->Add_Ref ();
- break;
- }
- }
- }
- //
- // Return a pointer to the cached sound buffer
- //
- return sound_buffer;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Free_Cache_Space
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- bool
- WWAudioClass::Free_Cache_Space (int bytes)
- {
- int bytes_freed = 0;
- // Loop through all the hash indicies
- for (int hash_index = 0;
- (hash_index < MAX_CACHE_HASH) && (bytes_freed < bytes);
- hash_index ++) {
- // Loop through all the buffers at this hash index
- for (int index = 0;
- (index < m_CachedBuffers[hash_index].Count ()) && (bytes_freed < bytes);
- index ++) {
- // Can we free this cached buffer?
- CACHE_ENTRY_STRUCT &info = m_CachedBuffers[hash_index][index];
- if ((info.buffer != NULL) && (info.buffer->Num_Refs () == 1)) {
- // Add the size of this buffer to our count of bytes freed
- bytes_freed += info.buffer->Get_Raw_Length ();
- // Free the buffer data
- SAFE_FREE (info.string_id);
- REF_PTR_RELEASE (info.buffer);
- // Remove this entry from the hash table
- m_CachedBuffers[hash_index].Delete (index);
- index --;
- }
- }
- }
- // Make sure to recompute out current cache size
- m_CurrentCacheSize -= bytes_freed;
- WWASSERT (m_CurrentCacheSize >= 0);
- // Return true if we freed enough bytes in the cache
- return (bytes_freed >= bytes);
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Cache_Buffer
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- bool
- WWAudioClass::Cache_Buffer
- (
- SoundBufferClass *buffer,
- const char *string_id
- )
- {
- WWPROFILE ("Cache_Buffer");
- // Assume failure
- bool retval = false;
- // Params OK?
- WWASSERT (buffer != NULL);
- WWASSERT (string_id != NULL);
- if ((buffer != NULL) && (string_id != NULL)) {
- //
- // Attempt to free space in the cache (if needed)
- //
- /*int space_needed = (m_CurrentCacheSize + buffer->Get_Raw_Length ()) - (int)m_MaxCacheSize;
- if (space_needed > 0) {
- Free_Cache_Space (space_needed);
- }*/
- // Do we have enough space in the cache for this buffer?
- //space_needed = (m_CurrentCacheSize + buffer->Get_Raw_Length ()) - (int)m_MaxCacheSize;
- //if (space_needed <= 0) {
- //
- // Determine which index in our hash table to use
- //
- int hash_index = ::CRC_Stringi (string_id) & CACHE_HASH_MASK;
- //
- // Add this buffer to the hash table at the given index.
- // Note: The assignment operator caused by the Add call
- // will add a reference to the sound buffer.
- //
- CACHE_ENTRY_STRUCT info;
- info.string_id = (char *)string_id;
- info.buffer = buffer;
- m_CachedBuffers[hash_index].Add (info);
- // Update our current cache size
- m_CurrentCacheSize += buffer->Get_Raw_Length ();
- retval = true;
- //}
- }
- if (retval == false) {
- WWDEBUG_SAY (("Unable to cache sound: %s.\r\n", string_id));
- }
- // Return the true/false result code
- return retval;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Create_Sound_Buffer
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- SoundBufferClass *
- WWAudioClass::Create_Sound_Buffer
- (
- FileClass & file,
- const char *string_id,
- bool is_3d
- )
- {
- WWPROFILE ("Create_Sound_Buffer");
- SoundBufferClass *sound_buffer = NULL;
- //
- // Determine how large this buffer can be
- //
- int max_size = is_3d ? m_Max3DBufferSize : m_Max2DBufferSize;
- //
- // Create a streaming sound buffer object if the
- // file is too large to preload.
- //
- if (file.Size () > max_size) {
- sound_buffer = new StreamSoundBufferClass;
- } else {
- sound_buffer = new SoundBufferClass;
- }
- SET_REF_OWNER(sound_buffer);
- //
- // Create a new sound buffer from the provided file
- //
- bool success = sound_buffer->Load_From_File (file);
- sound_buffer->Set_Filename (string_id);
- WWASSERT (success);
- // If we were successful in creating the sound buffer, then
- // try to cache it as well, otherwise free the buffer and return NULL.
- if (success && (string_id != NULL)) {
- Cache_Buffer (sound_buffer, string_id);
- } else if (success == false) {
- REF_PTR_RELEASE (sound_buffer);
- }
- // Return a pointer to the new sound buffer
- return sound_buffer;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Create_Sound_Buffer
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- SoundBufferClass *
- WWAudioClass::Create_Sound_Buffer
- (
- unsigned char * file_image,
- unsigned long bytes,
- const char * string_id,
- bool is_3d
- )
- {
- WWPROFILE ("Create_Sound_Buffer");
- // Create a new sound buffer from the provided file
- SoundBufferClass *sound_buffer = new SoundBufferClass;
- SET_REF_OWNER(sound_buffer);
- //
- // Initialize the sound from this piece of memory
- //
- bool success = sound_buffer->Load_From_Memory (file_image, bytes);
- sound_buffer->Set_Filename (string_id);
- WWASSERT (success);
- // If we were successful in creating the sound buffer, then
- // try to cache it as well, otherwise free the buffer and return NULL.
- if (success && (string_id != NULL)) {
- Cache_Buffer (sound_buffer, string_id);
- } else if (success == false) {
- REF_PTR_RELEASE (sound_buffer);
- }
- // Return a pointer to the new sound buffer
- return sound_buffer;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Create_Sound_Effect
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- AudibleSoundClass *
- WWAudioClass::Create_Sound_Effect (FileClass &file, const char *string_id)
- {
- WWPROFILE ("Create_Sound_Effect");
- // Create a new sound object
- AudibleSoundClass *sound_obj = NEW_REF( AudibleSoundClass, () );
- if (Is_Disabled () == false) {
- // Try to find the buffer in our cache, otherwise create a new buffer.
- SoundBufferClass *buffer = Get_Sound_Buffer (file, string_id, false);
- // Pass the actual sound data onto the sound object
- sound_obj->Set_Buffer (buffer);
- REF_PTR_RELEASE (buffer);
- }
- // Return a pointer to the sound effect
- return sound_obj;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Create_Sound_Effect
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- AudibleSoundClass *
- WWAudioClass::Create_Sound_Effect (const char *filename)
- {
- WWPROFILE ("Create_Sound_Effect");
- // Assume failure
- AudibleSoundClass *sound_obj = NULL;
- if (Is_Disabled () == false) {
- // Param OK?
- WWASSERT (filename != NULL);
- if (filename != NULL) {
- // Create a file object and pass it onto the appropriate function
- FileClass *file = Get_File (filename);
- if (file && file->Is_Available()) {
- sound_obj = Create_Sound_Effect (*file, filename);
- } else {
- WWDEBUG_SAY(( "Sound %s not found\r\n", filename ));
- }
- Return_File (file);
- }
- }
- // Return a pointer to the sound effect
- return sound_obj;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Create_Sound_Effect
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- AudibleSoundClass *
- WWAudioClass::Create_Sound_Effect
- (
- const char * string_id,
- unsigned char *raw_wave_data,
- unsigned long bytes
- )
- {
- WWPROFILE ("Create_Sound_Effect");
- // Create a new sound object
- AudibleSoundClass *sound_obj = NEW_REF( AudibleSoundClass, () );
- if (Is_Disabled () == false) {
- // Try to find the buffer in our cache, otherwise create a new buffer.
- SoundBufferClass *buffer = Find_Cached_Buffer (string_id);
- if (buffer == NULL) {
- buffer = Create_Sound_Buffer (raw_wave_data, bytes, string_id, false);
- }
- // Pass the actual sound data onto the sound object
- sound_obj->Set_Buffer (buffer);
- REF_PTR_RELEASE (buffer);
- }
- // Return a pointer to the sound effect
- return sound_obj;
- }
- /////////////////////////////////////////////////////////////////////////////////
- //
- // Create_3D_Sound
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- Sound3DClass *
- WWAudioClass::Create_3D_Sound (FileClass &file, const char *string_id, int classid_hint)
- {
- WWPROFILE ("Create_3D_Sound (FileClass)");
- Sound3DClass *sound_obj = NULL;
- if (Is_Disabled () == false) {
- // Try to find the buffer in our cache, otherwise create a new buffer.
- SoundBufferClass *buffer = Get_Sound_Buffer (file, string_id, true);
- //
- // What type of sound object should we create? A true 3D sound or one of
- // our pseudo-3d sounds? (volume and panning only)
- //
- if ( classid_hint == CLASSID_PSEUDO3D ||
- Validate_3D_Sound_Buffer (buffer) == false)
- {
- sound_obj = new SoundPseudo3DClass;
- sound_obj->Set_Buffer (buffer);
- } else if (buffer != NULL) {
- sound_obj = new Sound3DClass;
- sound_obj->Set_Buffer (buffer);
- }
- REF_PTR_RELEASE (buffer);
- }
- // Return a pointer to the sound effect
- return sound_obj;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Create_3D_Sound
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- Sound3DClass *
- WWAudioClass::Create_3D_Sound
- (
- const char * filename,
- int classid_hint
- )
- {
- WWPROFILE ("Create_3D_Sound (filename)");
- WWMEMLOG(MEM_SOUND);
- // Assume failure
- Sound3DClass *sound_obj = NULL;
- if (Is_Disabled () == false) {
- // Param OK?
- WWASSERT (filename != NULL);
- if (filename != NULL) {
- // Try to find the buffer in our cache, otherwise create a new buffer.
- SoundBufferClass *buffer = Get_Sound_Buffer (filename, true);
- //
- // What type of sound object should we create? A true 3D sound or one of
- // our pseudo-3d sounds? (volume and panning only)
- //
- if ( classid_hint == CLASSID_PSEUDO3D ||
- Validate_3D_Sound_Buffer (buffer) == false)
- {
- sound_obj = new SoundPseudo3DClass;
- sound_obj->Set_Buffer (buffer);
- } else if (buffer != NULL) {
- sound_obj = new Sound3DClass;
- sound_obj->Set_Buffer (buffer);
- } else {
- static int count = 0;
- if ( ++count < 10 ) {
- WWDEBUG_SAY(( "Sound File not Found \"%s\"\r\n", filename ));
- }
- }
- REF_PTR_RELEASE (buffer);
- }
- }
- // Return a pointer to the sound effect
- return sound_obj;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Create_3D_Sound
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- Sound3DClass *
- WWAudioClass::Create_3D_Sound
- (
- const char * string_id,
- unsigned char * raw_wave_data,
- unsigned long bytes,
- int classid_hint
- )
- {
- WWPROFILE ("Create_3D_Sound (Raw)");
- Sound3DClass *sound_obj = NULL;
- if (Is_Disabled () == false) {
- //
- // Try to find the buffer in our cache, otherwise create a new buffer.
- //
- SoundBufferClass *buffer = Find_Cached_Buffer (string_id);
- if (buffer == NULL) {
- buffer = Create_Sound_Buffer (raw_wave_data, bytes, string_id, true);
- }
- //
- // What type of sound object should we create? A true 3D sound or one of
- // our pseudo-3d sounds? (volume and panning only)
- //
- if ( classid_hint == CLASSID_PSEUDO3D ||
- Validate_3D_Sound_Buffer (buffer) == false)
- {
- sound_obj = new SoundPseudo3DClass;
- sound_obj->Set_Buffer (buffer);
- } else if (buffer != NULL) {
- sound_obj = new Sound3DClass;
- sound_obj->Set_Buffer (buffer);
- }
- REF_PTR_RELEASE (buffer);
- }
- // Return a pointer to the sound effect
- return sound_obj;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Create_Sound
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- AudibleSoundClass *
- WWAudioClass::Create_Sound
- (
- int definition_id,
- RefCountClass *user_obj,
- uint32 user_data,
- int classid_hint
- )
- {
- WWPROFILE ("Create_Sound");
- AudibleSoundClass *sound = NULL;
- //
- // Find the definition
- //
- DefinitionClass *definition = DefinitionMgrClass::Find_Definition (definition_id);
- if (definition != NULL ) {
- //
- // Make sure this is really a sound definition
- //
- WWASSERT (definition->Get_Class_ID () == CLASSID_SOUND);
- if (definition->Get_Class_ID () == CLASSID_SOUND) {
- AudibleSoundDefinitionClass *sound_def = reinterpret_cast<AudibleSoundDefinitionClass *> (definition);
- //
- // Create an instance of the sound
- //
- sound = sound_def->Create_Sound (classid_hint);
- if (sound != NULL) {
- sound->Set_User_Data (user_obj, user_data);
- }
- }
- }
- return sound;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Create_Sound
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- AudibleSoundClass *
- WWAudioClass::Create_Sound
- (
- const char * def_name,
- RefCountClass *user_obj,
- uint32 user_data,
- int classid_hint
- )
- {
- WWPROFILE ("Create_Sound");
- AudibleSoundClass *sound = NULL;
- //
- // Find the definition
- //
- DefinitionClass *definition = DefinitionMgrClass::Find_Typed_Definition (def_name, CLASSID_SOUND, true);
- if (definition != NULL ) {
- //
- // Make sure this is really a sound definition
- //
- WWASSERT (definition->Get_Class_ID () == CLASSID_SOUND);
- if (definition->Get_Class_ID () == CLASSID_SOUND) {
- AudibleSoundDefinitionClass *sound_def = reinterpret_cast<AudibleSoundDefinitionClass *> (definition);
- //
- // Create an instance of the sound
- //
- sound = sound_def->Create_Sound (classid_hint);
- if (sound != NULL) {
- sound->Set_User_Data (user_obj, user_data);
- }
- }
- }
- return sound;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Create_Continuous_Sound
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- AudibleSoundClass *
- WWAudioClass::Create_Continuous_Sound
- (
- int definition_id,
- RefCountClass *user_obj,
- uint32 user_data,
- int classid_hint
- )
- {
- WWPROFILE ("Create_Continuous_Sound");
- //
- // Create an instance of the sound and play it
- //
- AudibleSoundClass *sound = Create_Sound (definition_id, user_obj, user_data, classid_hint);
- if (sound != NULL) {
- if (sound->Get_Loop_Count () != INFINITE_LOOPS) {
- WWDEBUG_SAY (("Audio Error: Creating a continuous sound with a finite loop count!\r\n"));
- }
- }
- return sound;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Create_Instant_Sound
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- int
- WWAudioClass::Create_Instant_Sound
- (
- int definition_id,
- const Matrix3D & tm,
- RefCountClass * user_obj,
- uint32 user_data,
- int classid_hint
- )
- {
- WWPROFILE ("Create_Instant_Sound");
- int sound_id = 0;
- //
- // Create an instance of the sound and play it
- //
- AudibleSoundClass *sound = Create_Sound (definition_id, user_obj, user_data, classid_hint);
- if (sound != NULL) {
- if (sound->Get_Loop_Count () == INFINITE_LOOPS) {
- WWDEBUG_SAY (("Audio Error: Creating an instant sound %s with an infinite loop count!\r\n",sound->Get_Definition()->Get_Name()));
- }
- sound_id = sound->Get_ID ();
- sound->Set_Transform (tm);
- sound->Add_To_Scene ();
- sound->Release_Ref ();
- }
- return sound_id;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Create_Continuous_Sound
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- AudibleSoundClass *
- WWAudioClass::Create_Continuous_Sound
- (
- const char * def_name,
- RefCountClass *user_obj,
- uint32 user_data,
- int classid_hint
- )
- {
- WWPROFILE ("Create_Continuous_Sound");
- //
- // Create an instance of the sound and play it
- //
- AudibleSoundClass *sound = Create_Sound (def_name, user_obj, user_data, classid_hint);
- if (sound != NULL) {
- if (sound->Get_Loop_Count () != INFINITE_LOOPS) {
- WWDEBUG_SAY (("Audio Error: Creating a continuous sound with a finite loop count!\r\n"));
- }
- }
- return sound;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Create_Instant_Sound
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- int
- WWAudioClass::Create_Instant_Sound
- (
- const char * def_name,
- const Matrix3D & tm,
- RefCountClass * user_obj,
- uint32 user_data,
- int classid_hint
- )
- {
- WWPROFILE ("Create_Instant_Sound");
- int sound_id = 0;
- //
- // Create an instance of the sound and play it
- //
- AudibleSoundClass *sound = Create_Sound (def_name, user_obj, user_data, classid_hint);
- if (sound != NULL) {
- if (sound->Get_Loop_Count () == INFINITE_LOOPS) {
- WWDEBUG_SAY (("Audio Error: Creating an instant sound %s with an infinite loop count!\r\n",sound->Get_Definition()->Get_Name()));
- }
- sound_id = sound->Get_ID ();
- sound->Set_Transform (tm);
- sound->Add_To_Scene ();
- sound->Release_Ref ();
- }
- return sound_id;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Flush_Playlist
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::Flush_Playlist (SOUND_PAGE page)
- {
- //
- // Loop through all the entries in this playlist
- //
- for (int index = 0; index < m_Playlist[page].Count (); index ++) {
- AudibleSoundClass *sound_obj = m_Playlist[page][index];
- if (sound_obj != NULL) {
- sound_obj->Stop ();
- sound_obj->Remove_From_Scene ();
- }
- //REF_PTR_RELEASE (sound_obj);
- }
- //
- // Now, make sure to free any completed sounds
- //
- Free_Completed_Sounds ();
- //
- // Free the list structure
- //
- m_Playlist[page].Delete_All ();
- return ;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Flush_Playlist
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::Flush_Playlist (void)
- {
- Flush_Playlist (PAGE_PRIMARY);
- Flush_Playlist (PAGE_SECONDARY);
- return ;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Free_Completed_Sounds
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::Free_Completed_Sounds (void)
- {
- if (m_CompletedSounds.Count () > 0) {
- //
- // Loop through all the entries in the completed sounds list
- //
- for (int index = 0; index < m_CompletedSounds.Count (); index ++) {
- AudibleSoundClass *sound_obj = m_CompletedSounds[index];
- WWASSERT(sound_obj != NULL); //TSS 05/24/99
- //
- // Be careful not to remove the sound from the playlist unless
- // its really done playing
- //
- if (sound_obj->Get_State () == AudibleSoundClass::STATE_STOPPED) {
- //
- // Remove this sound from the playlist
- //
- bool found = false;
- for (int page = 0; page < PAGE_COUNT && !found; page ++) {
- for (int play_index = 0; (play_index < m_Playlist[page].Count ()) && !found; play_index ++) {
- if (m_Playlist[page][play_index] == sound_obj) {
- //
- // Free our hold on this sound object
- //
- m_Playlist[page].Delete (play_index);
- REF_PTR_RELEASE (sound_obj);
- found = true;
- }
- }
- }
- }
- }
- //
- // Free the list structure
- //
- m_CompletedSounds.Delete_All ();
- //
- // Try to give a play-handle back to a sound that was priority-bumped.
- //
- Reprioritize_Playlist ();
- }
- return;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Get_Playlist_Entry
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- AudibleSoundClass *
- WWAudioClass::Get_Playlist_Entry (int index) const
- {
- AudibleSoundClass *sound_obj = NULL;
- // Params OK?
- WWASSERT (index >= 0 && index < m_Playlist[m_CurrPage].Count ());
- if ((index >= 0) && (index < m_Playlist[m_CurrPage].Count ())) {
- m_Playlist[m_CurrPage][index]->Add_Ref ();
- m_Playlist[m_CurrPage][index];
- }
- // Return a pointer to the sound object
- return sound_obj;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Add_To_Playlist
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- bool
- WWAudioClass::Add_To_Playlist (AudibleSoundClass *sound)
- {
- bool retval = false;
- WWASSERT (sound != NULL);
- if (sound != NULL) {
- //
- // Loop through all the entries in the playlist
- //
- bool already_added = false;
- for (int index = 0; (index < m_Playlist[m_CurrPage].Count ()) && (already_added == false); index ++) {
- already_added = (sound == m_Playlist[m_CurrPage][index]);
- }
- //
- // Add this sound to our playlist
- //
- if (already_added == false) {
- sound->Add_Ref ();
- m_Playlist[m_CurrPage].Add (sound);
- }
- }
- return retval;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Remove_From_Playlist
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- bool
- WWAudioClass::Remove_From_Playlist (AudibleSoundClass *sound_obj)
- {
- bool retval = false;
- WWASSERT (sound_obj != NULL);
- if (sound_obj != NULL) {
- //
- // Loop through all the entries in the playlist
- //
- for (int page = 0; page < PAGE_COUNT && !retval; page ++) {
- for (int index = 0; (index < m_Playlist[page].Count ()) && !retval; index ++) {
- //
- // Is this the entry we are looking for?
- //
- if (sound_obj == m_Playlist[page][index]) {
- //
- // Add this sound to the 'completed' list
- //
- m_CompletedSounds.Add (sound_obj);
- retval = true;
- }
- }
- }
- //
- // Notify any callbacks that this sound is ending...
- //
- if (sound_obj->Get_Loop_Count () != INFINITE_LOOPS) {
- for (int index = 0; index < m_EOSCallbackList.Count (); index ++) {
- uint32 user_data = NULL;
- LPFNEOSCALLBACK callback = m_EOSCallbackList.Get_Callback (index, &user_data);
- if (callback != NULL) {
- (*callback) (sound_obj, user_data);
- }
- }
- }
- }
- return retval;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Is_Sound_In_Playlist
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- bool
- WWAudioClass::Is_Sound_In_Playlist (AudibleSoundClass *sound_obj)
- {
- // Assume failure
- bool retval = false;
- // Loop through all the entries in the playlist
- for (int index = 0; (index < m_Playlist[m_CurrPage].Count ()) && (retval == false); index ++) {
- if (sound_obj == m_Playlist[m_CurrPage][index]) {
- retval = true;
- }
- }
- // Return the true/false result code
- return retval;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Reprioritize_Playlist
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::Reprioritize_Playlist (void)
- {
- AudibleSoundClass *sound_to_get_handle = NULL;
- float hightest_priority = 0;
- //
- // Loop through all the entries in the playlist
- //
- for (int index = 0; index < m_Playlist[m_CurrPage].Count (); index ++) {
- //
- // Is this the highest priority without a miles handle?
- //
- AudibleSoundClass *sound_obj = m_Playlist[m_CurrPage][index];
- if ((sound_obj->Get_Miles_Handle () == NULL) &&
- (sound_obj->Is_Sound_Culled () == false) &&
- (sound_obj->Get_Priority () > hightest_priority))
- {
- //
- // This is now the highest priority sound effect without
- // a play-handle.
- //
- sound_to_get_handle = sound_obj;
- hightest_priority = sound_obj->Get_Priority ();
- }
- }
- //
- // Get a new handle for this sound if necessary
- //
- if (sound_to_get_handle != NULL) {
- sound_to_get_handle->Allocate_Miles_Handle ();
- }
- return;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // On_Frame_Update
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::On_Frame_Update (unsigned int milliseconds)
- {
- //
- // Free any sounds we completed last frame
- //
- Free_Completed_Sounds ();
- //
- // Calculate the time in ms since the last frame
- //
- unsigned int time_delta = milliseconds;
- if (time_delta == 0) {
- time_delta = WW3D::Get_Frame_Time ();
- }
- //
- // Update the sound scene as necessary
- //
- if (m_CurrPage == PAGE_PRIMARY && m_SoundScene != NULL) {
- m_SoundScene->On_Frame_Update (milliseconds);
- m_SoundScene->Collect_Logical_Sounds ();
- }
- //int dialog_count = 0;
- //
- // Loop through all the entries in the playlist
- //
- for (int index = 0; index < m_Playlist[m_CurrPage].Count (); index ++) {
- //
- // Update this sound object
- //
- AudibleSoundClass *sound_obj = m_Playlist[m_CurrPage][index];
- sound_obj->On_Frame_Update (time_delta);
- //
- // Is this an important piece of dialog?
- //
- /*if ( sound_obj->Is_Sound_Culled () == false &&
- sound_obj->Get_Type () == AudibleSoundClass::TYPE_DIALOG &&
- sound_obj->Get_Priority () > 0.5F)
- {
- dialog_count ++;
- }*/
- }
- //
- // Fade sound fx and music when there's important dialog playing.
- //
- /*if (dialog_count == 0) {
- Fade_Non_Dialog_In ();
- } else {
- Fade_Non_Dialog_Out ();
- }*/
- //
- // Update any fading we have going on
- //
- //Update_Fade ();
- return;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Release_2D_Handles
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::Release_2D_Handles (void)
- {
- MMSLockClass lock;
- // Release our hold on all the samples we've allocated
- for (int index = 0; index < m_2DSampleHandles.Count (); index ++) {
- HSAMPLE sample = m_2DSampleHandles[index];
- if (sample != NULL) {
- ::AIL_release_sample_handle (sample);
- }
- }
- m_2DSampleHandles.Delete_All ();
- return;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Allocate_2D_Handles
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::Allocate_2D_Handles (void)
- {
- MMSLockClass lock;
- // Start fresh
- Release_2D_Handles ();
- if (m_Driver2D != NULL) {
- // Attempt to allocate our share of 2D sample handles
- for (int index = 0; index < m_Max2DSamples; index ++) {
- HSAMPLE sample = ::AIL_allocate_sample_handle (m_Driver2D);
- if (sample != NULL) {
- ::AIL_set_sample_user_data (sample, INFO_OBJECT_PTR, NULL);
- m_2DSampleHandles.Add (sample);
- }
- }
- // Record our actual number of available 2D sample handles
- m_Max2DSamples = m_2DSampleHandles.Count ();
- }
- return;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Get_2D_Sample
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- HSAMPLE
- WWAudioClass::Get_2D_Sample (const AudibleSoundClass &sound_obj)
- {
- if (Is_OK_To_Give_Handle (sound_obj) == false) {
- return (HSAMPLE)INVALID_MILES_HANDLE;
- }
- MMSLockClass lock;
- float lowest_priority = sound_obj.Get_Priority ();
- float lowest_runtime_priority = sound_obj.Get_Runtime_Priority ();
- AudibleSoundClass *lowest_pri_sound = NULL;
- HSAMPLE lowest_pri_sample = NULL;
- HSAMPLE free_sample = (HSAMPLE)INVALID_MILES_HANDLE;
- // Loop through all the available sample handles and try to find
- // one that isn't being used to play a sound.
- bool found = false;
- for (int index = 0; (index < m_2DSampleHandles.Count ()) && !found; index ++) {
- HSAMPLE sample = m_2DSampleHandles[index];
- if (sample != NULL) {
- // Get a pointer to the object that is currently using this sample
- AudibleSoundClass *sound_obj = (AudibleSoundClass *)::AIL_sample_user_data (sample, INFO_OBJECT_PTR);
- if (sound_obj == NULL) {
- // Return this sample handle to the caller
- free_sample = sample;
- found = true;
- } else {
- //
- // Determine if this sound's priority is lesser then the sound we want to play.
- // This is done by comparing both the designer-specified priority and the current
- // runtime priority (which is calculated by distance to the listener).
- //
- float priority = sound_obj->Get_Priority ();
- float runtime_priority = sound_obj->Get_Runtime_Priority ();
- if ( (priority < lowest_priority) ||
- (priority == lowest_priority && runtime_priority <= lowest_runtime_priority))
- {
- lowest_priority = priority;
- lowest_pri_sound = sound_obj;
- lowest_pri_sample = sample;
- lowest_runtime_priority = runtime_priority;
- }
- }
- }
- }
- // Steal the sample handle from the lower priority
- // sound and return the handle to the caller.
- if ((found == false) && (lowest_pri_sound != NULL)) {
- lowest_pri_sound->Free_Miles_Handle ();
- free_sample = lowest_pri_sample;
- }
- // Return the free sample handle if we found one
- return free_sample;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Get_3D_Sample
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- H3DSAMPLE
- WWAudioClass::Get_3D_Sample (const Sound3DClass &sound_obj)
- {
- if (Is_OK_To_Give_Handle (sound_obj) == false) {
- return (H3DSAMPLE)INVALID_MILES_HANDLE;
- }
- MMSLockClass lock;
- float lowest_priority = sound_obj.Get_Priority ();
- float lowest_runtime_priority = sound_obj.Get_Runtime_Priority ();
- AudibleSoundClass *lowest_pri_sound = NULL;
- H3DSAMPLE lowest_pri_sample = NULL;
- H3DSAMPLE free_sample = (H3DSAMPLE)INVALID_MILES_HANDLE;
- // Loop through all the available sample handles and try to find
- // one that isn't being used to play a sound.
- bool found = false;
- for (int index = 0; (index < m_3DSampleHandles.Count ()) && !found; index ++) {
- H3DSAMPLE sample = m_3DSampleHandles[index];
- if (sample != NULL) {
- // Get a pointer to the object that is currently using this sample
- AudibleSoundClass *sound_obj = (AudibleSoundClass *)::AIL_3D_object_user_data (sample, INFO_OBJECT_PTR);
- if (sound_obj == NULL) {
- // Return this sample handle to the caller
- free_sample = sample;
- found = true;
- } else {
- //
- // Determine if this sound's priority is lesser then the sound we want to play.
- // This is done by comparing both the designer-specified priority and the current
- // runtime priority (which is calculated by distance to the listener).
- //
- float priority = sound_obj->Get_Priority ();
- float runtime_priority = sound_obj->Get_Runtime_Priority ();
- if ( (priority < lowest_priority) ||
- (priority == lowest_priority && runtime_priority <= lowest_runtime_priority))
- {
- lowest_priority = priority;
- lowest_pri_sound = sound_obj;
- lowest_pri_sample = sample;
- lowest_runtime_priority = runtime_priority;
- }
- }
- }
- }
- // Steal the sample handle from the lower priority
- // sound and return the handle to the caller.
- if ((found == false) && (lowest_pri_sound != NULL)) {
- lowest_pri_sound->Free_Miles_Handle ();
- free_sample = lowest_pri_sample;
- }
- // Return the free sample handle if we found one
- return free_sample;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Get_Listener_Handle
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- H3DPOBJECT
- WWAudioClass::Get_Listener_Handle (void)
- {
- MMSLockClass lock;
- return ::AIL_3D_open_listener (m_Driver3D);
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Build_3D_Driver_List
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::Build_3D_Driver_List (void)
- {
- MMSLockClass lock;
- HPROENUM next = HPROENUM_FIRST;
- HPROVIDER provider = NULL;
- char *name = NULL;
- while (::AIL_enumerate_3D_providers (&next, &provider, &name) > 0) {
- // Can we successfully open this provider?
- if (::AIL_open_3D_provider (provider) == M3D_NOERR) {
- DRIVER_INFO_STRUCT *info = new DRIVER_INFO_STRUCT;
- info->driver = provider;
- info->name = ::strdup (name);
- m_Driver3DList.Add (info);
- ::AIL_close_3D_provider (provider);
- } else {
- char *error_info = ::AIL_last_error ();
- WWDEBUG_SAY (("WWAudio: Unable to open %s.\r\n", name));
- WWDEBUG_SAY (("WWAudio: Reason %s.\r\n", error_info));
- }
- }
- //
- // Attempt to select one of the known drivers (in the following order).
- //
- if ( (Select_3D_Device (DRIVER3D_PSEUDO) == false) &&
- (Select_3D_Device (DRIVER3D_EAX) == false) &&
- (Select_3D_Device (DRIVER3D_A3D) == false) &&
- (Select_3D_Device (DRIVER3D_D3DSOUND) == false) &&
- (Select_3D_Device (DRIVER3D_DOLBY) == false))
- {
- //
- // Couldn't select a known driver, so just use the first possible.
- //
- if (m_Driver3DList.Count () > 0) {
- Select_3D_Device ((int)0);
- }
- }
- return;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Free_3D_Driver_List
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::Free_3D_Driver_List (void)
- {
- MMSLockClass lock;
- //
- // Remove all the handles
- //
- Remove_3D_Sound_Handles ();
- Release_3D_Handles ();
- //
- // Loop through all the driver entries and free them all
- //
- for (int index = 0; index < m_Driver3DList.Count (); index ++) {
- DRIVER_INFO_STRUCT *info = m_Driver3DList[index];
- if (info != NULL) {
- //
- // Free the information we have stored with this driver
- //
- if (info->name != NULL) {
- ::free (info->name);
- }
- delete info;
- }
- }
- if (m_Driver3D != NULL) {
- ::AIL_close_3D_provider (m_Driver3D);
- m_Driver3D = NULL;
- }
- //
- // Clear the list
- //
- m_Driver3DList.Delete_All ();
- return;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Select_3D_Device
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- bool
- WWAudioClass::Select_3D_Device (const char *device_name)
- {
- bool retval = false;
- //
- // Loop through all the drivers until we've found the one we want
- //
- for (int index = 0; index < m_Driver3DList.Count (); index ++) {
- DRIVER_INFO_STRUCT *info = m_Driver3DList[index];
- if (info != NULL) {
- //
- // Is this the device we were looking for?
- //
- if (::lstrcmpi (info->name, device_name) == 0) {
- retval = Select_3D_Device (device_name, info->driver);
- break;
- }
- }
- }
- return retval;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Select_3D_Device
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- bool
- WWAudioClass::Select_3D_Device (const char *device_name, HPROVIDER provider)
- {
- bool retval = false;
- if ((provider != NULL) && (provider != m_Driver3D)) {
- Close_3D_Device ();
- //
- // Select this device and re-allocate all handles
- //
- if (::AIL_open_3D_provider (provider) == M3D_NOERR) {
- m_Driver3D = provider;
- m_SoundScene->Initialize ();
- Allocate_3D_Handles ();
- AIL_set_3D_speaker_type (provider, AIL_3D_2_SPEAKER);
- //
- // Adjust the effects level to 1.0 if this is an EAX based driver
- //
- StringClass lower_name = device_name;
- ::strlwr (lower_name.Peek_Buffer ());
- if (::strstr (device_name, "eax") != 0) {
- m_EffectsLevel = 1.0F;
- } else {
- m_EffectsLevel = 0.0F;
- }
- m_Driver3DName = device_name;
- }
- retval = true;
- }
- // Return true if we successfully selected the device
- return retval;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Select_3D_Device
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- bool
- WWAudioClass::Select_3D_Device (int index)
- {
- bool retval = false;
- //
- // Index valid?
- //
- if ((index >= 0) && (index < m_Driver3DList.Count ())) {
- Select_3D_Device (m_Driver3DList[index]->name, m_Driver3DList[index]->driver);
- WWDEBUG_SAY (("WWAudio: Selecting 3D sound device: %s.\r\n", m_Driver3DList[index]->name));
- retval = true;
- }
- //
- // Return true if we successfully selected the device
- //
- return retval;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Select_3D_Device
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- bool
- WWAudioClass::Select_3D_Device (DRIVER_TYPE_3D type)
- {
- // Return true if we successfully selected the device
- return Select_3D_Device (Find_3D_Device (type));
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Find_3D_Device
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- int
- WWAudioClass::Find_3D_Device (DRIVER_TYPE_3D type)
- {
- // Determine which substring to search for in the
- // name of the driver.
- const char *sub_string = "RSX";
- switch (type) {
- case DRIVER3D_D3DSOUND:
- sub_string = "DirectSound";
- break;
- case DRIVER3D_EAX:
- sub_string = "EAX";
- break;
- case DRIVER3D_A3D:
- sub_string = "A3D";
- break;
- case DRIVER3D_PSEUDO:
- sub_string = "Fast";
- break;
- case DRIVER3D_DOLBY:
- sub_string = "Dolby";
- break;
- }
- // Loop through all the driver entries and free them all
- int driver_index = -1;
- for (int index = 0; (index < m_Driver3DList.Count ()) && (driver_index == -1); index ++) {
- DRIVER_INFO_STRUCT *info = m_Driver3DList[index];
- if ((info != NULL) && (info->name != NULL)) {
- // Is this the driver we were looking for?
- if (::strstr (info->name, sub_string) != NULL) {
- driver_index = index;
- }
- }
- }
- // Return -1 if not found, otherwise the 0 based index
- return driver_index;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Allocate_3D_Handles
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::Allocate_3D_Handles (void)
- {
- MMSLockClass lock;
- // Start fresh
- Release_3D_Handles ();
- if (m_Driver3D != NULL) {
- // Attempt to allocate our share of 3D sample handles
- for (int index = 0; index < m_Max3DSamples; index ++) {
- H3DSAMPLE sample = ::AIL_allocate_3D_sample_handle (m_Driver3D);
- if (sample != NULL) {
- ::AIL_set_3D_object_user_data (sample, INFO_OBJECT_PTR, NULL);
- m_3DSampleHandles.Add (sample);
- }
- }
- }
- return;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Release_3D_Handles
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::Release_3D_Handles (void)
- {
- MMSLockClass lock;
- //
- // Release our hold on all the samples we've allocated
- //
- for (int index = 0; index < m_3DSampleHandles.Count (); index ++) {
- H3DSAMPLE sample = m_3DSampleHandles[index];
- if (sample != NULL) {
- ::AIL_release_3D_sample_handle (sample);
- }
- }
- m_3DSampleHandles.Delete_All ();
- return;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Validate_3D_Sound_Buffer
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- bool
- WWAudioClass::Validate_3D_Sound_Buffer (SoundBufferClass *buffer)
- {
- bool retval = false;
- //
- // 3D sound buffer MUST be uncompressed mono WAV data
- //
- if ((buffer != NULL) &&
- (buffer->Get_Channels () == 1) &&
- (buffer->Get_Type () == WAVE_FORMAT_PCM) &&
- (buffer->Is_Streaming () == false))
- {
- retval = true;
- }
- // Return a true/false result code
- return retval;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // ReAssign_2D_Handles
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::ReAssign_2D_Handles (void)
- {
- // Loop through all the entries in the playlist
- for (int index = 0; index < m_Playlist[m_CurrPage].Count (); index ++) {
- AudibleSoundClass *sound_obj = m_Playlist[m_CurrPage][index];
- // If this is a 2D sound effect, then force it to 'get' a new
- // sound handle.
- if ((sound_obj->Get_Class_ID () == CLASSID_2D) ||
- (sound_obj->Get_Class_ID () == CLASSID_PSEUDO3D) ||
- (sound_obj->Get_Class_ID () == CLASSID_2DTRIGGER))
- {
- sound_obj->Free_Miles_Handle ();
- sound_obj->Allocate_Miles_Handle ();
- }
- }
- return;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // ReAssign_3D_Handles
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::ReAssign_3D_Handles (void)
- {
- // Loop through all the entries in the playlist
- for (int index = 0; index < m_Playlist[m_CurrPage].Count (); index ++) {
- AudibleSoundClass *sound_obj = m_Playlist[m_CurrPage][index];
- // If this is a 3D sound effect, then force it to 'get' a new
- // sound handle.
- if (sound_obj->Get_Class_ID () == CLASSID_3D) {
- sound_obj->Free_Miles_Handle ();
- sound_obj->Allocate_Miles_Handle ();
- }
- }
- return;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Remove_2D_Sound_Handles
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::Remove_2D_Sound_Handles (void)
- {
- //
- // Loop over all the 2D handles
- //
- for (int index = 0; index < m_2DSampleHandles.Count (); index ++) {
- HSAMPLE sample = m_2DSampleHandles[index];
- if (sample != NULL) {
- //
- // Get a pointer to the object that is currently using this sample
- //
- AudibleSoundClass *sound_obj = (AudibleSoundClass *)::AIL_sample_user_data (sample, INFO_OBJECT_PTR);
- if (sound_obj != NULL) {
- sound_obj->Free_Miles_Handle ();
- }
- }
- }
- return;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Remove_3D_Sound_Handles
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::Remove_3D_Sound_Handles (void)
- {
- //
- // Loop over all the 3D handles
- //
- for (int index = 0; index < m_3DSampleHandles.Count (); index ++) {
- H3DSAMPLE sample = m_3DSampleHandles[index];
- if (sample != NULL) {
- //
- // Get a pointer to the object that is currently using this sample
- //
- AudibleSoundClass *sound_obj = (AudibleSoundClass *)::AIL_3D_object_user_data (sample, INFO_OBJECT_PTR);
- if (sound_obj != NULL) {
- sound_obj->Free_Miles_Handle ();
- }
- }
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Set_Dialog_Volume
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::Set_Dialog_Volume (float volume)
- {
- m_DialogVolume = volume;
- m_DialogVolume = min (1.0F, m_DialogVolume);
- m_DialogVolume = max (0.0F, m_DialogVolume);
- // Update all the currently playing 'Dialog' to
- // reflect this new volume
- for (int index = 0; index < m_Playlist[m_CurrPage].Count (); index ++) {
- AudibleSoundClass *sound_obj = m_Playlist[m_CurrPage][index];
- if (sound_obj->Get_Type () == AudibleSoundClass::TYPE_DIALOG) {
- sound_obj->Update_Volume ();
- }
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Set_Cinematic_Volume
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::Set_Cinematic_Volume (float volume)
- {
- m_CinematicVolume = volume;
- m_CinematicVolume = min (1.0F, m_CinematicVolume);
- m_CinematicVolume = max (0.0F, m_CinematicVolume);
- //
- // Update all the currently playing cinematic-counds to
- // reflect this new volume
- //
- for (int index = 0; index < m_Playlist[m_CurrPage].Count (); index ++) {
- AudibleSoundClass *sound_obj = m_Playlist[m_CurrPage][index];
- if (sound_obj->Get_Type () == AudibleSoundClass::TYPE_CINEMATIC) {
- sound_obj->Update_Volume ();
- }
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Set_Sound_Effects_Volume
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::Set_Sound_Effects_Volume (float volume)
- {
- m_RealSoundVolume = volume;
- m_RealSoundVolume = min (1.0F, m_RealSoundVolume);
- m_RealSoundVolume = max (0.0F, m_RealSoundVolume);
- Internal_Set_Sound_Effects_Volume (m_RealSoundVolume);
- return ;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Set_Music_Volume
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::Set_Music_Volume (float volume)
- {
- m_RealMusicVolume = volume;
- m_RealMusicVolume = min (1.0F, m_RealMusicVolume);
- m_RealMusicVolume = max (0.0F, m_RealMusicVolume);
- Internal_Set_Music_Volume (m_RealMusicVolume);
- return;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Internal_Set_Sound_Effects_Volume
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::Internal_Set_Sound_Effects_Volume (float volume)
- {
- m_SoundVolume = volume;
- m_SoundVolume = min (1.0F, m_SoundVolume);
- m_SoundVolume = max (0.0F, m_SoundVolume);
- // Update all the currently playing 'Sound Effects' to
- // reflect this new volume
- for (int index = 0; index < m_Playlist[m_CurrPage].Count (); index ++) {
- AudibleSoundClass *sound_obj = m_Playlist[m_CurrPage][index];
- if (sound_obj->Get_Type () == AudibleSoundClass::TYPE_SOUND_EFFECT) {
- sound_obj->Update_Volume ();
- }
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Internal_Set_Music_Volume
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::Internal_Set_Music_Volume (float volume)
- {
- m_MusicVolume = volume;
- m_MusicVolume = min (1.0F, m_MusicVolume);
- m_MusicVolume = max (0.0F, m_MusicVolume);
- // Update all currently playing music to
- // reflect this new volume
- for (int index = 0; index < m_Playlist[m_CurrPage].Count (); index ++) {
- AudibleSoundClass *sound_obj = m_Playlist[m_CurrPage][index];
- if (sound_obj->Get_Type () == AudibleSoundClass::TYPE_MUSIC) {
- sound_obj->Update_Volume ();
- }
- }
- return;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Is_Disabled
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- bool
- WWAudioClass::Is_Disabled (void) const
- {
- static bool _firsttime = true;
- static bool _disabled = false;
- if (_firsttime) {
- _firsttime = false;
- #ifdef G_CODE_BASE
- //
- // Use command line arguement.
- //
- ArgvClass argv;
- if (argv.Find("-NOAUDIO")) {
- _disabled = true;
- }
- #endif
- //
- // Read the disabled key from the registry
- //
- RegistryClass registry ("SOFTWARE\\Westwood\\WWAudio");
- if (registry.Is_Valid ()) {
- if (registry.Get_Int ("Disabled", 0) == 1) {
- _disabled = true;
- WWDEBUG_SAY (("WWAudio: Audio system disabled in registry.\r\n"));
- }
- }
- }
- return (_disabled | m_ForceDisable);
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Initialize
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::Initialize (const char *registry_subkey_name)
- {
- WWMEMLOG(MEM_SOUND);
- if (Is_Disabled () == false) {
- //
- // Initialize the audio system from the registry settings
- //
- Load_From_Registry (registry_subkey_name);
- //
- // Grab the first (and only) filter for use with our 'tinny' effect.
- //
- HPROENUM next = HPROENUM_FIRST;
- char *name = NULL;
- if (::AIL_enumerate_filters (&next, &m_ReverbFilter, &name) == 0) {
- m_ReverbFilter = INVALID_MILES_HANDLE;
- }
- m_RealMusicVolume = m_MusicVolume;
- m_RealSoundVolume = m_SoundVolume;
- }
- //
- // Register the file callbacks so we can support streaming from MIX files...
- //
- ::AIL_set_file_callbacks (File_Open_Callback, File_Close_Callback,
- File_Seek_Callback, File_Read_Callback);
- return ;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Initialize
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::Initialize
- (
- bool stereo,
- int bits,
- int hertz
- )
- {
- // Open the default 2D device, then build a list of 3D
- // devices and open the default.
- if (Is_Disabled () == false) {
- Open_2D_Device (stereo, bits, hertz);
- Build_3D_Driver_List ();
- //
- // Grab the first (and only) filter for use with our 'tinny' effect.
- //
- HPROENUM next = HPROENUM_FIRST;
- char *name = NULL;
- if (::AIL_enumerate_filters (&next, &m_ReverbFilter, &name) == 0) {
- m_ReverbFilter = INVALID_MILES_HANDLE;
- }
- }
- //
- // Register the file callbacks so we can support streaming from MIX files...
- //
- ::AIL_set_file_callbacks (File_Open_Callback, File_Close_Callback,
- File_Seek_Callback, File_Read_Callback);
- return;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Shutdown
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::Shutdown (void)
- {
- //
- // If there is a timer running, then stop the timer...
- //
- if (m_UpdateTimer != -1) {
- // Kill the timer
- ::AIL_stop_timer (m_UpdateTimer);
- ::AIL_release_timer_handle (m_UpdateTimer);
- m_UpdateTimer = -1;
- // Wait for the timer callback function to end
- ::WaitForSingleObject (_TimerSyncEvent, 20000);
- ::CloseHandle (_TimerSyncEvent);
- _TimerSyncEvent = NULL;
- }
- //
- // Stop the background music
- //
- Set_Background_Music (NULL);
- //
- // Stop all sounds from playing
- //
- Flush_Playlist ();
- if (m_SoundScene != NULL) {
- m_SoundScene->Flush_Scene ();
- }
- //
- // Free all our cached sound buffers
- //
- Flush_Cache ();
- //
- // Close-out our hold on any driver resources
- //
- Remove_2D_Sound_Handles ();
- Remove_3D_Sound_Handles ();
- Release_2D_Handles ();
- Release_3D_Handles ();
- Free_3D_Driver_List ();
- SAFE_DELETE (m_SoundScene);
- Close_2D_Device ();
- //
- // Shutdown Miles Sound System
- //
- ::AIL_shutdown ();
- return;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Register_EOS_Callback
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::Register_EOS_Callback (LPFNEOSCALLBACK callback, DWORD user_param)
- {
- m_EOSCallbackList.Add_Callback (callback, user_param);
- return;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // UnRegister_EOS_Callback
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::UnRegister_EOS_Callback (LPFNEOSCALLBACK callback)
- {
- m_EOSCallbackList.Remove_Callback (callback);
- return;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Register_Text_Callback
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::Register_Text_Callback (LPFNTEXTCALLBACK callback, DWORD user_param)
- {
- m_TextCallbackList.Add_Callback (callback, user_param);
- return;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // UnRegister_Text_Callback
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::UnRegister_Text_Callback (LPFNTEXTCALLBACK callback)
- {
- m_TextCallbackList.Remove_Callback (callback);
- return;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Fire_Text_Callback
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::Fire_Text_Callback (AudibleSoundClass *sound_obj, const StringClass &text)
- {
- if (text.Get_Length () > 0) {
- //
- // Loop over all the text-callbacks that have been registered
- //
- for (int index = 0; index < m_TextCallbackList.Count (); index ++) {
- uint32 user_data = 0L;
- LPFNTEXTCALLBACK callback = m_TextCallbackList.Get_Callback (index, &user_data);
- if (callback != NULL) {
- //
- // Fire the notification
- //
- (*callback) (sound_obj, text, user_data);
- }
- }
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Allow_Sound_Effects
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::Allow_Sound_Effects (bool onoff)
- {
- //
- // Is the state changing?
- //
- if (m_AreSoundEffectsEnabled != onoff) {
- m_AreSoundEffectsEnabled = onoff;
- //
- // Update all the currently playing 'Sound Effects' to
- // reflect this new state.
- //
- if (m_AreSoundEffectsEnabled) {
- for (int page = 0; page < PAGE_COUNT; page ++) {
- Push_Active_Sound_Page ((WWAudioClass::SOUND_PAGE)page);
- for (int index = 0; index < m_Playlist[page].Count (); index ++) {
- AudibleSoundClass *sound_obj = m_Playlist[page][index];
- if (sound_obj->Get_Type () == AudibleSoundClass::TYPE_SOUND_EFFECT) {
- sound_obj->Allocate_Miles_Handle ();
- }
- }
- Pop_Active_Sound_Page ();
- }
- } else {
- for (int page = 0; page < PAGE_COUNT; page ++) {
- for (int index = 0; index < m_Playlist[page].Count (); index ++) {
- AudibleSoundClass *sound_obj = m_Playlist[page][index];
- if (sound_obj->Get_Type () == AudibleSoundClass::TYPE_SOUND_EFFECT) {
- sound_obj->Free_Miles_Handle ();
- }
- }
- }
- }
- }
- return;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Allow_Music
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::Allow_Music (bool onoff)
- {
- // Is the state changing?
- if (m_IsMusicEnabled != onoff) {
- m_IsMusicEnabled = onoff;
- //
- // Update all the currently playing 'music tracks' to
- // reflect this new state.
- //
- if (m_IsMusicEnabled) {
- for (int page = 0; page < PAGE_COUNT; page ++) {
- Push_Active_Sound_Page ((WWAudioClass::SOUND_PAGE)page);
- for (int index = 0; index < m_Playlist[page].Count (); index ++) {
- AudibleSoundClass *sound_obj = m_Playlist[page][index];
- if (sound_obj->Get_Type () == AudibleSoundClass::TYPE_MUSIC) {
- sound_obj->Stop (false);
- sound_obj->Play ();
- }
- }
- Pop_Active_Sound_Page ();
- }
- } else {
- for (int page = 0; page < PAGE_COUNT; page ++) {
- for (int index = 0; index < m_Playlist[page].Count (); index ++) {
- AudibleSoundClass *sound_obj = m_Playlist[page][index];
- if (sound_obj->Get_Type () == AudibleSoundClass::TYPE_MUSIC) {
- sound_obj->Free_Miles_Handle ();
- }
- }
- }
- }
- }
- return;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Allow_Dialog
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::Allow_Dialog (bool onoff)
- {
- // Is the state changing?
- if (m_IsDialogEnabled != onoff) {
- m_IsDialogEnabled = onoff;
- //
- // Update all the currently playing 'dialog' to
- // reflect this new state.
- //
- if (m_IsDialogEnabled) {
- for (int page = 0; page < PAGE_COUNT; page ++) {
- Push_Active_Sound_Page ((WWAudioClass::SOUND_PAGE)page);
- for (int index = 0; index < m_Playlist[page].Count (); index ++) {
- AudibleSoundClass *sound_obj = m_Playlist[page][index];
- if (sound_obj->Get_Type () == AudibleSoundClass::TYPE_DIALOG) {
- sound_obj->Stop (false);
- sound_obj->Play ();
- }
- }
- Pop_Active_Sound_Page ();
- }
- } else {
- for (int page = 0; page < PAGE_COUNT; page ++) {
- for (int index = 0; index < m_Playlist[page].Count (); index ++) {
- AudibleSoundClass *sound_obj = m_Playlist[page][index];
- if (sound_obj->Get_Type () == AudibleSoundClass::TYPE_DIALOG) {
- sound_obj->Free_Miles_Handle ();
- }
- }
- }
- }
- }
- return;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Allow_Cinematic_Sound
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::Allow_Cinematic_Sound (bool onoff)
- {
- // Is the state changing?
- if (m_IsCinematicSoundEnabled != onoff) {
- m_IsCinematicSoundEnabled = onoff;
- //
- // Update all the currently playing 'dialog' to
- // reflect this new state.
- //
- if (m_IsCinematicSoundEnabled) {
- for (int page = 0; page < PAGE_COUNT; page ++) {
- Push_Active_Sound_Page ((WWAudioClass::SOUND_PAGE)page);
- for (int index = 0; index < m_Playlist[page].Count (); index ++) {
- AudibleSoundClass *sound_obj = m_Playlist[page][index];
- if (sound_obj->Get_Type () == AudibleSoundClass::TYPE_CINEMATIC) {
- sound_obj->Stop (false);
- sound_obj->Play ();
- }
- }
- Pop_Active_Sound_Page ();
- }
- } else {
- for (int page = 0; page < PAGE_COUNT; page ++) {
- for (int index = 0; index < m_Playlist[page].Count (); index ++) {
- AudibleSoundClass *sound_obj = m_Playlist[page][index];
- if (sound_obj->Get_Type () == AudibleSoundClass::TYPE_CINEMATIC) {
- sound_obj->Free_Miles_Handle ();
- }
- }
- }
- }
- }
- return;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Simple_Play_2D_Sound_Effect
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- bool
- WWAudioClass::Simple_Play_2D_Sound_Effect
- (
- const char *filename,
- float priority,
- float volume
- )
- {
- bool retval = false;
- AudibleSoundClass *sound = Create_Sound_Effect (filename);
- if (sound != NULL) {
- sound->Set_Priority (priority);
- sound->Set_Loop_Count (1);
- sound->Set_Volume(volume);
- sound->Play ();
- sound->Release_Ref ();
- sound = NULL;
- retval = true;
- }
- return retval;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Simple_Play_2D_Sound_Effect
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- bool
- WWAudioClass::Simple_Play_2D_Sound_Effect
- (
- FileClass &file,
- float priority,
- float volume
- )
- {
- bool retval = false;
- AudibleSoundClass *sound = Create_Sound_Effect (file);
- if (sound != NULL) {
- sound->Set_Priority (priority);
- sound->Set_Loop_Count (1);
- sound->Set_Volume(volume);
- sound->Play ();
- sound->Release_Ref ();
- sound = NULL;
- retval = true;
- }
- return retval;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Get_File
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- FileClass *
- WWAudioClass::Get_File (LPCTSTR filename)
- {
- FileClass *file = NULL;
- if (m_FileFactory != NULL) {
- file = m_FileFactory->Get_File (filename);
- } else {
- file = _TheFileFactory->Get_File(filename);
- }
- // Return a pointer to the file
- return file;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Return_File
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::Return_File (FileClass *file)
- {
- if (m_FileFactory != NULL) {
- m_FileFactory->Return_File (file);
- } else {
- SAFE_DELETE (file);
- }
- return;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Create_Logical_Sound
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- LogicalSoundClass *
- WWAudioClass::Create_Logical_Sound (void)
- {
- return new LogicalSoundClass;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Create_Logical_Listener
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- LogicalListenerClass *
- WWAudioClass::Create_Logical_Listener (void)
- {
- return new LogicalListenerClass;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Add_Logical_Type
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::Add_Logical_Type (int id, LPCTSTR display_name)
- {
- m_LogicalTypes.Add (LOGICAL_TYPE_STRUCT (id, display_name));
- return ;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Reset_Logical_Types
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::Reset_Logical_Types (void)
- {
- m_LogicalTypes.Delete_All ();
- return ;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Get_Logical_Type
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- int
- WWAudioClass::Get_Logical_Type (int index, StringClass &name)
- {
- int type_id = 0;
- WWASSERT (index >= 0 && index < m_LogicalTypes.Count ());
- if (index >= 0 && index < m_LogicalTypes.Count ()) {
- type_id = m_LogicalTypes[index].id;
- name = m_LogicalTypes[index].display_name;
- }
- return type_id;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Find_Sound_Object
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- SoundSceneObjClass *
- WWAudioClass::Find_Sound_Object (uint32 sound_obj_id)
- {
- SoundSceneObjClass *sound_obj = NULL;
- //
- // Lookup the sound object and return it to the caller
- //
- int index = 0;
- if (SoundSceneObjClass::Find_Sound_Object (sound_obj_id, &index)) {
- sound_obj = SoundSceneObjClass::m_GlobalSoundList[index];
- }
- return sound_obj;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Load_From_Registry
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- bool
- WWAudioClass::Load_From_Registry (const char *subkey_name)
- {
- bool retval = true;
- StringClass device_name;
- bool is_stereo = true;
- int bits = 16;
- int hertz = 44100;
- //
- // Load the settings from the registry
- //
- if (Load_From_Registry (subkey_name, device_name, is_stereo, bits, hertz,
- m_AreSoundEffectsEnabled, m_IsMusicEnabled, m_IsDialogEnabled, m_IsCinematicSoundEnabled,
- m_SoundVolume, m_MusicVolume, m_DialogVolume, m_CinematicVolume, m_SpeakerType))
- {
- //
- // Close any open devices
- //
- Free_3D_Driver_List ();
- Close_2D_Device ();
- //
- // Open the 2D device as specified
- //
- Open_2D_Device (is_stereo, bits, hertz);
- //
- // Find and open the 3D device specified
- //
- Build_3D_Driver_List ();
- Select_3D_Device (device_name);
- retval = true;
- //
- // Select the speaker type
- //
- Set_Speaker_Type (m_SpeakerType);
- }
- m_RealMusicVolume = m_MusicVolume;
- m_RealSoundVolume = m_SoundVolume;
- return retval;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Load_From_Registry
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- bool
- WWAudioClass::Load_From_Registry
- (
- const char * subkey_name,
- StringClass & device_name,
- bool & is_stereo,
- int & bits,
- int & hertz,
- bool & sound_enabled,
- bool & music_enabled,
- bool & dialog_enabled,
- bool & cinematic_enabled,
- float & sound_volume,
- float & music_volume,
- float & dialog_volume,
- float & cinematic_volume,
- int & speaker_type
- )
- {
- bool retval = false;
- //
- // Attempt to open the registry key
- //
- RegistryClass registry (subkey_name);
- if (registry.Is_Valid ()) {
- int defaultmusicvolume, defaultsoundvolume, defaultdialogvolume, defaultcinematicvolume;
- //
- // Read the device name into a string object
- //
- char temp_buffer[256] = { 0 };
- registry.Get_String (VALUE_NAME_DEVICE_NAME, temp_buffer, sizeof (temp_buffer));
- device_name = temp_buffer;
- //
- // Read the 2D settings
- //
- is_stereo = (registry.Get_Int (VALUE_NAME_IS_STEREO, true) == 1);
- bits = registry.Get_Int (VALUE_NAME_BITS, 16);
- hertz = registry.Get_Int (VALUE_NAME_HERTZ, 44100);
- //
- // Read the sound/music enabled settings
- //
- music_enabled = (registry.Get_Int (VALUE_NAME_MUSIC_ENABLED, 1) == 1);
- sound_enabled = (registry.Get_Int (VALUE_NAME_SOUND_ENABLED, 1) == 1);
- dialog_enabled = (registry.Get_Int (VALUE_NAME_DIALOG_ENABLED, 1) == 1);
- cinematic_enabled = (registry.Get_Int (VALUE_NAME_CINEMATIC_ENABLED, 1) == 1);
- Load_Default_Volume (defaultmusicvolume, defaultsoundvolume, defaultdialogvolume, defaultcinematicvolume);
- //
- // Read the volume information
- //
- music_volume = registry.Get_Int (VALUE_NAME_MUSIC_VOL, defaultmusicvolume) / 100.0F;
- sound_volume = registry.Get_Int (VALUE_NAME_SOUND_VOL, defaultsoundvolume) / 100.0F;
- dialog_volume = registry.Get_Int (VALUE_NAME_DIALOG_VOL, defaultdialogvolume) / 100.0F;
- cinematic_volume = registry.Get_Int (VALUE_NAME_CINEMATIC_VOL, defaultcinematicvolume) / 100.0F;
- music_volume = WWMath::Clamp (music_volume, 0, 1.0F);
- sound_volume = WWMath::Clamp (sound_volume, 0, 1.0F);
- dialog_volume = WWMath::Clamp (dialog_volume, 0, 1.0F);
- cinematic_volume = WWMath::Clamp (cinematic_volume, 0, 1.0F);
- //
- // Misc
- //
- speaker_type = registry.Get_Int (VALUE_NAME_SPEAKER_TYPE, 0);
- retval = true;
- }
- return retval;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Save_To_Registry
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- bool
- WWAudioClass::Save_To_Registry (const char *subkey_name)
- {
- StringClass device_name;
- //
- // Get the name of the current 3D driver
- //
- for (int index = 0; index < m_Driver3DList.Count (); index ++) {
- DRIVER_INFO_STRUCT *info = m_Driver3DList[index];
- //
- // Is this the device we were looking for?
- //
- if (info != NULL && info->driver == m_Driver3D) {
- device_name = info->name;
- break;
- }
- }
- //
- // Save these settings to the registry
- //
- return Save_To_Registry (subkey_name, device_name, m_PlaybackStereo, m_PlaybackBits, m_PlaybackRate,
- m_AreSoundEffectsEnabled, m_IsMusicEnabled, m_IsDialogEnabled, m_IsCinematicSoundEnabled,
- m_SoundVolume, m_MusicVolume, m_DialogVolume, m_CinematicVolume, m_SpeakerType);
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Save_To_Registry
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- bool
- WWAudioClass::Save_To_Registry
- (
- const char * subkey_name,
- const StringClass & device_name,
- bool is_stereo,
- int bits,
- int hertz,
- bool sound_enabled,
- bool music_enabled,
- bool dialog_enabled,
- bool cinematic_enabled,
- float sound_volume,
- float music_volume,
- float dialog_volume,
- float cinematic_volume,
- int speaker_type
- )
- {
- bool retval = false;
- //
- // Attempt to open the registry key
- //
- RegistryClass registry (subkey_name);
- if (registry.Is_Valid ()) {
- //
- // Save the settings to the registry
- //
- registry.Set_String (VALUE_NAME_DEVICE_NAME, device_name);
- registry.Set_Int (VALUE_NAME_IS_STEREO, is_stereo);
- registry.Set_Int (VALUE_NAME_BITS, bits);
- registry.Set_Int (VALUE_NAME_HERTZ, hertz);
- registry.Set_Int (VALUE_NAME_MUSIC_ENABLED, music_enabled);
- registry.Set_Int (VALUE_NAME_SOUND_ENABLED, sound_enabled);
- registry.Set_Int (VALUE_NAME_DIALOG_ENABLED, dialog_enabled);
- registry.Set_Int (VALUE_NAME_CINEMATIC_ENABLED, cinematic_enabled);
- registry.Set_Int (VALUE_NAME_MUSIC_VOL, music_volume * 100);
- registry.Set_Int (VALUE_NAME_SOUND_VOL, sound_volume * 100);
- registry.Set_Int (VALUE_NAME_DIALOG_VOL, dialog_volume * 100);
- registry.Set_Int (VALUE_NAME_CINEMATIC_VOL, cinematic_volume * 100);
- registry.Set_Int (VALUE_NAME_SPEAKER_TYPE, speaker_type);
- retval = true;
- }
- return retval;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // File_Open_Callback
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- U32 AILCALLBACK
- WWAudioClass::File_Open_Callback (char const *filename, U32 *file_handle)
- {
- U32 retval = false;
- if (Get_Instance () != NULL) {
- //
- // Open the file
- //
- FileClass *file = Get_Instance ()->Get_File (filename);
- if (file != NULL && file->Open ()) {
- (*file_handle) = (U32)file;
- retval = true;
- }
- }
- return retval;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // File_Close_Callback
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- void AILCALLBACK
- WWAudioClass::File_Close_Callback (U32 file_handle)
- {
- if (Get_Instance () != NULL) {
- //
- // Close the file (if necessary)
- //
- FileClass *file = reinterpret_cast<FileClass *> (file_handle);
- if (file != NULL) {
- Get_Instance ()->Return_File (file);
- }
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // File_Seek_Callback
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- S32 AILCALLBACK
- WWAudioClass::File_Seek_Callback (U32 file_handle, S32 offset, U32 type)
- {
- S32 retval = 0;
- //
- // Convert the handle to a file handle type
- //
- FileClass *file = reinterpret_cast<FileClass *> (file_handle);
- if (file != NULL) {
- //
- // Convert the Miles seek type to one of our own
- //
- int seek_type = SEEK_CUR;
- switch (type)
- {
- case AIL_FILE_SEEK_BEGIN:
- seek_type = SEEK_SET;
- break;
- case AIL_FILE_SEEK_CURRENT:
- seek_type = SEEK_CUR;
- break;
- case AIL_FILE_SEEK_END:
- seek_type = SEEK_END;
- break;
- }
- //
- // Perform the seek
- //
- retval = file->Seek (offset, seek_type);
- }
- return retval;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // File_Read_Callback
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- U32 AILCALLBACK
- WWAudioClass::File_Read_Callback (U32 file_handle, void *buffer, U32 bytes)
- {
- U32 retval = 0;
- //
- // Convert the handle to a file handle type
- //
- FileClass *file = reinterpret_cast<FileClass *> (file_handle);
- if (file != NULL) {
- //
- // Read the bytes from the file
- //
- retval = file->Read (buffer, bytes);
- }
- return retval;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Fade_Background_Music
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::Fade_Background_Music (const char *filename, int fade_out_time, int fade_in_time)
- {
- //
- // Fade-out the background music (as necessary)
- //
- if (m_BackgroundMusic != NULL) {
- m_BackgroundMusic->Fade_Out (fade_out_time);
- REF_PTR_RELEASE (m_BackgroundMusic);
- }
- m_BackgroundMusicName = filename;
- if (filename != NULL) {
- //
- // Create the sound
- //
- m_BackgroundMusic = Create_Sound_Effect (filename);
- if (m_BackgroundMusic != NULL) {
- //
- // Configure the sound and start playing it
- //
- m_BackgroundMusic->Set_Priority (1.0F);
- m_BackgroundMusic->Set_Runtime_Priority (1.0F);
- m_BackgroundMusic->Set_Loop_Count (INFINITE_LOOPS);
- m_BackgroundMusic->Set_Type (AudibleSoundClass::TYPE_MUSIC);
- m_BackgroundMusic->Cull_Sound (false);
- m_BackgroundMusic->Fade_In (fade_in_time);
- }
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Set_Background_Music
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::Set_Background_Music (const char *filename)
- {
- //
- // Stop the background music
- //
- if (m_BackgroundMusic != NULL) {
- m_BackgroundMusic->Stop ();
- REF_PTR_RELEASE (m_BackgroundMusic);
- }
- m_BackgroundMusicName = filename;
- if (filename != NULL) {
- //
- // Create the sound
- //
- m_BackgroundMusic = Create_Sound_Effect (filename);
- if (m_BackgroundMusic != NULL) {
- //
- // Configure the sound and start playing it
- //
- m_BackgroundMusic->Set_Priority (1.0F);
- m_BackgroundMusic->Set_Runtime_Priority (1.0F);
- m_BackgroundMusic->Set_Loop_Count (INFINITE_LOOPS);
- m_BackgroundMusic->Set_Type (AudibleSoundClass::TYPE_MUSIC);
- m_BackgroundMusic->Cull_Sound (false);
- m_BackgroundMusic->Play ();
- }
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Set_Active_Sound_Page
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::Set_Active_Sound_Page (SOUND_PAGE page)
- {
- if (page == m_CurrPage) {
- return ;
- }
- //
- // Pause any sounds that are playing in the old page
- //
- for (int index = 0; index < m_Playlist[m_CurrPage].Count ();index ++) {
- m_Playlist[m_CurrPage][index]->Pause ();
- }
- //
- // Resume any sounds that are playing in the new page
- //
- for (index = 0; index < m_Playlist[page].Count ();index ++) {
- m_Playlist[page][index]->Resume ();
- }
- m_CurrPage = page;
- return ;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Fade_Non_Dialog_In
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::Fade_Non_Dialog_In (void)
- {
- if (m_FadeType == FADE_IN || m_FadeType == FADE_NONE) {
- return ;
- }
- m_FadeType = FADE_IN;
- m_FadeTimer = m_NonDialogFadeTime;
- return ;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Fade_Non_Dialog_Out
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::Fade_Non_Dialog_Out (void)
- {
- if (m_FadeType == FADE_OUT || m_FadeType == FADED_OUT) {
- return ;
- }
- m_FadeType = FADE_OUT;
- m_FadeTimer = m_NonDialogFadeTime;
- return ;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Update_Fade
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::Update_Fade (void)
- {
- if (m_FadeType == FADE_NONE || m_FadeType == FADED_OUT) {
- return ;
- }
- m_FadeTimer -= (WW3D::Get_Frame_Time () / 1000.0F);
- m_FadeTimer = max (m_FadeTimer, 0.0F);
- //
- // Determine what percent we should ramp up or down to...
- //
- float percent = (m_FadeTimer / m_NonDialogFadeTime);
- percent = WWMath::Clamp (percent, 0.0F, 1.0F);
- //
- // Invert the percent if we're fading out
- //
- if (m_FadeType == FADE_IN) {
- percent = 1.0F - percent;
- }
- //
- // Determine what the current percent is
- //
- const float FADE_MAX = 0.6F;
- percent = (1.0F - FADE_MAX) + (percent * FADE_MAX);
- //
- // Re-adjust the music and sound effect volumes
- //
- Internal_Set_Music_Volume (m_RealMusicVolume * percent);
- Internal_Set_Sound_Effects_Volume (m_RealSoundVolume * percent);
- //
- // If we've done the fade, then return to the "no fade" stage
- //
- if (m_FadeTimer == 0) {
- if (m_FadeType == FADE_OUT) {
- m_FadeType = FADED_OUT;
- } else {
- m_FadeType = FADE_NONE;
- }
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Peek_2D_Sample
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- AudibleSoundClass *
- WWAudioClass::Peek_2D_Sample (int index)
- {
- if (index < 0 || index > m_2DSampleHandles.Count ()) {
- return NULL;
- }
- MMSLockClass lock;
- AudibleSoundClass *retval = NULL;
- //
- // Try to get the sound object associated with this handle
- //
- HSAMPLE sample = m_2DSampleHandles[index];
- if (sample != NULL) {
- retval = (AudibleSoundClass *)::AIL_sample_user_data (sample, INFO_OBJECT_PTR);
- }
- return retval;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Peek_3D_Sample
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- AudibleSoundClass *
- WWAudioClass::Peek_3D_Sample (int index)
- {
- if (index < 0 || index > m_3DSampleHandles.Count ()) {
- return NULL;
- }
- MMSLockClass lock;
- AudibleSoundClass *retval = NULL;
- //
- // Try to get the sound object associated with this handle
- //
- H3DSAMPLE sample = m_3DSampleHandles[index];
- if (sample != NULL) {
- retval = (AudibleSoundClass *)::AIL_3D_object_user_data (sample, INFO_OBJECT_PTR);
- }
- return retval;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Acquire_Virtual_Channel
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- bool
- WWAudioClass::Acquire_Virtual_Channel (AudibleSoundClass *sound_obj, int channel_index)
- {
- //
- // Verify parameters
- //
- channel_index --;
- if (sound_obj == NULL || channel_index < 0 || channel_index >= MAX_VIRTUAL_CHANNELS) {
- return false;
- }
- //
- // Is there already a sound playing on this channel?
- //
- bool retval = true;
- if (m_VirtualChannels[channel_index] != NULL) {
- AudibleSoundClass *curr_sound = m_VirtualChannels[channel_index];
- //
- // If the new sound has overriding priority, then stop the sound
- // that's currently playing on this channel
- //
- if (sound_obj->Get_Priority () >= curr_sound->Get_Priority ()) {
- m_VirtualChannels[channel_index] = NULL;
- curr_sound->Stop ();
- REF_PTR_RELEASE (curr_sound);
- } else {
- retval = false;
- }
- }
- //
- // Store this sound in the virtual channel
- //
- if (retval) {
- m_VirtualChannels[channel_index] = sound_obj;
- sound_obj->Add_Ref ();
- }
- return retval;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Release_Virtual_Channel
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::Release_Virtual_Channel (AudibleSoundClass *sound_obj, int channel_index)
- {
- //
- // Verify parameters
- //
- channel_index --;
- if (sound_obj == NULL || channel_index < 0 || channel_index >= MAX_VIRTUAL_CHANNELS) {
- return ;
- }
- //
- // Check to ensure this sound has control of the virtual channel
- //
- if (m_VirtualChannels[channel_index] == sound_obj) {
- //
- // Free the channel
- //
- m_VirtualChannels[channel_index] = NULL;
- REF_PTR_RELEASE (sound_obj);
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Set_Speaker_Type
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::Set_Speaker_Type (int speaker_type)
- {
- m_SpeakerType = speaker_type;
- //
- // Pass the new speaker type onto miles
- //
- if (m_Driver3D != NULL) {
- ::AIL_set_3D_speaker_type (m_Driver3D, speaker_type);
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Get_Speaker_Type
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- int
- WWAudioClass::Get_Speaker_Type (void) const
- {
- return m_SpeakerType;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Push_Active_Sound_Page
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::Push_Active_Sound_Page (SOUND_PAGE page)
- {
- m_PageStack.Add (m_CurrPage);
- Set_Active_Sound_Page (page);
- return ;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Pop_Active_Sound_Page
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::Pop_Active_Sound_Page (void)
- {
- if (m_PageStack.Count () > 0) {
- SOUND_PAGE new_page = m_PageStack[m_PageStack.Count () - 1];
- m_PageStack.Delete (m_PageStack.Count () - 1);
- Set_Active_Sound_Page (new_page);
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Temp_Disable_Audio
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- void
- WWAudioClass::Temp_Disable_Audio (bool onoff)
- {
- if (onoff) {
- m_CachedIsMusicEnabled = m_IsMusicEnabled;
- m_CachedIsDialogEnabled = m_IsDialogEnabled;
- m_CachedIsCinematicSoundEnabled = m_IsCinematicSoundEnabled;
- m_CachedAreSoundEffectsEnabled = m_AreSoundEffectsEnabled;
- Allow_Sound_Effects (false);
- Allow_Music (false);
- Allow_Dialog (false);
- Allow_Cinematic_Sound (false);
- } else {
- Allow_Sound_Effects (m_CachedAreSoundEffectsEnabled);
- Allow_Music (m_CachedIsMusicEnabled);
- Allow_Dialog (m_CachedIsDialogEnabled);
- Allow_Cinematic_Sound (m_CachedIsCinematicSoundEnabled);
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Load_Default_Volume
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- void WWAudioClass::Load_Default_Volume (int &defaultmusicvolume, int &defaultsoundvolume, int &defaultdialogvolume, int &defaultcinematicvolume)
- {
- const int minsetting = 0;
- const int maxsetting = 100;
- // IML: If the audio INI has not yet been loaded then do it now.
- if (AudioIni == NULL) {
- AudioIni = new INIClass;
- if (!AudioIni->Load (WWAUDIO_INI_FILENAME)) {
- AudioIni->Load (WWAUDIO_INI_RELATIVE_PATHNAME);
- }
- }
- defaultmusicvolume = MIN (maxsetting, MAX (minsetting, AudioIni->Get_Int (INI_DEFAULT_VOLUME_SECTION, INI_MUSIC_VOLUME_ENTRY, 31)));
- defaultsoundvolume = MIN (maxsetting, MAX (minsetting, AudioIni->Get_Int (INI_DEFAULT_VOLUME_SECTION, INI_SOUND_VOLUME_ENTRY, 43)));
- defaultdialogvolume = MIN (maxsetting, MAX (minsetting, AudioIni->Get_Int (INI_DEFAULT_VOLUME_SECTION, INI_DIALOG_VOLUME_ENTRY, 50)));
- defaultcinematicvolume = MIN (maxsetting, MAX (minsetting, AudioIni->Get_Int (INI_DEFAULT_VOLUME_SECTION, INI_CINEMATIC_VOLUME_ENTRY, 100)));
- }
-
|