| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343 |
- /*
- ** Command & Conquer Generals(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) 2001-2003 Electronic Arts Inc. //
- // //
- ////////////////////////////////////////////////////////////////////////////////
- // FILE: MilesAudioManager.cpp
- /*---------------------------------------------------------------------------*/
- /* EA Pacific */
- /* Confidential Information */
- /* Copyright (C) 2001 - All Rights Reserved */
- /* DO NOT DISTRIBUTE */
- /*---------------------------------------------------------------------------*/
- /* Project: RTS3 */
- /* File name: MilesAudioManager.cpp */
- /* Created: John K. McDonald, Jr., 3/21/2002 */
- /* Desc: This is the implementation for the MilesAudioManager, which */
- /* interfaces with the Miles Sound System. */
- /* Revision History: */
- /* 7/18/2002 : Initial creation */
- /*---------------------------------------------------------------------------*/
- #include <dsound.h>
- #include "Lib/Basetype.h"
- #include "MilesAudioDevice/MilesAudioManager.h"
- #include "Common/AudioAffect.h"
- #include "Common/AudioHandleSpecialValues.h"
- #include "Common/AudioRequest.h"
- #include "Common/AudioSettings.h"
- #include "Common/AsciiString.h"
- #include "Common/AudioEventInfo.h"
- #include "Common/FileSystem.h"
- #include "Common/GameCommon.h"
- #include "Common/GameSounds.h"
- #include "Common/CRCDebug.h"
- #include "Common/GlobalData.h"
- #include "Common/ScopedMutex.h"
- #include "GameClient/DebugDisplay.h"
- #include "GameClient/Drawable.h"
- #include "GameClient/GameClient.h"
- #include "GameClient/VideoPlayer.h"
- #include "GameClient/View.h"
- #include "GameLogic/GameLogic.h"
- #include "GameLogic/TerrainLogic.h"
- #include "Common/File.h"
- #ifdef _INTERNAL
- //#pragma optimize("", off)
- //#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
- #endif
- enum { INFINITE_LOOP_COUNT = 1000000 };
- // Callback functions useful for Miles ////////////////////////////////////////////////////////////
- static void AILCALLBACK setSampleCompleted( HSAMPLE sampleCompleted );
- static void AILCALLBACK set3DSampleCompleted( H3DSAMPLE sample3DCompleted );
- static void AILCALLBACK setStreamCompleted( HSTREAM streamCompleted );
- static U32 AILCALLBACK streamingFileOpen(char const *fileName, U32 *file_handle);
- static void AILCALLBACK streamingFileClose(U32 fileHandle);
- static S32 AILCALLBACK streamingFileSeek(U32 fileHandle, S32 offset, U32 type);
- static U32 AILCALLBACK streamingFileRead(U32 fileHandle, void *buffer, U32 bytes);
- //-------------------------------------------------------------------------------------------------
- MilesAudioManager::MilesAudioManager() :
- m_providerCount(0),
- m_selectedProvider(PROVIDER_ERROR),
- m_selectedSpeakerType(0),
- m_lastProvider(PROVIDER_ERROR),
- m_digitalHandle(NULL),
- m_num2DSamples(0),
- m_num3DSamples(0),
- m_numStreams(0),
- m_delayFilter(NULL),
- m_binkHandle(NULL),
- m_pref3DProvider(AsciiString::TheEmptyString),
- m_prefSpeaker(AsciiString::TheEmptyString)
- {
- m_audioCache = NEW AudioFileCache;
- }
- //-------------------------------------------------------------------------------------------------
- MilesAudioManager::~MilesAudioManager()
- {
- DEBUG_ASSERTCRASH(m_binkHandle == NULL, ("Leaked a Bink handle. Chuybregts"));
- releaseHandleForBink();
- closeDevice();
- delete m_audioCache;
-
- DEBUG_ASSERTCRASH(this == TheAudio, ("Umm...\n"));
- TheAudio = NULL;
- }
- //-------------------------------------------------------------------------------------------------
- #if defined(_DEBUG) || defined(_INTERNAL)
- AudioHandle MilesAudioManager::addAudioEvent( const AudioEventRTS *eventToAdd )
- {
- if (TheGlobalData->m_preloadReport) {
- if (!eventToAdd->getEventName().isEmpty()) {
- m_allEventsLoaded.insert(eventToAdd->getEventName());
- }
- }
- return AudioManager::addAudioEvent(eventToAdd);
- }
- #endif
- #if defined(_DEBUG) || defined(_INTERNAL)
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::audioDebugDisplay(DebugDisplayInterface *dd, void *, FILE *fp )
- {
- std::list<PlayingAudio *>::iterator it;
- static char buffer[128] = { 0 };
- if (buffer[0] == 0) {
- AIL_MSS_version(buffer, 128);
- }
-
- Coord3D lookPos;
- TheTacticalView->getPosition( &lookPos );
- lookPos.z = TheTerrainLogic->getGroundHeight( lookPos.x, lookPos.y );
- const Coord3D *mikePos = TheAudio->getListenerPosition();
- Coord3D distanceVector = TheTacticalView->get3DCameraPosition();
- distanceVector.sub( mikePos );
- Int now = TheGameLogic->getFrame();
- static Int lastCheck = now;
- const Int frames = 60;
- static Int latency = 0;
- static Int worstLatency = 0;
- if( lastCheck + frames <= now )
- {
- latency = AIL_get_timer_highest_delay();
- if( latency > worstLatency )
- {
- worstLatency = latency;
- }
- lastCheck = now;
- }
- if( dd )
- {
- dd->printf("Miles Sound System version: %s ", buffer);
- dd->printf("Memory Usage : %d/%d\n", m_audioCache->getCurrentlyUsedSize(), m_audioCache->getMaxSize());
- dd->printf("Sound: %s ", (isOn(AudioAffect_Sound) ? "Yes" : "No"));
- dd->printf("3DSound: %s ", (isOn(AudioAffect_Sound3D) ? "Yes" : "No"));
- dd->printf("Speech: %s ", (isOn(AudioAffect_Speech) ? "Yes" : "No"));
- dd->printf("Music: %s\n", (isOn(AudioAffect_Music) ? "Yes" : "No"));
- dd->printf("Channels Available: ");
- dd->printf("%d Sounds ", m_sound->getAvailableSamples());
- dd->printf("%d(%d) 3D Sounds\n", m_sound->getAvailable3DSamples(), m_available3DSamples.size() );
- dd->printf("Volume: ");
- dd->printf("Sound: %d ", REAL_TO_INT(m_soundVolume * 100.0f));
- dd->printf("3DSound: %d ", REAL_TO_INT(m_sound3DVolume * 100.0f));
- dd->printf("Speech: %d ", REAL_TO_INT(m_speechVolume * 100.0f));
- dd->printf("Music: %d\n", REAL_TO_INT(m_musicVolume * 100.0f));
- dd->printf("Current 3D Provider: %s ",
-
- TheAudio->getProviderName(m_selectedProvider).str());
- dd->printf("Current Speaker Type: %s\n", TheAudio->translateUnsignedIntToSpeakerType(TheAudio->getSpeakerType()).str());
- dd->printf( "Looking at: (%d,%d,%d) -- Microphone at: (%d,%d,%d)\n",
- (Int)lookPos.x, (Int)lookPos.y, (Int)lookPos.z, (Int)mikePos->x, (Int)mikePos->y, (Int)mikePos->z );
- dd->printf( "Camera distance from microphone: %d -- Zoom Volume: %d%%\n",
- (Int)distanceVector.length(), (Int)(TheAudio->getZoomVolume()*100.0f) );
- dd->printf( "Worst latency: %d -- Current latency: %d\n", worstLatency, latency );
- dd->printf("-----------------------------------------------------------\n");
- dd->printf("Playing Audio\n");
- }
- if( fp )
- {
- fprintf( fp, "Miles Sound System version: %s ", buffer );
- fprintf( fp, "Memory Usage : %d/%d\n", m_audioCache->getCurrentlyUsedSize(), m_audioCache->getMaxSize() );
- fprintf( fp, "Sound: %s ", (isOn(AudioAffect_Sound) ? "Yes" : "No") );
- fprintf( fp, "3DSound: %s ", (isOn(AudioAffect_Sound3D) ? "Yes" : "No") );
- fprintf( fp, "Speech: %s ", (isOn(AudioAffect_Speech) ? "Yes" : "No") );
- fprintf( fp, "Music: %s\n", (isOn(AudioAffect_Music) ? "Yes" : "No") );
- fprintf( fp, "Channels Available: " );
- fprintf( fp, "%d Sounds ", m_sound->getAvailableSamples() );
- fprintf( fp, "%d 3D Sounds\n", m_sound->getAvailable3DSamples() );
- fprintf( fp, "Volume: ");
- fprintf( fp, "Sound: %d ", REAL_TO_INT(m_soundVolume * 100.0f) );
- fprintf( fp, "3DSound: %d ", REAL_TO_INT(m_sound3DVolume * 100.0f) );
- fprintf( fp, "Speech: %d ", REAL_TO_INT(m_speechVolume * 100.0f) );
- fprintf( fp, "Music: %d\n", REAL_TO_INT(m_musicVolume * 100.0f) );
- fprintf( fp, "Current 3D Provider: %s ", TheAudio->getProviderName(m_selectedProvider).str());
- fprintf( fp, "Current Speaker Type: %s\n", TheAudio->translateUnsignedIntToSpeakerType(TheAudio->getSpeakerType()).str());
- fprintf( fp, "Looking at: (%d,%d,%d) -- Microphone at: (%d,%d,%d)\n",
- (Int)lookPos.x, (Int)lookPos.y, (Int)lookPos.z, (Int)mikePos->x, (Int)mikePos->y, (Int)mikePos->z );
- fprintf( fp, "Camera distance from microphone: %d -- Zoom Volume: %d%%\n",
- (Int)distanceVector.length(), (Int)(TheAudio->getZoomVolume()*100.0f) );
- fprintf( fp, "-----------------------------------------------------------\n" );
- fprintf( fp, "Playing Audio\n" );
- }
- PlayingAudio *playing = NULL;
- Int channel;
- Int channelCount;
- Real volume = 0.0f;
- AsciiString filenameNoSlashes;
- const Int maxChannels = 64;
- PlayingAudio *playingArray[maxChannels] = { NULL };
- // 2-D Sounds
- if( dd )
- {
- dd->printf("-----------------------------------------------------Sounds\n");
- channelCount = TheAudio->getNum2DSamples();
- for (it = m_playingSounds.begin(); it != m_playingSounds.end(); ++it) {
- playing = *it;
- if (!playing) {
- continue;
- }
- playingArray[AIL_sample_user_data(playing->m_sample, 0)] = playing;
- }
- for (Int i = 1; i <= maxChannels && i <= channelCount; ++i) {
- playing = playingArray[i];
- if (!playing) {
- dd->printf("%d: Silence\n", i);
- continue;
- }
- filenameNoSlashes = playing->m_audioEventRTS->getFilename();
- filenameNoSlashes = filenameNoSlashes.reverseFind('\\') + 1;
-
- // Calculate Sample volume
- volume = 100.0f;
- volume *= getEffectiveVolume(playing->m_audioEventRTS);
- dd->printf("%2d: %-20s - (%s) Volume: %d (2D)\n", i, playing->m_audioEventRTS->getEventName().str(), filenameNoSlashes.str(), REAL_TO_INT(volume));
- playingArray[i] = NULL;
- }
- }
- if( fp )
- {
- fprintf( fp, "-----------------------------------------------------Sounds\n" );
- channelCount = TheAudio->getNum2DSamples();
- channel = 1;
- for( it = m_playingSounds.begin(); it != m_playingSounds.end(); ++it )
- {
- playing = *it;
- if( !playing )
- {
- continue;
- }
- filenameNoSlashes = playing->m_audioEventRTS->getFilename();
- filenameNoSlashes = filenameNoSlashes.reverseFind( '\\' ) + 1;
-
- // Calculate Sample volume
- volume = 100.0f;
- volume *= getEffectiveVolume( playing->m_audioEventRTS );
- fprintf( fp, "%2d: %-20s - (%s) Volume: %d (2D)\n", channel++, playing->m_audioEventRTS->getEventName().str(), filenameNoSlashes.str(), REAL_TO_INT( volume ) );
- }
- for( int i = channel; i <= channelCount; ++i )
- {
- fprintf( fp, "%d: Silence\n", i );
- }
- }
- const Coord3D *microphonePos = TheAudio->getListenerPosition();
- // Now 3D Sounds
- if( dd )
- {
- dd->printf("--------------------------------------------------3D Sounds\n");
- channelCount = TheAudio->getNum3DSamples();
- for (it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); ++it) {
- playing = *it;
- if (!playing) {
- continue;
- }
- playingArray[AIL_3D_user_data(playing->m_3DSample, 0)] = playing;
- }
- for (Int i = 1; i <= maxChannels && i <= channelCount; ++i)
- {
- playing = playingArray[i];
- if (!playing)
- {
- dd->printf("%d: Silence\n", i);
- continue;
- }
- filenameNoSlashes = playing->m_audioEventRTS->getFilename();
- filenameNoSlashes = filenameNoSlashes.reverseFind('\\') + 1;
-
- // Calculate Sample volume
- volume = 100.0f;
- volume *= getEffectiveVolume(playing->m_audioEventRTS);
- Real dist = -1.0f;
- const Coord3D *pos = playing->m_audioEventRTS->getPosition();
- char distStr[32];
- if( pos )
- {
- Coord3D vector = *microphonePos;
- vector.sub( pos );
- dist = vector.length();
- sprintf( distStr, "%d", REAL_TO_INT( dist ) );
- }
- else
- {
- sprintf( distStr, "???" );
- }
- char str[32];
- switch( playing->m_audioEventRTS->getOwnerType() )
- {
- case OT_Positional:
- sprintf( str, "(3D)" );
- break;
- case OT_Object:
- sprintf( str, "(3DObj)" );
- break;
- case OT_Drawable:
- sprintf( str, "(3DDraw)" );
- break;
- case OT_Dead:
- sprintf( str, "(3DDead)" );
- break;
- }
- dd->printf("%2d: %-20s - (%s) Volume: %d, Dist: %s, %s\n",
- i, playing->m_audioEventRTS->getEventName().str(), filenameNoSlashes.str(), REAL_TO_INT(volume), distStr, str );
- playingArray[i] = NULL;
- }
- }
- if( fp )
- {
- fprintf( fp, "--------------------------------------------------3D Sounds\n" );
- channelCount = TheAudio->getNum3DSamples();
- channel = 1;
- for( it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); ++it )
- {
- playing = *it;
- if( !playing )
- {
- continue;
- }
- filenameNoSlashes = playing->m_audioEventRTS->getFilename();
- filenameNoSlashes = filenameNoSlashes.reverseFind('\\') + 1;
-
- // Calculate Sample volume
- volume = 100.0f;
- volume *= getEffectiveVolume( playing->m_audioEventRTS );
- fprintf( fp, "%2d: %-24s - (%s) Volume: %d \n", channel++, playing->m_audioEventRTS->getEventName().str(), filenameNoSlashes.str(), REAL_TO_INT( volume ) );
- }
- for( int i = channel; i <= channelCount; ++i )
- {
- fprintf( fp, "%2d: Silence\n", i );
- }
- }
- // Now Streams
- if( dd )
- {
- dd->printf("----------------------------------------------------Streams\n");
- channelCount = TheAudio->getNumStreams();
- channel = 1;
- for (it = m_playingStreams.begin(); it != m_playingStreams.end(); ++it) {
- playing = *it;
- if (!playing) {
- continue;
- }
- filenameNoSlashes = playing->m_audioEventRTS->getFilename();
- filenameNoSlashes = filenameNoSlashes.reverseFind('\\') + 1;
-
- // Calculate Sample volume
- volume = 100.0f;
- volume *= getEffectiveVolume(playing->m_audioEventRTS);
- dd->printf("%2d: %-24s - (%s) Volume: %d (Stream)\n", channel++, playing->m_audioEventRTS->getEventName().str(), filenameNoSlashes.str(), REAL_TO_INT(volume));
- }
-
- for ( int i = channel; i <= channelCount; ++i) {
- dd->printf("%2d: Silence\n", i);
- }
- dd->printf("===========================================================\n");
- }
- if( fp )
- {
- fprintf( fp, "----------------------------------------------------Streams\n" );
- channelCount = TheAudio->getNumStreams();
- channel = 1;
- for( it = m_playingStreams.begin(); it != m_playingStreams.end(); ++it )
- {
- playing = *it;
- if( !playing )
- {
- continue;
- }
- filenameNoSlashes = playing->m_audioEventRTS->getFilename();
- filenameNoSlashes = filenameNoSlashes.reverseFind('\\') + 1;
-
- // Calculate Sample volume
- volume = 100.0f;
- volume *= getEffectiveVolume(playing->m_audioEventRTS);
- fprintf( fp, "%2d: %-24s - (%s) Volume: %d (Stream)\n", channel++, playing->m_audioEventRTS->getEventName().str(), filenameNoSlashes.str(), REAL_TO_INT( volume ) );
- }
-
- for( int i = channel; i <= channelCount; ++i )
- {
- fprintf( fp, "%2d: Silence\n", i );
- }
- fprintf( fp, "===========================================================\n" );
- }
- }
- #endif
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::init()
- {
- AudioManager::init();
- #ifdef INTENSE_DEBUG
- DEBUG_LOG(("Sound has temporarily been disabled in debug builds only. jkmcd\n"));
- // for now, _DEBUG builds only should have no sound. ask jkmcd or srj about this.
- return;
- #endif
- // We should now know how many samples we want to load
- openDevice();
- m_audioCache->setMaxSize(getAudioSettings()->m_maxCacheSize);
- // Now, set the file callbacks to load the streams from Biggie files
- AIL_set_file_callbacks(streamingFileOpen, streamingFileClose, streamingFileSeek, streamingFileRead);
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::postProcessLoad()
- {
- AudioManager::postProcessLoad();
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::reset()
- {
- #if defined(_DEBUG) || defined(_INTERNAL)
- dumpAllAssetsUsed();
- m_allEventsLoaded.clear();
- #endif
- AudioManager::reset();
- stopAllAudioImmediately();
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::update()
- {
- AudioManager::update();
- setDeviceListenerPosition();
- processRequestList();
- processPlayingList();
- processFadingList();
- processStoppedList();
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::stopAudio( AudioAffect which )
- {
- // All we really need to do is:
- // 1) Remove the EOS callback.
- // 2) Stop the sample, (so that when we later unload it, bad stuff doesn't happen)
- // 3) Set the status to stopped, so that when we next process the playing list, we will
- // correctly clean up the sample.
- std::list<PlayingAudio *>::iterator it;
- PlayingAudio *playing = NULL;
- if (BitTest(which, AudioAffect_Sound)) {
- for (it = m_playingSounds.begin(); it != m_playingSounds.end(); ++it) {
- playing = *it;
- if (playing) {
- AIL_register_EOS_callback(playing->m_sample, NULL);
- AIL_stop_sample(playing->m_sample);
- playing->m_status = PS_Stopped;
- }
- }
- }
- if (BitTest(which, AudioAffect_Sound3D)) {
- for (it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); ++it) {
- playing = *it;
- if (playing) {
- AIL_register_3D_EOS_callback(playing->m_3DSample, NULL);
- AIL_stop_3D_sample(playing->m_3DSample);
- playing->m_status = PS_Stopped;
- }
- }
- }
- if (BitTest(which, AudioAffect_Speech | AudioAffect_Music)) {
- for (it = m_playingStreams.begin(); it != m_playingStreams.end(); ++it) {
- playing = *it;
- if (playing) {
- if (playing->m_audioEventRTS->getAudioEventInfo()->m_soundType == AT_Music) {
- if (!BitTest(which, AudioAffect_Music)) {
- continue;
- }
- } else {
- if (!BitTest(which, AudioAffect_Speech)) {
- continue;
- }
- }
- AIL_register_stream_callback(playing->m_stream, NULL);
- AIL_pause_stream(playing->m_stream, 1);
- playing->m_status = PS_Stopped;
- }
- }
- }
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::pauseAudio( AudioAffect which )
- {
- std::list<PlayingAudio *>::iterator it;
- PlayingAudio *playing = NULL;
- if (BitTest(which, AudioAffect_Sound)) {
- for (it = m_playingSounds.begin(); it != m_playingSounds.end(); ++it) {
- playing = *it;
- if (playing) {
- AIL_stop_sample(playing->m_sample);
- }
- }
- }
- if (BitTest(which, AudioAffect_Sound3D)) {
- for (it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); ++it) {
- playing = *it;
- if (playing) {
- AIL_stop_3D_sample(playing->m_3DSample);
- }
- }
- }
- if (BitTest(which, AudioAffect_Speech | AudioAffect_Music)) {
- for (it = m_playingStreams.begin(); it != m_playingStreams.end(); ++it) {
- playing = *it;
- if (playing) {
- if (playing->m_audioEventRTS->getAudioEventInfo()->m_soundType == AT_Music) {
- if (!BitTest(which, AudioAffect_Music)) {
- continue;
- }
- } else {
- if (!BitTest(which, AudioAffect_Speech)) {
- continue;
- }
- }
- AIL_pause_stream(playing->m_stream, 1);
- }
- }
- }
-
- //Get rid of PLAY audio requests when pausing audio.
- std::list<AudioRequest*>::iterator ait;
- for (ait = m_audioRequests.begin(); ait != m_audioRequests.end(); /* empty */)
- {
- AudioRequest *req = (*ait);
- if( req && req->m_request == AR_Play )
- {
- req->deleteInstance();
- ait = m_audioRequests.erase(ait);
- }
- else
- {
- ait++;
- }
- }
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::resumeAudio( AudioAffect which )
- {
- std::list<PlayingAudio *>::iterator it;
- PlayingAudio *playing = NULL;
- if (BitTest(which, AudioAffect_Sound)) {
- for (it = m_playingSounds.begin(); it != m_playingSounds.end(); ++it) {
- playing = *it;
- if (playing) {
- AIL_resume_sample(playing->m_sample);
- }
- }
- }
- if (BitTest(which, AudioAffect_Sound3D)) {
- for (it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); ++it) {
- playing = *it;
- if (playing) {
- AIL_resume_3D_sample(playing->m_3DSample);
- }
- }
- }
- if (BitTest(which, AudioAffect_Speech | AudioAffect_Music)) {
- for (it = m_playingStreams.begin(); it != m_playingStreams.end(); ++it) {
- playing = *it;
- if (playing) {
- if (playing->m_audioEventRTS->getAudioEventInfo()->m_soundType == AT_Music) {
- if (!BitTest(which, AudioAffect_Music)) {
- continue;
- }
- } else {
- if (!BitTest(which, AudioAffect_Speech)) {
- continue;
- }
- }
- AIL_pause_stream(playing->m_stream, 0);
- }
- }
- }
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::pauseAmbient( Bool shouldPause )
- {
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::stopAllAmbientsBy( Object *obj )
- {
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::stopAllAmbientsBy( Drawable *draw )
- {
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::playAudioEvent( AudioEventRTS *event )
- {
- #ifdef INTENSIVE_AUDIO_DEBUG
- DEBUG_LOG(("MILES (%d) - Processing play request: %d (%s)", TheGameLogic->getFrame(), event->getPlayingHandle(), event->getEventName().str()));
- #endif
- const AudioEventInfo *info = event->getAudioEventInfo();
- if (!info) {
- return;
- }
- std::list<PlayingAudio *>::iterator it;
- PlayingAudio *playing = NULL;
- AudioHandle handleToKill = event->getHandleToKill();
- AsciiString fileToPlay = event->getFilename();
- PlayingAudio *audio = allocatePlayingAudio();
- switch(info->m_soundType)
- {
- case AT_Music:
- case AT_Streaming:
- {
- #ifdef INTENSIVE_AUDIO_DEBUG
- DEBUG_LOG(("- Stream\n"));
- #endif
-
- if ((info->m_soundType == AT_Streaming) && event->getUninterruptable()) {
- stopAllSpeech();
- }
- Real curVolume = 1.0;
- if (info->m_soundType == AT_Music) {
- curVolume = m_musicVolume;
- } else {
- curVolume = m_speechVolume;
- }
- curVolume *= event->getVolume();
- Bool foundSoundToReplace = false;
- if (handleToKill) {
- for (it = m_playingStreams.begin(); it != m_playingStreams.end(); ++it) {
- playing = (*it);
- if (!playing) {
- continue;
- }
- if (playing->m_audioEventRTS && playing->m_audioEventRTS->getPlayingHandle() == handleToKill)
- {
- //Release this streaming channel immediately because we are going to play another sound in it's place.
- releasePlayingAudio(playing);
- m_playingStreams.erase(it);
- foundSoundToReplace = true;
- break;
- }
- }
- }
- HSTREAM stream;
- if (!handleToKill || foundSoundToReplace) {
- stream = AIL_open_stream(m_digitalHandle, fileToPlay.str(), 0);
- } else {
- stream = NULL;
- }
- // Put this on here, so that the audio event RTS will be cleaned up regardless.
- audio->m_audioEventRTS = event;
- audio->m_stream = stream;
- audio->m_type = PAT_Stream;
- if (stream) {
- if ((info->m_soundType == AT_Streaming) && event->getUninterruptable()) {
- setDisallowSpeech(TRUE);
- }
- AIL_set_stream_volume_pan(stream, curVolume, 0.5f);
- playStream(event, stream);
- m_playingStreams.push_back(audio);
- audio = NULL;
- }
- break;
- }
- case AT_SoundEffect:
- {
- #ifdef INTENSIVE_AUDIO_DEBUG
- DEBUG_LOG(("- Sound"));
- #endif
-
- if (event->isPositionalAudio()) {
- // Sounds that are non-global are positional 3-D sounds. Deal with them accordingly
- #ifdef INTENSIVE_AUDIO_DEBUG
- DEBUG_LOG((" Positional"));
- #endif
- Bool foundSoundToReplace = false;
- if (handleToKill)
- {
- for (it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); ++it) {
- playing = (*it);
- if (!playing) {
- continue;
- }
- if( playing->m_audioEventRTS && playing->m_audioEventRTS->getPlayingHandle() == handleToKill )
- {
- //Release this 3D sound channel immediately because we are going to play another sound in it's place.
- releasePlayingAudio(playing);
- m_playing3DSounds.erase(it);
- foundSoundToReplace = true;
- break;
- }
- }
- }
-
- H3DSAMPLE sample3D;
- if( !handleToKill || foundSoundToReplace )
- {
- sample3D = getFirst3DSample( event );
- if( !sample3D )
- {
- //If we don't have an available sample, kill the lowest priority assuming we have one that is lower
- //than the sound we are trying to add. One possibility for strangeness is when an interrupt sound
- //that wants to kill a handle to replace it, it's possible that another request already killed it,
- //in which case we need to attempt to find another sound to kill.
- if( killLowestPrioritySoundImmediately( event ) )
- {
- sample3D = getFirst3DSample( event );
- }
- }
- }
- else
- {
- sample3D = NULL;
- }
- // Push it onto the list of playing things
- audio->m_audioEventRTS = event;
- audio->m_3DSample = sample3D;
- audio->m_file = NULL;
- audio->m_type = PAT_3DSample;
- m_playing3DSounds.push_back(audio);
- if (sample3D) {
- audio->m_file = playSample3D(event, sample3D);
- m_sound->notifyOf3DSampleStart();
- }
- if( !audio->m_file )
- {
- m_playing3DSounds.pop_back();
- #ifdef INTENSIVE_AUDIO_DEBUG
- DEBUG_LOG((" Killed (no handles available)\n"));
- #endif
- }
- else
- {
- audio = NULL;
- #ifdef INTENSIVE_AUDIO_DEBUG
- DEBUG_LOG((" Playing.\n"));
- #endif
- }
- }
- else
- {
- // UI sounds are always 2-D. All other sounds should be Positional
- // Unit acknowledgement, etc, falls into the UI category of sound.
- Bool foundSoundToReplace = false;
- if (handleToKill) {
- for (it = m_playingSounds.begin(); it != m_playingSounds.end(); ++it) {
- playing = (*it);
- if (!playing) {
- continue;
- }
- if (playing->m_audioEventRTS && playing->m_audioEventRTS->getPlayingHandle() == handleToKill)
- {
- //Release this 2D sound channel immediately because we are going to play another sound in it's place.
- releasePlayingAudio(playing);
- m_playingSounds.erase(it);
- foundSoundToReplace = true;
- break;
- }
- }
- }
- HSAMPLE sample;
- if( !handleToKill || foundSoundToReplace )
- {
- sample = getFirst2DSample(event);
- if( !sample )
- {
- //If we don't have an available sample, kill the lowest priority assuming we have one that is lower
- //than the sound we are trying to add. One possibility for strangeness is when an interrupt sound
- //that wants to kill a handle to replace it, it's possible that another request already killed it,
- //in which case we need to attempt to find another sound to kill.
- if( killLowestPrioritySoundImmediately( event ) )
- {
- sample = getFirst2DSample( event );
- }
- }
- }
- else
- {
- sample = NULL;
- }
- // Push it onto the list of playing things
- audio->m_audioEventRTS = event;
- audio->m_sample = sample;
- audio->m_file = NULL;
- audio->m_type = PAT_Sample;
- m_playingSounds.push_back(audio);
- if (sample) {
- audio->m_file = playSample(event, sample);
- m_sound->notifyOf2DSampleStart();
- }
- if (!audio->m_file) {
- #ifdef INTENSIVE_AUDIO_DEBUG
- DEBUG_LOG((" Killed (no handles available)\n"));
- #endif
- m_playingSounds.pop_back();
- } else {
- audio = NULL;
- }
- #ifdef INTENSIVE_AUDIO_DEBUG
- DEBUG_LOG((" Playing.\n"));
- #endif
- }
- break;
- }
- }
- // If we were able to successfully play audio, then we set it to NULL above. (And it will be freed
- // later. However, if audio is non-NULL at this point, then it must be freed.
- if (audio) {
- releasePlayingAudio(audio);
- }
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::stopAudioEvent( AudioHandle handle )
- {
- #ifdef INTENSIVE_AUDIO_DEBUG
- DEBUG_LOG(("MILES (%d) - Processing stop request: %d\n", TheGameLogic->getFrame(), handle));
- #endif
- std::list<PlayingAudio *>::iterator it;
- if ( handle == AHSV_StopTheMusic || handle == AHSV_StopTheMusicFade ) {
- // for music, just find the currently playing music stream and kill it.
- for ( it = m_playingStreams.begin(); it != m_playingStreams.end(); ++it ) {
- PlayingAudio *audio = (*it);
- if (!audio) {
- continue;
- }
- if( audio->m_audioEventRTS->getAudioEventInfo()->m_soundType == AT_Music )
- {
- if( handle == AHSV_StopTheMusicFade )
- {
- m_fadingAudio.push_back(audio);
- }
- else
- {
- //m_stoppedAudio.push_back(audio);
- releasePlayingAudio( audio );
- }
- m_playingStreams.erase(it);
- break;
- }
- }
- }
- for ( it = m_playingStreams.begin(); it != m_playingStreams.end(); ++it ) {
- PlayingAudio *audio = (*it);
- if (!audio) {
- continue;
- }
- if (audio->m_audioEventRTS->getPlayingHandle() == handle) {
- // found it
- audio->m_requestStop = true;
- notifyOfAudioCompletion((UnsignedInt)(audio->m_stream), PAT_Stream);
- break;
- }
- }
- for ( it = m_playingSounds.begin(); it != m_playingSounds.end(); ++it ) {
- PlayingAudio *audio = (*it);
- if (!audio) {
- continue;
- }
- if (audio->m_audioEventRTS->getPlayingHandle() == handle) {
- audio->m_requestStop = true;
- break;
- }
- }
- for ( it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); ++it ) {
- PlayingAudio *audio = (*it);
- if (!audio) {
- continue;
- }
- if (audio->m_audioEventRTS->getPlayingHandle() == handle) {
- #ifdef INTENSIVE_AUDIO_DEBUG
- DEBUG_LOG((" (%s)\n", audio->m_audioEventRTS->getEventName()));
- #endif
- audio->m_requestStop = true;
- break;
- }
- }
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::killAudioEventImmediately( AudioHandle audioEvent )
- {
- //First look for it in the request list.
- std::list<AudioRequest*>::iterator ait;
- for( ait = m_audioRequests.begin(); ait != m_audioRequests.end(); ait++ )
- {
- AudioRequest *req = (*ait);
- if( req && req->m_request == AR_Play && req->m_handleToInteractOn == audioEvent )
- {
- req->deleteInstance();
- ait = m_audioRequests.erase(ait);
- return;
- }
- }
- //Look for matching 3D sound to kill
- std::list<PlayingAudio *>::iterator it;
- for( it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); it++ )
- {
- PlayingAudio *audio = (*it);
- if( !audio )
- {
- continue;
- }
- if( audio->m_audioEventRTS->getPlayingHandle() == audioEvent )
- {
- releasePlayingAudio( audio );
- m_playing3DSounds.erase( it );
- return;
- }
- }
- //Look for matching 2D sound to kill
- for( it = m_playingSounds.begin(); it != m_playingSounds.end(); it++ )
- {
- PlayingAudio *audio = (*it);
- if( !audio )
- {
- continue;
- }
- if( audio->m_audioEventRTS->getPlayingHandle() == audioEvent )
- {
- releasePlayingAudio( audio );
- m_playingSounds.erase( it );
- return;
- }
- }
- //Look for matching steaming sound to kill
- for( it = m_playingStreams.begin(); it != m_playingStreams.end(); it++ )
- {
- PlayingAudio *audio = (*it);
- if( !audio )
- {
- continue;
- }
- if( audio->m_audioEventRTS->getPlayingHandle() == audioEvent )
- {
- releasePlayingAudio( audio );
- m_playingStreams.erase( it );
- return;
- }
- }
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::pauseAudioEvent( AudioHandle handle )
- {
- // pause audio
- }
- //-------------------------------------------------------------------------------------------------
- void *MilesAudioManager::loadFileForRead( AudioEventRTS *eventToLoadFrom )
- {
- return m_audioCache->openFile(eventToLoadFrom);
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::closeFile( void *fileRead )
- {
- m_audioCache->closeFile(fileRead);
- }
- //-------------------------------------------------------------------------------------------------
- PlayingAudio *MilesAudioManager::allocatePlayingAudio( void )
- {
- PlayingAudio *aud = NEW PlayingAudio; // poolify
- aud->m_status = PS_Playing;
- return aud;
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::releaseMilesHandles( PlayingAudio *release )
- {
- switch (release->m_type)
- {
- case PAT_Sample:
- {
- if (release->m_sample) {
- AIL_register_EOS_callback(release->m_sample, NULL);
- AIL_stop_sample(release->m_sample);
- m_availableSamples.push_back(release->m_sample);
- }
- break;
- }
- case PAT_3DSample:
- {
- if (release->m_3DSample) {
- AIL_register_3D_EOS_callback(release->m_3DSample, NULL);
- AIL_stop_3D_sample(release->m_3DSample);
- m_available3DSamples.push_back(release->m_3DSample);
- }
- break;
- }
- case PAT_Stream:
- {
- if (release->m_stream) {
- AIL_register_stream_callback(release->m_stream, NULL);
- AIL_close_stream(release->m_stream);
- }
- break;
- }
- }
- release->m_type = PAT_INVALID;
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::releasePlayingAudio( PlayingAudio *release )
- {
- if (release->m_audioEventRTS->getAudioEventInfo()->m_soundType == AT_SoundEffect) {
- if (release->m_type == PAT_Sample) {
- if (release->m_sample) {
- m_sound->notifyOf2DSampleCompletion();
- }
- } else {
- if (release->m_3DSample) {
- m_sound->notifyOf3DSampleCompletion();
- }
- }
- }
- releaseMilesHandles(release); // forces stop of this audio
- closeFile( release->m_file );
- if (release->m_cleanupAudioEventRTS) {
- releaseAudioEventRTS(release->m_audioEventRTS);
- }
- delete release;
- release = NULL;
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::stopAllAudioImmediately( void )
- {
- std::list<PlayingAudio *>::iterator it;
- PlayingAudio *playing;
- for (it = m_playingSounds.begin(); it != m_playingSounds.end(); ) {
- playing = *it;
- if (!playing) {
- continue;
- }
- releasePlayingAudio(playing);
- it = m_playingSounds.erase(it);
- }
- for (it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); ) {
- playing = *it;
- if (!playing) {
- continue;
- }
- releasePlayingAudio(playing);
- it = m_playing3DSounds.erase(it);
- }
- for (it = m_playingStreams.begin(); it != m_playingStreams.end(); ) {
- playing = (*it);
- if (!playing) {
- continue;
- }
- releasePlayingAudio(playing);
- it = m_playingStreams.erase(it);
- }
- std::list<HAUDIO>::iterator hit;
- for (hit = m_audioForcePlayed.begin(); hit != m_audioForcePlayed.end(); ++hit) {
- if (*hit) {
- AIL_quick_unload(*hit);
- }
- }
- m_audioForcePlayed.clear();
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::freeAllMilesHandles( void )
- {
- // First, we need to ensure that we don't have any sample handles open. To that end, we must stop
- // all of our currently playing audio.
- stopAllAudioImmediately();
- // Walks through the available 2-D and 3-D handles and releases them
- std::list<HSAMPLE>::iterator it;
- for ( it = m_availableSamples.begin(); it != m_availableSamples.end(); /* empty */ ) {
- HSAMPLE sample = *it;
- AIL_release_sample_handle(sample);
- it = m_availableSamples.erase(it);
- }
- m_num2DSamples = 0;
-
- std::list<H3DSAMPLE>::iterator it3D;
- for ( it3D = m_available3DSamples.begin(); it3D != m_available3DSamples.end(); /* empty */ ) {
- H3DSAMPLE sample3D = *it3D;
- AIL_release_3D_sample_handle(sample3D);
- it3D = m_available3DSamples.erase(it3D);
- }
- m_num3DSamples = 0;
- m_numStreams = 0;
- }
- //-------------------------------------------------------------------------------------------------
- HSAMPLE MilesAudioManager::getFirst2DSample( AudioEventRTS *event )
- {
- if (m_availableSamples.begin() != m_availableSamples.end()) {
- HSAMPLE retSample = *m_availableSamples.begin();
- m_availableSamples.erase(m_availableSamples.begin());
- return (retSample);
- }
- // Find the first sample of lower priority than my augmented priority that is interruptable and take its handle
- return NULL;
- }
- //-------------------------------------------------------------------------------------------------
- H3DSAMPLE MilesAudioManager::getFirst3DSample( AudioEventRTS *event )
- {
- if (m_available3DSamples.begin() != m_available3DSamples.end()) {
- H3DSAMPLE retSample = *m_available3DSamples.begin();
- m_available3DSamples.erase(m_available3DSamples.begin());
- return (retSample);
- }
- // Find the first sample of lower priority than my augmented priority that is interruptable and take its handle
- return NULL;
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::adjustPlayingVolume( PlayingAudio *audio )
- {
- Real desiredVolume = audio->m_audioEventRTS->getVolume() * audio->m_audioEventRTS->getVolumeShift();
- Real pan;
- if (audio->m_type == PAT_Sample) {
- AIL_sample_volume_pan(audio->m_sample, NULL, &pan);
- AIL_set_sample_volume_pan(audio->m_sample, m_soundVolume * desiredVolume, pan);
- } else if (audio->m_type == PAT_3DSample) {
- AIL_set_3D_sample_volume(audio->m_3DSample, m_sound3DVolume * desiredVolume);
- } else if (audio->m_type == PAT_Stream) {
- AIL_stream_volume_pan(audio->m_stream, NULL, &pan);
- if (audio->m_audioEventRTS->getAudioEventInfo()->m_soundType == AT_Music ) {
- AIL_set_stream_volume_pan(audio->m_stream, m_musicVolume * desiredVolume, pan);
-
- } else {
- AIL_set_stream_volume_pan(audio->m_stream, m_speechVolume * desiredVolume, pan);
-
- }
- }
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::stopAllSpeech( void )
- {
- std::list<PlayingAudio *>::iterator it;
- PlayingAudio *playing;
- for (it = m_playingStreams.begin(); it != m_playingStreams.end(); ) {
- playing = (*it);
- if (!playing) {
- continue;
- }
- if (playing->m_audioEventRTS->getAudioEventInfo()->m_soundType == AT_Streaming) {
- releasePlayingAudio(playing);
- it = m_playingStreams.erase(it);
- } else {
- ++it;
- }
- }
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::initFilters( HSAMPLE sample, const AudioEventRTS *event )
- {
- // set the sample volume
- Real volume = event->getVolume() * event->getVolumeShift() * m_soundVolume;
- AIL_set_sample_volume_pan(sample, volume, 0.5f);
- // pitch shift
- Real pitchShift = event->getPitchShift();
- if (pitchShift == 0.0f) {
- DEBUG_CRASH(("Invalid Pitch shift in sound: '%s'", event->getEventName().str()) );
- } else {
- AIL_set_sample_playback_rate(sample, REAL_TO_INT(AIL_sample_playback_rate(sample) * pitchShift));
- }
- // set up delay filter, if applicable
- if (event->getDelay() > 0.0f) {
- Real value;
- value = event->getDelay();
- AIL_set_sample_processor(sample, DP_FILTER, m_delayFilter);
- AIL_set_filter_sample_preference(sample, "Mono Delay Time", &value);
- value = 0.0;
- AIL_set_filter_sample_preference(sample, "Mono Delay", &value);
- AIL_set_filter_sample_preference(sample, "Mono Delay Mix", &value);
- }
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::initFilters3D( H3DSAMPLE sample, const AudioEventRTS *event, const Coord3D *pos )
- {
- // set the sample volume
- Real volume = event->getVolume() * event->getVolumeShift() * m_sound3DVolume;
- AIL_set_3D_sample_volume(sample, volume);
- // pitch shift
- Real pitchShift = event->getPitchShift();
- if (pitchShift == 0.0f) {
- DEBUG_CRASH(("Invalid Pitch shift in sound: '%s'", event->getEventName().str()) );
- } else {
- AIL_set_3D_sample_playback_rate(sample, REAL_TO_INT(AIL_3D_sample_playback_rate(sample) * pitchShift));
- }
-
- // Low pass filter
- if (event->getAudioEventInfo()->m_lowPassFreq > 0 && !isOnScreen(pos) ) {
- AIL_set_3D_sample_occlusion(sample, 1.0f - event->getAudioEventInfo()->m_lowPassFreq);
- }
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::nextMusicTrack( void )
- {
- AsciiString trackName;
- std::list<PlayingAudio *>::iterator it;
- PlayingAudio *playing;
- for (it = m_playingStreams.begin(); it != m_playingStreams.end(); ++it) {
- playing = *it;
- if (playing && playing->m_audioEventRTS->getAudioEventInfo()->m_soundType == AT_Music) {
- trackName = playing->m_audioEventRTS->getEventName();
- }
- }
- // Stop currently playing music
- TheAudio->removeAudioEvent(AHSV_StopTheMusic);
- trackName = nextTrackName(trackName);
- AudioEventRTS newTrack(trackName);
- TheAudio->addAudioEvent(&newTrack);
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::prevMusicTrack( void )
- {
- AsciiString trackName;
- std::list<PlayingAudio *>::iterator it;
- PlayingAudio *playing;
- for (it = m_playingStreams.begin(); it != m_playingStreams.end(); ++it) {
- playing = *it;
- if (playing && playing->m_audioEventRTS->getAudioEventInfo()->m_soundType == AT_Music) {
- trackName = playing->m_audioEventRTS->getEventName();
- }
- }
- // Stop currently playing music
- TheAudio->removeAudioEvent(AHSV_StopTheMusic);
- trackName = prevTrackName(trackName);
- AudioEventRTS newTrack(trackName);
- TheAudio->addAudioEvent(&newTrack);
- }
- //-------------------------------------------------------------------------------------------------
- Bool MilesAudioManager::isMusicPlaying( void ) const
- {
- std::list<PlayingAudio *>::const_iterator it;
- PlayingAudio *playing;
- for (it = m_playingStreams.begin(); it != m_playingStreams.end(); ++it) {
- playing = *it;
- if (playing && playing->m_audioEventRTS->getAudioEventInfo()->m_soundType == AT_Music) {
- return TRUE;
- }
- }
- return FALSE;
- }
- //-------------------------------------------------------------------------------------------------
- Bool MilesAudioManager::hasMusicTrackCompleted( const AsciiString& trackName, Int numberOfTimes ) const
- {
- std::list<PlayingAudio *>::const_iterator it;
- PlayingAudio *playing;
- for (it = m_playingStreams.begin(); it != m_playingStreams.end(); ++it) {
- playing = *it;
- if (playing && playing->m_audioEventRTS->getAudioEventInfo()->m_soundType == AT_Music) {
- if (playing->m_audioEventRTS->getEventName() == trackName) {
- if (INFINITE_LOOP_COUNT - AIL_stream_loop_count(playing->m_stream) >= numberOfTimes) {
- return TRUE;
- }
- }
- }
- }
- return FALSE;
- }
- //-------------------------------------------------------------------------------------------------
- AsciiString MilesAudioManager::getMusicTrackName( void ) const
- {
- // First check the requests. If there's one there, then report that as the currently playing track.
- std::list<AudioRequest *>::const_iterator ait;
- for (ait = m_audioRequests.begin(); ait != m_audioRequests.end(); ++ait) {
- if ((*ait)->m_request != AR_Play) {
- continue;
- }
- if (!(*ait)->m_usePendingEvent) {
- continue;
- }
- if ((*ait)->m_pendingEvent->getAudioEventInfo()->m_soundType == AT_Music) {
- return (*ait)->m_pendingEvent->getEventName();
- }
- }
- std::list<PlayingAudio *>::const_iterator it;
- PlayingAudio *playing;
- for (it = m_playingStreams.begin(); it != m_playingStreams.end(); ++it) {
- playing = *it;
- if (playing && playing->m_audioEventRTS->getAudioEventInfo()->m_soundType == AT_Music) {
- return playing->m_audioEventRTS->getEventName();
- }
- }
- return AsciiString::TheEmptyString;
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::openDevice( void )
- {
- if (!TheGlobalData->m_audioOn) {
- return;
- }
-
- AIL_set_redist_directory("MSS\\");
- AIL_startup();
- Int retval = 0;
- // AIL_quick_startup should be replaced later with a call to actually pick which device to use, etc
- const AudioSettings *audioSettings = getAudioSettings();
- m_selectedSpeakerType = TheAudio->translateSpeakerTypeToUnsignedInt(m_prefSpeaker);
- retval = AIL_quick_startup(audioSettings->m_useDigital, audioSettings->m_useMidi, audioSettings->m_outputRate, audioSettings->m_outputBits, audioSettings->m_outputChannels);
-
- // Quick handles tells us where to store the various devices. For now, we're only interested in the digital handle.
- AIL_quick_handles(&m_digitalHandle, NULL, NULL);
-
- if (retval) {
- buildProviderList();
- } else {
- // if we couldn't initialize any devices, turn sound off (fail silently)
- setOn( false, AudioAffect_All );
- }
- selectProvider(TheAudio->getProviderIndex(m_pref3DProvider));
- // Now that we're all done, update the cached variables so that everything is in sync.
- TheAudio->refreshCachedVariables();
- if (!isValidProvider()) {
- return;
- }
- initDelayFilter();
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::closeDevice( void )
- {
- freeAllMilesHandles();
- unselectProvider();
- AIL_shutdown();
- }
- //-------------------------------------------------------------------------------------------------
- Bool MilesAudioManager::isCurrentlyPlaying( AudioHandle handle )
- {
- std::list<PlayingAudio *>::iterator it;
- PlayingAudio *playing;
- for (it = m_playingSounds.begin(); it != m_playingSounds.end(); ++it) {
- playing = *it;
- if (playing && playing->m_audioEventRTS->getPlayingHandle() == handle) {
- return true;
- }
- }
- for (it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); ++it) {
- playing = *it;
- if (playing && playing->m_audioEventRTS->getPlayingHandle() == handle) {
- return true;
- }
- }
- for (it = m_playingStreams.begin(); it != m_playingStreams.end(); ++it) {
- playing = *it;
- if (playing && playing->m_audioEventRTS->getPlayingHandle() == handle) {
- return true;
- }
- }
- // if something is requested, it is also considered playing
- std::list<AudioRequest *>::iterator ait;
- AudioRequest *req = NULL;
- for (ait = m_audioRequests.begin(); ait != m_audioRequests.end(); ++ait) {
- req = *ait;
- if (req && req->m_usePendingEvent && req->m_pendingEvent->getPlayingHandle() == handle) {
- return true;
- }
- }
- return false;
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::notifyOfAudioCompletion( UnsignedInt audioCompleted, UnsignedInt flags )
- {
- PlayingAudio *playing = findPlayingAudioFrom(audioCompleted, flags);
- if (!playing) {
- DEBUG_CRASH(("Audio has completed playing, but we can't seem to find it. - jkmcd"));
- return;
- }
-
- if (getDisallowSpeech() && playing->m_audioEventRTS->getAudioEventInfo()->m_soundType == AT_Streaming) {
- setDisallowSpeech(FALSE);
- }
- if (playing->m_audioEventRTS->getAudioEventInfo()->m_control & AC_LOOP) {
- if (playing->m_audioEventRTS->getNextPlayPortion() == PP_Attack) {
- playing->m_audioEventRTS->setNextPlayPortion(PP_Sound);
- }
- if (playing->m_audioEventRTS->getNextPlayPortion() == PP_Sound) {
- // First, decrease the loop count.
- playing->m_audioEventRTS->decreaseLoopCount();
- // Now, try to start the next loop
- if (startNextLoop(playing)) {
- return;
- }
- }
- }
- playing->m_audioEventRTS->advanceNextPlayPortion();
- if (playing->m_audioEventRTS->getNextPlayPortion() != PP_Done) {
- if (playing->m_type == PAT_Sample) {
- closeFile(playing->m_file); // close it so as not to leak it.
- playing->m_file = playSample(playing->m_audioEventRTS, playing->m_sample);
-
- // If we don't have a file now, then we should drop to the stopped status so that
- // We correctly close this handle.
- if (playing->m_file) {
- return;
- }
- } else if (playing->m_type == PAT_3DSample) {
- closeFile(playing->m_file); // close it so as not to leak it.
- playing->m_file = playSample3D(playing->m_audioEventRTS, playing->m_3DSample);
- // If we don't have a file now, then we should drop to the stopped status so that
- // We correctly close this handle.
- if (playing->m_file) {
- return;
- }
- }
- }
- if (playing->m_type == PAT_Stream) {
- if (playing->m_audioEventRTS->getAudioEventInfo()->m_soundType == AT_Music) {
- playStream(playing->m_audioEventRTS, playing->m_stream);
-
- return;
- }
- }
- playing->m_status = PS_Stopped; // it will be cleaned up on the next frame update
- }
- //-------------------------------------------------------------------------------------------------
- PlayingAudio *MilesAudioManager::findPlayingAudioFrom( UnsignedInt audioCompleted, UnsignedInt flags )
- {
- std::list<PlayingAudio *>::iterator it;
- PlayingAudio *playing;
- if (flags == PAT_Sample) {
- HSAMPLE sample = (HSAMPLE) audioCompleted;
- for (it = m_playingSounds.begin(); it != m_playingSounds.end(); ++it) {
- playing = *it;
- if (playing && playing->m_sample == sample) {
- return playing;
- }
- }
- }
- if (flags == PAT_3DSample) {
- H3DSAMPLE sample3D = (H3DSAMPLE) audioCompleted;
- for (it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); ++it) {
- playing = *it;
- if (playing && playing->m_3DSample == sample3D) {
- return playing;
- }
- }
- }
- if (flags == PAT_Stream) {
- HSTREAM stream = (HSTREAM) audioCompleted;
- for (it = m_playingStreams.begin(); it != m_playingStreams.end(); ++it) {
- playing = *it;
- if (playing && playing->m_stream == stream) {
- return playing;
- }
- }
- }
- return NULL;
- }
- //-------------------------------------------------------------------------------------------------
- UnsignedInt MilesAudioManager::getProviderCount( void ) const
- {
- return m_providerCount;
- }
- //-------------------------------------------------------------------------------------------------
- AsciiString MilesAudioManager::getProviderName( UnsignedInt providerNum ) const
- {
- if (isOn(AudioAffect_Sound3D) && providerNum < m_providerCount) {
- return m_provider3D[providerNum].name;
- }
- return AsciiString::TheEmptyString;
- }
- //-------------------------------------------------------------------------------------------------
- UnsignedInt MilesAudioManager::getProviderIndex( AsciiString providerName ) const
- {
- for (UnsignedInt i = 0; i < m_providerCount; ++i) {
- if (providerName == m_provider3D[i].name) {
- return i;
- }
- }
- return PROVIDER_ERROR;
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::selectProvider( UnsignedInt providerNdx )
- {
- if (!isOn(AudioAffect_Sound3D))
- {
- return;
- }
- if (providerNdx == m_selectedProvider)
- {
- return;
- }
- if (isValidProvider())
- {
- freeAllMilesHandles();
- unselectProvider();
- }
- LPDIRECTSOUND lpDirectSoundInfo;
- AIL_get_DirectSound_info( NULL, (void**)&lpDirectSoundInfo, NULL );
- Bool useDolby = FALSE;
- if( lpDirectSoundInfo )
- {
- DWORD speakerConfig;
- lpDirectSoundInfo->GetSpeakerConfig( &speakerConfig );
- switch( DSSPEAKER_CONFIG( speakerConfig ) )
- {
- case DSSPEAKER_DIRECTOUT:
- m_selectedSpeakerType = AIL_3D_2_SPEAKER;
- break;
- case DSSPEAKER_MONO:
- m_selectedSpeakerType = AIL_3D_2_SPEAKER;
- break;
- case DSSPEAKER_STEREO:
- m_selectedSpeakerType = AIL_3D_2_SPEAKER;
- break;
- case DSSPEAKER_HEADPHONE:
- m_selectedSpeakerType = AIL_3D_HEADPHONE;
- useDolby = TRUE;
- break;
- case DSSPEAKER_QUAD:
- m_selectedSpeakerType = AIL_3D_4_SPEAKER;
- useDolby = TRUE;
- break;
- case DSSPEAKER_SURROUND:
- m_selectedSpeakerType = AIL_3D_SURROUND;
- useDolby = TRUE;
- break;
- case DSSPEAKER_5POINT1:
- m_selectedSpeakerType = AIL_3D_51_SPEAKER;
- useDolby = TRUE;
- break;
- case DSSPEAKER_7POINT1:
- m_selectedSpeakerType = AIL_3D_71_SPEAKER;
- useDolby = TRUE;
- break;
- }
- }
- Bool success = FALSE;
- if( useDolby )
- {
- providerNdx = getProviderIndex( "Dolby Surround" );
- }
- else
- {
- providerNdx = getProviderIndex( "Miles Fast 2D Positional Audio" );
- }
- success = AIL_open_3D_provider( m_provider3D[providerNdx].id ) == 0;
- //if (providerNdx < m_providerCount)
- //{
- // failed = AIL_open_3D_provider(m_provider3D[providerNdx].id);
- //}
- if( !success )
- {
- m_selectedProvider = PROVIDER_ERROR;
- // try to select a failsafe
- providerNdx = getProviderIndex( "Miles Fast 2D Positional Audio" );
- success = AIL_open_3D_provider( m_provider3D[providerNdx].id ) == 0;
- }
- if ( success )
- {
- m_selectedProvider = providerNdx;
-
- initSamplePools();
-
- createListener();
- setSpeakerType(m_selectedSpeakerType);
- if (TheVideoPlayer)
- {
- TheVideoPlayer->notifyVideoPlayerOfNewProvider(TRUE);
- }
- }
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::unselectProvider( void )
- {
- if (!(isOn(AudioAffect_Sound3D) && isValidProvider())) {
- return;
- }
- if (TheVideoPlayer) {
- TheVideoPlayer->notifyVideoPlayerOfNewProvider(FALSE);
- }
- AIL_close_3D_listener(m_listener);
- m_listener = NULL;
- AIL_close_3D_provider(m_provider3D[m_selectedProvider].id);
- m_lastProvider = m_selectedProvider;
- m_selectedProvider = PROVIDER_ERROR;
- }
- //-------------------------------------------------------------------------------------------------
- UnsignedInt MilesAudioManager::getSelectedProvider( void ) const
- {
- return m_selectedProvider;
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::setSpeakerType( UnsignedInt speakerType )
- {
- if (!isValidProvider()) {
- return;
- }
-
- AIL_set_3D_speaker_type( m_provider3D[m_selectedProvider].id, speakerType );
- m_selectedSpeakerType = speakerType;
- }
- //-------------------------------------------------------------------------------------------------
- UnsignedInt MilesAudioManager::getSpeakerType( void )
- {
- if (!isValidProvider()) {
- return 0;
- }
- return m_selectedSpeakerType;
- }
- //-------------------------------------------------------------------------------------------------
- UnsignedInt MilesAudioManager::getNum2DSamples( void ) const
- {
- return m_num2DSamples;
- }
- //-------------------------------------------------------------------------------------------------
- UnsignedInt MilesAudioManager::getNum3DSamples( void ) const
- {
- return m_num3DSamples;
- }
- //-------------------------------------------------------------------------------------------------
- UnsignedInt MilesAudioManager::getNumStreams( void ) const
- {
- return m_numStreams;
- }
- //-------------------------------------------------------------------------------------------------
- Bool MilesAudioManager::doesViolateLimit( AudioEventRTS *event ) const
- {
- Int limit = event->getAudioEventInfo()->m_limit;
- if (limit == 0) {
- return false;
- }
- Int totalCount = 0;
- Int totalRequestCount = 0;
- std::list<PlayingAudio *>::const_iterator it;
- if (!event->isPositionalAudio()) {
- // 2-D
- for ( it = m_playingSounds.begin(); it != m_playingSounds.end(); ++it ) {
- if ((*it)->m_audioEventRTS->getEventName() == event->getEventName()) {
- if (totalCount == 0) {
- // This is the oldest audio of this type playing.
- event->setHandleToKill((*it)->m_audioEventRTS->getPlayingHandle());
- }
- ++totalCount;
- }
- }
- } else {
- // 3-D
- for ( it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); ++it ) {
- if ((*it)->m_audioEventRTS->getEventName() == event->getEventName()) {
- if (totalCount == 0) {
- // This is the oldest audio of this type playing.
- event->setHandleToKill((*it)->m_audioEventRTS->getPlayingHandle());
- }
- ++totalCount;
- }
- }
- }
-
- // Also check the request list in case we've requested to play this sound.
- std::list<AudioRequest*>::const_iterator arIt;
- for (arIt = m_audioRequests.begin(); arIt != m_audioRequests.end(); ++arIt) {
- AudioRequest *req = (*arIt);
- if (req == NULL) {
- continue;
- }
- if( req->m_usePendingEvent )
- {
- if( req->m_pendingEvent->getEventName() == event->getEventName() )
- {
- totalRequestCount++;
- totalCount++;
- }
- }
- }
- //If our event is an interrupting type, then normally we would always add it. The exception is when we have requested
- //multiple sounds in the same frame and those requests violate the limit. Because we don't have any "old" sounds to
- //remove in the case of an interrupt, we need to catch it early and prevent the sound from being added if we already
- //reached the limit
- if( event->getAudioEventInfo()->m_control & AC_INTERRUPT )
- {
- if( totalRequestCount < limit )
- {
- Int totalPlayingCount = totalCount - totalRequestCount;
- if( totalRequestCount + totalPlayingCount < limit )
- {
- //We aren't exceeding the actual limit, then clear the kill handle.
- event->setHandleToKill(0);
- return false;
- }
- //We are exceeding the limit - the kill handle will kill the
- //oldest playing sound to enforce the actual limit.
- return false;
- }
- }
- if( totalCount < limit )
- {
- event->setHandleToKill(0);
- return false;
- }
- return true;
- }
- //-------------------------------------------------------------------------------------------------
- Bool MilesAudioManager::isPlayingAlready( AudioEventRTS *event ) const
- {
- std::list<PlayingAudio *>::const_iterator it;
- if (!event->isPositionalAudio()) {
- // 2-D
- for ( it = m_playingSounds.begin(); it != m_playingSounds.end(); ++it ) {
- if ((*it)->m_audioEventRTS->getEventName() == event->getEventName()) {
- return true;
- }
- }
- } else {
- // 3-D
- for ( it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); ++it ) {
- if ((*it)->m_audioEventRTS->getEventName() == event->getEventName()) {
- return true;
- }
- }
- }
- return false;
- }
- //-------------------------------------------------------------------------------------------------
- Bool MilesAudioManager::isObjectPlayingVoice( UnsignedInt objID ) const
- {
- if (objID == 0) {
- return false;
- }
- std::list<PlayingAudio *>::const_iterator it;
- // 2-D
- for ( it = m_playingSounds.begin(); it != m_playingSounds.end(); ++it ) {
- if ((*it)->m_audioEventRTS->getObjectID() == objID && (*it)->m_audioEventRTS->getAudioEventInfo()->m_type & ST_VOICE) {
- return true;
- }
- }
- // 3-D
- for ( it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); ++it ) {
- if ((*it)->m_audioEventRTS->getObjectID() == objID && (*it)->m_audioEventRTS->getAudioEventInfo()->m_type & ST_VOICE) {
- return true;
- }
- }
- return false;
- }
- //-------------------------------------------------------------------------------------------------
- AudioEventRTS* MilesAudioManager::findLowestPrioritySound( AudioEventRTS *event )
- {
- AudioPriority priority = event->getAudioEventInfo()->m_priority;
- if( priority == AP_LOWEST )
- {
- //If the event we pass in is the lowest priority, don't bother checking because
- //there is nothing lower priority than lowest.
- return NULL;
- }
- AudioEventRTS *lowestPriorityEvent = NULL;
- AudioPriority lowestPriority;
- std::list<PlayingAudio *>::const_iterator it;
- if( event->isPositionalAudio() )
- {
- //3D
- for( it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); ++it )
- {
- AudioEventRTS *itEvent = (*it)->m_audioEventRTS;
- AudioPriority itPriority = itEvent->getAudioEventInfo()->m_priority;
- if( itPriority < priority )
- {
- if( !lowestPriorityEvent || lowestPriority > itPriority )
- {
- lowestPriorityEvent = itEvent;
- lowestPriority = itPriority;
- if( lowestPriority == AP_LOWEST )
- {
- return lowestPriorityEvent;
- }
- }
- }
- }
- }
- else
- {
- //2D
- for( it = m_playingSounds.begin(); it != m_playingSounds.end(); ++it )
- {
- AudioEventRTS *itEvent = (*it)->m_audioEventRTS;
- AudioPriority itPriority = itEvent->getAudioEventInfo()->m_priority;
- if( itPriority < priority )
- {
- if( !lowestPriorityEvent || lowestPriority > itPriority )
- {
- lowestPriorityEvent = itEvent;
- lowestPriority = itPriority;
- if( lowestPriority == AP_LOWEST )
- {
- return lowestPriorityEvent;
- }
- }
- }
- }
- }
- return lowestPriorityEvent;
- }
- //-------------------------------------------------------------------------------------------------
- Bool MilesAudioManager::isPlayingLowerPriority( AudioEventRTS *event ) const
- {
- //We don't actually want to do anything to this CONST function. Remember, we're
- //just checking to see if there is a lower priority sound.
- AudioPriority priority = event->getAudioEventInfo()->m_priority;
- if( priority == AP_LOWEST )
- {
- //If the event we pass in is the lowest priority, don't bother checking because
- //there is nothing lower priority than lowest.
- return false;
- }
- std::list<PlayingAudio *>::const_iterator it;
- if (!event->isPositionalAudio()) {
- // 2-D
- for ( it = m_playingSounds.begin(); it != m_playingSounds.end(); ++it ) {
- if ((*it)->m_audioEventRTS->getAudioEventInfo()->m_priority < priority) {
- //event->setHandleToKill((*it)->m_audioEventRTS->getPlayingHandle());
- return true;
- }
- }
- } else {
- // 3-D
- for ( it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); ++it ) {
- if ((*it)->m_audioEventRTS->getAudioEventInfo()->m_priority < priority) {
- //event->setHandleToKill((*it)->m_audioEventRTS->getPlayingHandle());
- return true;
- }
- }
- }
- return false;
- }
- //-------------------------------------------------------------------------------------------------
- Bool MilesAudioManager::killLowestPrioritySoundImmediately( AudioEventRTS *event )
- {
- //Actually, we want to kill the LOWEST PRIORITY SOUND, not the first "lower" priority
- //sound we find, because it could easily be
- AudioEventRTS *lowestPriorityEvent = findLowestPrioritySound( event );
- if( lowestPriorityEvent )
- {
- std::list<PlayingAudio *>::iterator it;
- if( event->isPositionalAudio() )
- {
- for( it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); ++it )
- {
- PlayingAudio *playing = (*it);
- if( !playing )
- {
- continue;
- }
- if( playing->m_audioEventRTS && playing->m_audioEventRTS == lowestPriorityEvent )
- {
- //Release this 3D sound channel immediately because we are going to play another sound in it's place.
- releasePlayingAudio( playing );
- m_playing3DSounds.erase( it );
- return TRUE;
- }
- }
- }
- else
- {
- for( it = m_playingSounds.begin(); it != m_playingSounds.end(); ++it )
- {
- PlayingAudio *playing = (*it);
- if( !playing )
- {
- continue;
- }
- if( playing->m_audioEventRTS && playing->m_audioEventRTS == lowestPriorityEvent )
- {
- //Release this 3D sound channel immediately because we are going to play another sound in it's place.
- releasePlayingAudio( playing );
- m_playing3DSounds.erase( it );
- return TRUE;
- }
- }
- }
- }
- return FALSE;
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::adjustVolumeOfPlayingAudio(AsciiString eventName, Real newVolume)
- {
- Real pan;
- std::list<PlayingAudio *>::iterator it;
- PlayingAudio *playing = NULL;
- for (it = m_playingSounds.begin(); it != m_playingSounds.end(); ++it) {
- playing = *it;
- if (playing && playing->m_audioEventRTS->getEventName() == eventName) {
- // Adjust it
- playing->m_audioEventRTS->setVolume(newVolume);
- Real desiredVolume = playing->m_audioEventRTS->getVolume() * playing->m_audioEventRTS->getVolumeShift();
- AIL_sample_volume_pan(playing->m_sample, NULL, &pan);
- AIL_set_sample_volume_pan(playing->m_sample, desiredVolume, pan);
- }
- }
- for (it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); ++it) {
- playing = *it;
- if (playing && playing->m_audioEventRTS->getEventName() == eventName) {
- // Adjust it
- playing->m_audioEventRTS->setVolume(newVolume);
- Real desiredVolume = playing->m_audioEventRTS->getVolume() * playing->m_audioEventRTS->getVolumeShift();
- AIL_set_3D_sample_volume(playing->m_3DSample, desiredVolume);
- }
- }
- for (it = m_playingStreams.begin(); it != m_playingStreams.end(); ++it) {
- playing = *it;
- if (playing && playing->m_audioEventRTS->getEventName() == eventName) {
- // Adjust it
- playing->m_audioEventRTS->setVolume(newVolume);
- Real desiredVolume = playing->m_audioEventRTS->getVolume() * playing->m_audioEventRTS->getVolumeShift();
- AIL_stream_volume_pan(playing->m_stream, NULL, &pan);
- AIL_set_stream_volume_pan(playing->m_stream, desiredVolume, pan);
- }
- }
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::removePlayingAudio( AsciiString eventName )
- {
- std::list<PlayingAudio *>::iterator it;
- PlayingAudio *playing = NULL;
- for( it = m_playingSounds.begin(); it != m_playingSounds.end(); )
- {
- playing = *it;
- if( playing && playing->m_audioEventRTS->getEventName() == eventName )
- {
- releasePlayingAudio( playing );
- it = m_playingSounds.erase(it);
- }
- else
- {
- it++;
- }
- }
- for( it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); )
- {
- playing = *it;
- if( playing && playing->m_audioEventRTS->getEventName() == eventName )
- {
- releasePlayingAudio( playing );
- it = m_playing3DSounds.erase(it);
- }
- else
- {
- it++;
- }
- }
- for( it = m_playingStreams.begin(); it != m_playingStreams.end(); )
- {
- playing = *it;
- if( playing && playing->m_audioEventRTS->getEventName() == eventName )
- {
- releasePlayingAudio( playing );
- it = m_playingStreams.erase(it);
- }
- else
- {
- it++;
- }
- }
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::removeAllDisabledAudio()
- {
- std::list<PlayingAudio *>::iterator it;
- PlayingAudio *playing = NULL;
- for( it = m_playingSounds.begin(); it != m_playingSounds.end(); )
- {
- playing = *it;
- if( playing && playing->m_audioEventRTS->getVolume() == 0.0f )
- {
- releasePlayingAudio( playing );
- it = m_playingSounds.erase(it);
- }
- else
- {
- it++;
- }
- }
- for( it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); )
- {
- playing = *it;
- if( playing && playing->m_audioEventRTS->getVolume() == 0.0f )
- {
- releasePlayingAudio( playing );
- it = m_playing3DSounds.erase(it);
- }
- else
- {
- it++;
- }
- }
- for( it = m_playingStreams.begin(); it != m_playingStreams.end(); )
- {
- playing = *it;
- if( playing && playing->m_audioEventRTS->getVolume() == 0.0f )
- {
- releasePlayingAudio( playing );
- it = m_playingStreams.erase(it);
- }
- else
- {
- it++;
- }
- }
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::processRequestList( void )
- {
- std::list<AudioRequest*>::iterator it;
- for (it = m_audioRequests.begin(); it != m_audioRequests.end(); /* empty */) {
- AudioRequest *req = (*it);
- if (req == NULL) {
- continue;
- }
- if (!shouldProcessRequestThisFrame(req)) {
- adjustRequest(req);
- ++it;
- continue;
- }
- if (!req->m_requiresCheckForSample || checkForSample(req)) {
- processRequest(req);
- }
- req->deleteInstance();
- it = m_audioRequests.erase(it);
- }
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::processPlayingList( void )
- {
- // There are two types of processing we have to do here.
- // 1. Move the item to the stopped list if it has become stopped.
- // 2. Update the position of the audio if it is positional
- std::list<PlayingAudio *>::iterator it;
- PlayingAudio *playing;
- for (it = m_playingSounds.begin(); it != m_playingSounds.end(); /* empty */) {
- playing = (*it);
- if (!playing)
- {
- it = m_playingSounds.erase(it);
- continue;
- }
- if (playing->m_status == PS_Stopped)
- {
- //m_stoppedAudio.push_back(playing);
- releasePlayingAudio( playing );
- it = m_playingSounds.erase(it);
- }
- else
- {
- if (m_volumeHasChanged)
- {
- adjustPlayingVolume(playing);
- }
- ++it;
- }
- }
- for (it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); )
- {
- playing = (*it);
- if (!playing)
- {
- it = m_playing3DSounds.erase(it);
- continue;
- }
- if (playing->m_status == PS_Stopped)
- {
- //m_stoppedAudio.push_back(playing);
- releasePlayingAudio( playing );
- it = m_playing3DSounds.erase(it);
- }
- else
- {
- if (m_volumeHasChanged)
- {
- adjustPlayingVolume(playing);
- }
- const Coord3D *pos = getCurrentPositionFromEvent(playing->m_audioEventRTS);
- if (pos)
- {
- if( playing->m_audioEventRTS->isDead() )
- {
- stopAudioEvent( playing->m_audioEventRTS->getPlayingHandle() );
- it++;
- continue;
- }
- else
- {
- Real volForConsideration = getEffectiveVolume(playing->m_audioEventRTS);
- volForConsideration /= (m_sound3DVolume > 0.0f ? m_soundVolume : 1.0f);
- Bool playAnyways = BitTest( playing->m_audioEventRTS->getAudioEventInfo()->m_type, ST_GLOBAL) || playing->m_audioEventRTS->getAudioEventInfo()->m_priority == AP_CRITICAL;
- if( volForConsideration < m_audioSettings->m_minVolume && !playAnyways )
- {
- // don't want to get an additional callback for this sample
- AIL_register_3D_EOS_callback(playing->m_3DSample, NULL);
- //m_stoppedAudio.push_back(playing);
- releasePlayingAudio( playing );
- it = m_playing3DSounds.erase(it);
- continue;
- }
- else
- {
- Real x = pos->x;
- Real y = pos->y;
- Real z = pos->z;
- AIL_set_3D_position( playing->m_3DSample, x, y, z );
- }
- }
- }
- else
- {
- AIL_register_3D_EOS_callback(playing->m_3DSample, NULL);
- //m_stoppedAudio.push_back(playing);
- releasePlayingAudio( playing );
- it = m_playing3DSounds.erase(it);
- continue;
- }
- ++it;
- }
- }
- for (it = m_playingStreams.begin(); it != m_playingStreams.end(); ) {
- playing = (*it);
- if (!playing)
- {
- it = m_playingStreams.erase(it);
- continue;
- }
- if (playing->m_status == PS_Stopped)
- {
- //m_stoppedAudio.push_back(playing);
- releasePlayingAudio( playing );
- it = m_playingStreams.erase(it);
- }
- else
- {
- if (m_volumeHasChanged)
- {
- adjustPlayingVolume(playing);
- }
- ++it;
- }
- }
- if (m_volumeHasChanged) {
- m_volumeHasChanged = false;
- }
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::processFadingList( void )
- {
- std::list<PlayingAudio *>::iterator it;
- PlayingAudio *playing;
- for (it = m_fadingAudio.begin(); it != m_fadingAudio.end(); /* emtpy */) {
- playing = *it;
- if (!playing) {
- continue;
- }
-
- if (playing->m_framesFaded >= getAudioSettings()->m_fadeAudioFrames) {
- playing->m_status = PS_Stopped;
- playing->m_requestStop = true;
- //m_stoppedAudio.push_back(playing);
- releasePlayingAudio( playing );
- it = m_fadingAudio.erase(it);
- continue;
- }
- ++playing->m_framesFaded;
- Real volume = getEffectiveVolume(playing->m_audioEventRTS);
- volume *= (1.0f - 1.0f * playing->m_framesFaded / getAudioSettings()->m_fadeAudioFrames);
- switch(playing->m_type)
- {
- case PAT_Sample:
- {
- AIL_set_sample_volume_pan(playing->m_sample, volume, 0.5f);
- break;
- }
- case PAT_3DSample:
- {
- AIL_set_3D_sample_volume(playing->m_3DSample, volume);
- break;
- }
-
- case PAT_Stream:
- {
- AIL_set_stream_volume_pan(playing->m_stream, volume, 0.5f);
- break;
- }
-
- }
-
- ++it;
- }
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::processStoppedList( void )
- {
- std::list<PlayingAudio *>::iterator it;
- PlayingAudio *playing;
- for (it = m_stoppedAudio.begin(); it != m_stoppedAudio.end(); /* emtpy */) {
- playing = *it;
- if (playing) {
- releasePlayingAudio(playing);
- }
- it = m_stoppedAudio.erase(it);
- }
- }
- //-------------------------------------------------------------------------------------------------
- Bool MilesAudioManager::shouldProcessRequestThisFrame( AudioRequest *req ) const
- {
- if (!req->m_usePendingEvent) {
- return true;
- }
- if (req->m_pendingEvent->getDelay() < MSEC_PER_LOGICFRAME_REAL) {
- return true;
- }
- return false;
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::adjustRequest( AudioRequest *req )
- {
- if (!req->m_usePendingEvent) {
- return;
- }
- req->m_pendingEvent->decrementDelay(MSEC_PER_LOGICFRAME_REAL);
- req->m_requiresCheckForSample = true;
- }
- //-------------------------------------------------------------------------------------------------
- Bool MilesAudioManager::checkForSample( AudioRequest *req )
- {
- if (!req->m_usePendingEvent) {
- return true;
- }
- if (req->m_pendingEvent->getAudioEventInfo()->m_type != AT_SoundEffect) {
- return true;
- }
- return m_sound->canPlayNow(req->m_pendingEvent);
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::setHardwareAccelerated(Bool accel)
- {
- // Extends
- Bool retEarly = (accel == m_hardwareAccel);
- AudioManager::setHardwareAccelerated(accel);
- if (retEarly) {
- return;
- }
-
- if (m_hardwareAccel) {
- for (Int i = 0; i < MAX_HW_PROVIDERS; ++i) {
- UnsignedInt providerNdx = TheAudio->getProviderIndex(TheAudio->getAudioSettings()->m_preferred3DProvider[i]);
- TheAudio->selectProvider(providerNdx);
- if (getSelectedProvider() == providerNdx) {
- return;
- }
- }
- }
- // set it false
- AudioManager::setHardwareAccelerated(FALSE);
- UnsignedInt providerNdx = TheAudio->getProviderIndex(TheAudio->getAudioSettings()->m_preferred3DProvider[MAX_HW_PROVIDERS]);
- TheAudio->selectProvider(providerNdx);
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::setSpeakerSurround(Bool surround)
- {
- // Extends
- Bool retEarly = (surround == m_surroundSpeakers);
- AudioManager::setSpeakerSurround(surround);
- if (retEarly) {
- return;
- }
- UnsignedInt speakerType;
- if (m_surroundSpeakers) {
- speakerType = TheAudio->getAudioSettings()->m_defaultSpeakerType3D;
- } else {
- speakerType = TheAudio->getAudioSettings()->m_defaultSpeakerType2D;
- }
- TheAudio->setSpeakerType(speakerType);
- }
- //-------------------------------------------------------------------------------------------------
- Real MilesAudioManager::getFileLengthMS( AsciiString strToLoad ) const
- {
- if (strToLoad.isEmpty()) {
- return 0.0f;
- }
- // Load it as a stream to get the file info without actually opening the file.
- HSTREAM stream = AIL_open_stream(m_digitalHandle, strToLoad.str(), 0);
- if (!stream) {
- return 0.0f;
- }
- long retVal;
- AIL_stream_ms_position(stream, &retVal, NULL);
- // Now close the stream
- AIL_close_stream(stream);
- return INT_TO_REAL(retVal);
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::closeAnySamplesUsingFile( const void *fileToClose )
- {
- std::list<PlayingAudio *>::iterator it;
- PlayingAudio *playing;
-
- for (it = m_playingSounds.begin(); it != m_playingSounds.end(); ) {
- playing = *it;
- if (!playing) {
- continue;
- }
- if (playing->m_file == fileToClose) {
- releasePlayingAudio(playing);
- it = m_playingSounds.erase(it);
- } else {
- ++it;
- }
- }
- for (it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); ) {
- playing = *it;
- if (!playing) {
- continue;
- }
- if (playing->m_file == fileToClose) {
- releasePlayingAudio(playing);
- it = m_playing3DSounds.erase(it);
- } else {
- ++it;
- }
- }
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::setDeviceListenerPosition( void )
- {
- if (m_listener) {
- AIL_set_3D_orientation(m_listener, m_listenerOrientation.x, m_listenerOrientation.y, m_listenerOrientation.z, 0, 0, -1);
- Real x = m_listenerPosition.x;
- Real y = m_listenerPosition.y;
- Real z = m_listenerPosition.z;
- AIL_set_3D_position( m_listener, x, y, z );
- }
- }
- //-------------------------------------------------------------------------------------------------
- const Coord3D *MilesAudioManager::getCurrentPositionFromEvent( AudioEventRTS *event )
- {
- if (!event->isPositionalAudio()) {
- return NULL;
- }
- return event->getCurrentPosition();
- }
- //-------------------------------------------------------------------------------------------------
- Bool MilesAudioManager::isOnScreen( const Coord3D *pos ) const
- {
- static ICoord2D dummy;
- // WorldToScreen will return True if the point is onscreen and false if it is offscreen.
- return TheTacticalView->worldToScreen(pos, &dummy);
- }
- //-------------------------------------------------------------------------------------------------
- Real MilesAudioManager::getEffectiveVolume(AudioEventRTS *event) const
- {
- Real volume = 1.0f;
- volume *= (event->getVolume() * event->getVolumeShift());
- if (event->getAudioEventInfo()->m_soundType == AT_Music)
- {
- volume *= m_musicVolume;
- }
- else if (event->getAudioEventInfo()->m_soundType == AT_Streaming)
- {
- volume *= m_speechVolume;
- }
- else
- {
- if (event->isPositionalAudio())
- {
- volume *= m_sound3DVolume;
- Coord3D distance = m_listenerPosition;
- const Coord3D *pos = event->getCurrentPosition();
- if (pos)
- {
- distance.sub(pos);
- Real objMinDistance;
- Real objMaxDistance;
- if (event->getAudioEventInfo()->m_type & ST_GLOBAL)
- {
- objMinDistance = TheAudio->getAudioSettings()->m_globalMinRange;
- objMaxDistance = TheAudio->getAudioSettings()->m_globalMaxRange;
- }
- else
- {
- objMinDistance = event->getAudioEventInfo()->m_minDistance;
- objMaxDistance = event->getAudioEventInfo()->m_maxDistance;
- }
- Real objDistance = distance.length();
- if( objDistance > objMinDistance )
- {
- volume *= 1 / (objDistance / objMinDistance);
- }
- if( objDistance >= objMaxDistance )
- {
- volume = 0.0f;
- }
- //else if( objDistance > objMinDistance )
- //{
- // volume *= 1.0f - (objDistance - objMinDistance) / (objMaxDistance - objMinDistance);
- //}
- }
- }
- else
- {
- volume *= m_soundVolume;
- }
- }
- return volume;
- }
- //-------------------------------------------------------------------------------------------------
- Bool MilesAudioManager::startNextLoop( PlayingAudio *looping )
- {
- closeFile(looping->m_file);
- looping->m_file = NULL;
- if (looping->m_requestStop) {
- return false;
- }
- if (looping->m_audioEventRTS->hasMoreLoops()) {
- // generate a new filename, and test to see whether we can play with it now
- looping->m_audioEventRTS->generateFilename();
-
- if (looping->m_audioEventRTS->getDelay() > MSEC_PER_LOGICFRAME_REAL) {
- // fake it out so that this sound appears done, but also so that it will not
- // delete the sound on completion (which would suck)
- looping->m_cleanupAudioEventRTS = false;
- looping->m_requestStop = true;
- looping->m_status = PS_Stopped;
-
-
- AudioRequest *req = allocateAudioRequest(true);
- req->m_pendingEvent = looping->m_audioEventRTS;
- req->m_requiresCheckForSample = true;
- appendAudioRequest(req);
- return true;
- }
- if (looping->m_type == PAT_3DSample) {
- looping->m_file = playSample3D(looping->m_audioEventRTS, looping->m_3DSample);
- } else {
- looping->m_file = playSample(looping->m_audioEventRTS, looping->m_sample);
- }
-
- return looping->m_file != NULL;
- }
- return false;
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::playStream( AudioEventRTS *event, HSTREAM stream )
- {
- // Force it to the beginning
- if (event->getAudioEventInfo()->m_soundType == AT_Music) {
- AIL_set_stream_loop_count(stream, INFINITE_LOOP_COUNT);
- }
- AIL_register_stream_callback(stream, setStreamCompleted);
- AIL_start_stream(stream);
- if (event->getAudioEventInfo()->m_soundType == AT_Music) {
- // Need to stop/fade out the old music here.
- }
- }
- //-------------------------------------------------------------------------------------------------
- void *MilesAudioManager::playSample( AudioEventRTS *event, HSAMPLE sample )
- {
- AIL_init_sample(sample);
- // Prep any sort of filtering, etc, here
- AIL_register_EOS_callback(sample, setSampleCompleted);
- initFilters(sample, event);
- // Load the file in
- void *fileBuffer = NULL;
- fileBuffer = loadFileForRead(event);
- if (fileBuffer) {
- AIL_set_sample_file(sample, fileBuffer, 0);
- // Start playback
- AIL_start_sample(sample);
- }
- return fileBuffer;
- }
- //-------------------------------------------------------------------------------------------------
- void *MilesAudioManager::playSample3D( AudioEventRTS *event, H3DSAMPLE sample3D )
- {
- const Coord3D *pos = getCurrentPositionFromEvent(event);
- if (pos) {
- // Load the file in
- void *fileBuffer = loadFileForRead(event);
- if (fileBuffer) {
- AIL_set_3D_sample_file(sample3D, fileBuffer);
- // Prep any sort of filtering, etc, here
- AIL_register_3D_EOS_callback(sample3D, set3DSampleCompleted);
- // Set the position values of the sample here
- if (event->getAudioEventInfo()->m_type & ST_GLOBAL) {
- AIL_set_3D_sample_distances(sample3D, TheAudio->getAudioSettings()->m_globalMinRange, TheAudio->getAudioSettings()->m_globalMaxRange );
- } else {
- AIL_set_3D_sample_distances(sample3D, event->getAudioEventInfo()->m_minDistance, event->getAudioEventInfo()->m_maxDistance );
- }
-
- // Set the position of the sample here
- Real x = pos->x;
- Real y = pos->y;
- Real z = pos->z;
- AIL_set_3D_position( sample3D, x, y, z );
- initFilters3D(sample3D, event, pos);
-
- // Start playback
- AIL_start_3D_sample(sample3D);
- }
- return fileBuffer;
- }
- return NULL;
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::buildProviderList( void )
- {
- HPROENUM next = HPROENUM_FIRST;
- char *name;
- UnsignedInt index = 0;
- while (index < MAXPROVIDERS && AIL_enumerate_3D_providers(&next, &m_provider3D[index].id, &name)) {
- m_provider3D[index].name.set(name); // set it to the AsciiString
- ++index;
- }
-
- m_providerCount = index;
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::createListener( void )
- {
- if (!(isOn(AudioAffect_Sound3D) && isValidProvider())) {
- return;
- }
- m_listener = AIL_open_3D_listener(m_provider3D[m_selectedProvider].id);
- // initial listener position will be (0, 0, 0)
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::initDelayFilter( void )
- {
- if (m_delayFilter != NULL) {
- return;
- }
- char* filterName;
- HPROENUM enumFLTs = HPROENUM_FIRST;
- HPROVIDER currentProvider;
- while (AIL_enumerate_filters(&enumFLTs, ¤tProvider, &filterName )) {
- if (strcmp(filterName,"Mono Delay Filter") == 0) {
- m_delayFilter = currentProvider;
- break;
- }
- }
- }
- //-------------------------------------------------------------------------------------------------
- Bool MilesAudioManager::isValidProvider( void )
- {
- return (m_selectedProvider < m_providerCount);
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::initSamplePools( void )
- {
- if (!(isOn(AudioAffect_Sound3D) && isValidProvider())) {
- return;
- }
- int i = 0;
- for (i = 0; i < getAudioSettings()->m_sampleCount2D; ++i) {
- HSAMPLE sample = AIL_allocate_sample_handle(m_digitalHandle);
- DEBUG_ASSERTCRASH(sample, ("Couldn't get %d 2D samples\n", i + 1));
- if (sample) {
- AIL_init_sample(sample);
- AIL_set_sample_user_data(sample, 0, i + 1);
- m_availableSamples.push_back(sample);
- ++m_num2DSamples;
- }
- }
- for (i = 0; i < getAudioSettings()->m_sampleCount3D; ++i) {
- H3DSAMPLE sample = AIL_allocate_3D_sample_handle(m_provider3D[m_selectedProvider].id);
- DEBUG_ASSERTCRASH(sample, ("Couldn't get %d 3D samples\n", i + 1));
- if (sample) {
- AIL_set_3D_user_data(sample, 0, i + 1);
- m_available3DSamples.push_back(sample);
- ++m_num3DSamples;
- }
- }
- // Streams are basically free, so we can just allocate the appropriate number
- m_numStreams = getAudioSettings()->m_streamCount;
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::processRequest( AudioRequest *req )
- {
- switch (req->m_request)
- {
- case AR_Play:
- {
- playAudioEvent(req->m_pendingEvent);
- break;
- }
- case AR_Pause:
- {
- pauseAudioEvent(req->m_handleToInteractOn);
- break;
- }
- case AR_Stop:
- {
- stopAudioEvent(req->m_handleToInteractOn);
- break;
- }
- }
- }
- //-------------------------------------------------------------------------------------------------
- void *MilesAudioManager::getHandleForBink( void )
- {
- if (m_binkHandle == NULL) {
- PlayingAudio *aud = allocatePlayingAudio();
- aud->m_audioEventRTS = NEW AudioEventRTS("BinkHandle"); // poolify
- getInfoForAudioEvent(aud->m_audioEventRTS);
- aud->m_sample = getFirst2DSample(aud->m_audioEventRTS);
- aud->m_type = PAT_Sample;
- if (!aud->m_sample) {
- releasePlayingAudio(aud);
- return NULL;
- }
- m_binkHandle = aud;
- }
-
- AILLPDIRECTSOUND lpDS;
- AIL_get_DirectSound_info(m_binkHandle->m_sample, &lpDS, NULL);
- return lpDS;
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::releaseHandleForBink( void )
- {
- if (m_binkHandle) {
- releasePlayingAudio(m_binkHandle);
- m_binkHandle = NULL;
- }
- }
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::friend_forcePlayAudioEventRTS(const AudioEventRTS* eventToPlay)
- {
- if (!eventToPlay->getAudioEventInfo()) {
- getInfoForAudioEvent(eventToPlay);
- if (!eventToPlay->getAudioEventInfo()) {
- DEBUG_CRASH(("No info for forced audio event '%s'\n", eventToPlay->getEventName().str()));
- return;
- }
- }
- switch (eventToPlay->getAudioEventInfo()->m_soundType)
- {
- case AT_Music:
- if (!isOn(AudioAffect_Music))
- return;
- break;
- case AT_SoundEffect:
- if (!isOn(AudioAffect_Sound) || !isOn(AudioAffect_Sound3D))
- return;
- break;
- case AT_Streaming:
- if (!isOn(AudioAffect_Speech))
- return;
- break;
- }
-
- AudioEventRTS event = *eventToPlay;
- event.generateFilename();
- event.generatePlayInfo();
- std::list<std::pair<AsciiString, Real> >::iterator it;
- for (it = m_adjustedVolumes.begin(); it != m_adjustedVolumes.end(); ++it) {
- if (it->first == event.getEventName()) {
- event.setVolume(it->second);
- break;
- }
- }
- AsciiString fileToPlay = event.getFilename();
- HAUDIO haud = AIL_quick_load_and_play(fileToPlay.str(), 1, 0);
- // Even though the event type is not Speech, this is used only for mission briefings, so use the
- // speech slider to adjust the volume.
- // Get the volume from the event, and pass 0.5 to play the audio in the middle. (0.0 is full left, 1.0 is full right)
- AIL_quick_set_volume(haud, event.getVolume() * getVolume(AudioAffect_Speech), 0.5);
- m_audioForcePlayed.push_back(haud);
- }
- //-------------------------------------------------------------------------------------------------
- //-------------------------------------------------------------------------------------------------
- //-------------------------------------------------------------------------------------------------
- void AILCALLBACK setSampleCompleted( HSAMPLE sampleCompleted )
- {
- TheAudio->notifyOfAudioCompletion((UnsignedInt) sampleCompleted, PAT_Sample);
- }
- //-------------------------------------------------------------------------------------------------
- void AILCALLBACK set3DSampleCompleted( H3DSAMPLE sample3DCompleted )
- {
- TheAudio->notifyOfAudioCompletion((UnsignedInt) sample3DCompleted, PAT_3DSample);
- }
- //-------------------------------------------------------------------------------------------------
- void AILCALLBACK setStreamCompleted( HSTREAM streamCompleted )
- {
- TheAudio->notifyOfAudioCompletion((UnsignedInt) streamCompleted, PAT_Stream);
- }
- //-------------------------------------------------------------------------------------------------
- U32 AILCALLBACK streamingFileOpen(char const *fileName, U32 *file_handle)
- {
- #if defined(_DEBUG) || defined(_INTERNAL)
- if (sizeof(U32) != sizeof(File*)) {
- RELEASE_CRASH(("streamingFileOpen - This function requires work in order to compile on non 32-bit platforms.\n"));
- }
- #endif
- (*file_handle) = (U32) TheFileSystem->openFile(fileName, File::READ | File::STREAMING);
- return ((*file_handle) != 0);
- }
- //-------------------------------------------------------------------------------------------------
- void AILCALLBACK streamingFileClose(U32 fileHandle)
- {
- ((File*) fileHandle)->close();
- }
- //-------------------------------------------------------------------------------------------------
- S32 AILCALLBACK streamingFileSeek(U32 fileHandle, S32 offset, U32 type)
- {
- return ((File*) fileHandle)->seek(offset, (File::seekMode) type);
- }
- //-------------------------------------------------------------------------------------------------
- U32 AILCALLBACK streamingFileRead(U32 file_handle, void *buffer, U32 bytes)
- {
- return ((File*) file_handle)->read(buffer, bytes);
- }
- //-------------------------------------------------------------------------------------------------
- //-------------------------------------------------------------------------------------------------
- //-------------------------------------------------------------------------------------------------
- AudioFileCache::AudioFileCache() : m_maxSize(0), m_currentlyUsedSize(0), m_mutexName("AudioFileCacheMutex")
- {
- m_mutex = CreateMutex(NULL, FALSE, m_mutexName);
- }
- //-------------------------------------------------------------------------------------------------
- AudioFileCache::~AudioFileCache()
- {
- {
- ScopedMutex mut(m_mutex);
- // Free all the samples that are open.
- OpenFilesHashIt it;
- for ( it = m_openFiles.begin(); it != m_openFiles.end(); ++it ) {
- if (it->second.m_openCount > 0) {
- DEBUG_CRASH(("Sample '%s' is still playing, and we're trying to quit.\n", it->second.m_eventInfo->m_audioName.str()));
- }
- releaseOpenAudioFile(&it->second);
- // Don't erase it from the map, cause it makes this whole process way more complicated, and
- // we're about to go away anyways.
- }
- }
- CloseHandle(m_mutex);
- }
- //-------------------------------------------------------------------------------------------------
- void *AudioFileCache::openFile( AudioEventRTS *eventToOpenFrom )
- {
- // Protect the entire openFile function
- ScopedMutex mut(m_mutex);
- AsciiString strToFind;
- switch (eventToOpenFrom->getNextPlayPortion())
- {
- case PP_Attack:
- strToFind = eventToOpenFrom->getAttackFilename();
- break;
- case PP_Sound:
- strToFind = eventToOpenFrom->getFilename();
- break;
- case PP_Decay:
- strToFind = eventToOpenFrom->getDecayFilename();
- break;
- case PP_Done:
- return NULL;
- }
- OpenFilesHash::iterator it;
- it = m_openFiles.find(strToFind);
- if (it != m_openFiles.end()) {
- ++it->second.m_openCount;
- return it->second.m_file;
- }
- // Couldn't find the file, so actually open it.
- File *file = TheFileSystem->openFile(strToFind.str());
- if (!file) {
- DEBUG_ASSERTLOG(strToFind.isEmpty(), ("Missing Audio File: '%s'\n", strToFind.str()));
- return NULL;
- }
- UnsignedInt fileSize = file->size();
- char* buffer = file->readEntireAndClose();
- OpenAudioFile openedAudioFile;
- openedAudioFile.m_eventInfo = eventToOpenFrom->getAudioEventInfo();
- AILSOUNDINFO soundInfo;
- AIL_WAV_info(buffer, &soundInfo);
- if (eventToOpenFrom->isPositionalAudio()) {
- if (soundInfo.channels > 1) {
- DEBUG_CRASH(("Requested Positional Play of audio '%s', but it is in stereo.", strToFind.str()));
- delete [] buffer;
- return NULL;
- }
- }
-
- if (soundInfo.format == WAVE_FORMAT_IMA_ADPCM) {
- void *decompressFileBuffer;
- U32 newFileSize;
- AIL_decompress_ADPCM(&soundInfo, &decompressFileBuffer, &newFileSize);
- fileSize = newFileSize;
- openedAudioFile.m_compressed = TRUE;
- delete [] buffer;
- openedAudioFile.m_file = decompressFileBuffer;
- openedAudioFile.m_soundInfo = soundInfo;
- openedAudioFile.m_openCount = 1;
- } else if (soundInfo.format == WAVE_FORMAT_PCM) {
- openedAudioFile.m_compressed = FALSE;
- openedAudioFile.m_file = buffer;
- openedAudioFile.m_soundInfo = soundInfo;
- openedAudioFile.m_openCount = 1;
- } else {
- DEBUG_CRASH(("Unexpected compression type in '%s'\n", strToFind.str()));
- // prevent leaks
- delete [] buffer;
- return NULL;
- }
- openedAudioFile.m_fileSize = fileSize;
- m_currentlyUsedSize += openedAudioFile.m_fileSize;
- if (m_currentlyUsedSize > m_maxSize) {
- // We need to free some samples, or we're not going to be able to play this sound.
- if (!freeEnoughSpaceForSample(openedAudioFile)) {
- m_currentlyUsedSize -= openedAudioFile.m_fileSize;
- releaseOpenAudioFile(&openedAudioFile);
- return NULL;
- }
- }
- m_openFiles[strToFind] = openedAudioFile;
- return openedAudioFile.m_file;
- }
- //-------------------------------------------------------------------------------------------------
- void AudioFileCache::closeFile( void *fileToClose )
- {
- if (!fileToClose) {
- return;
- }
- // Protect the entire closeFile function
- ScopedMutex mut(m_mutex);
- OpenFilesHash::iterator it;
- for ( it = m_openFiles.begin(); it != m_openFiles.end(); ++it ) {
- if ( it->second.m_file == fileToClose ) {
- --it->second.m_openCount;
- return;
- }
- }
- }
- //-------------------------------------------------------------------------------------------------
- void AudioFileCache::setMaxSize( UnsignedInt size )
- {
- // Protect the function, in case we're trying to use this value elsewhere.
- ScopedMutex mut(m_mutex);
- m_maxSize = size;
- }
- //-------------------------------------------------------------------------------------------------
- void AudioFileCache::releaseOpenAudioFile( OpenAudioFile *fileToRelease )
- {
- if (fileToRelease->m_openCount > 0) {
- // This thing needs to be terminated IMMEDIATELY.
- TheAudio->closeAnySamplesUsingFile(fileToRelease->m_file);
- }
- if (fileToRelease->m_file) {
- if (fileToRelease->m_compressed) {
- // Files read in via AIL_decompress_ADPCM must be freed with AIL_mem_free_lock.
- AIL_mem_free_lock(fileToRelease->m_file);
- } else {
- // Otherwise, we read it, we own it, blow it away.
- delete [] fileToRelease->m_file;
- }
- fileToRelease->m_file = NULL;
- fileToRelease->m_eventInfo = NULL;
- }
- }
- //-------------------------------------------------------------------------------------------------
- Bool AudioFileCache::freeEnoughSpaceForSample(const OpenAudioFile& sampleThatNeedsSpace)
- {
-
- Int spaceRequired = m_currentlyUsedSize - m_maxSize;
- Int runningTotal = 0;
- std::list<AsciiString> filesToClose;
- // First, search for any samples that have ref counts of 0. They are low-hanging fruit, and
- // should be considered immediately.
- OpenFilesHashIt it;
- for (it = m_openFiles.begin(); it != m_openFiles.end(); ++it) {
- if (it->second.m_openCount == 0) {
- // This is said low-hanging fruit.
- filesToClose.push_back(it->first);
- runningTotal += it->second.m_fileSize;
- if (runningTotal >= spaceRequired) {
- break;
- }
- }
- }
- // If we don't have enough space yet, then search through the events who have a count of 1 or more
- // and who are lower priority than this sound.
- // Mical said that at this point, sounds shouldn't care if other sounds are interruptable or not.
- // Kill any files of lower priority necessary to clear our the buffer.
- if (runningTotal < spaceRequired) {
- for (it = m_openFiles.begin(); it != m_openFiles.end(); ++it) {
- if (it->second.m_openCount > 0) {
- if (it->second.m_eventInfo->m_priority < sampleThatNeedsSpace.m_eventInfo->m_priority) {
- filesToClose.push_back(it->first);
- runningTotal += it->second.m_fileSize;
-
- if (runningTotal >= spaceRequired) {
- break;
- }
- }
- }
- }
- }
- // We weren't able to find enough sounds to truncate. Therefore, this sound is not going to play.
- if (runningTotal < spaceRequired) {
- return FALSE;
- }
- std::list<AsciiString>::iterator ait;
- for (ait = filesToClose.begin(); ait != filesToClose.end(); ++ait) {
- OpenFilesHashIt itToErase = m_openFiles.find(*ait);
- if (itToErase != m_openFiles.end()) {
- releaseOpenAudioFile(&itToErase->second);
- m_currentlyUsedSize -= itToErase->second.m_fileSize;
- m_openFiles.erase(itToErase);
- }
- }
- return TRUE;
- }
- #if defined(_DEBUG) || defined(_INTERNAL)
- //-------------------------------------------------------------------------------------------------
- void MilesAudioManager::dumpAllAssetsUsed()
- {
- if (!TheGlobalData->m_preloadReport) {
- return;
- }
- // Dump all the audio assets we've used.
- FILE *logfile=fopen("PreloadedAssets.txt","a+"); //append to log
- if (!logfile)
- return;
- std::list<AsciiString> missingEvents;
- std::list<AsciiString> usedFiles;
- std::list<AsciiString>::iterator lit;
- fprintf(logfile, "\nAudio Asset Report - BEGIN\n");
- {
- SetAsciiStringIt it;
- std::vector<AsciiString>::iterator asIt;
- for (it = m_allEventsLoaded.begin(); it != m_allEventsLoaded.end(); ++it) {
- AsciiString astr = *it;
- AudioEventInfo *aei = findAudioEventInfo(astr);
- if (!aei) {
- missingEvents.push_back(astr);
- continue;
- }
- for (asIt = aei->m_attackSounds.begin(); asIt != aei->m_attackSounds.end(); ++asIt) {
- usedFiles.push_back(*asIt);
- }
- for (asIt = aei->m_sounds.begin(); asIt != aei->m_sounds.end(); ++asIt) {
- usedFiles.push_back(*asIt);
- }
- for (asIt = aei->m_decaySounds.begin(); asIt != aei->m_decaySounds.end(); ++asIt) {
- usedFiles.push_back(*asIt);
- }
- if (!aei->m_filename.isEmpty()) {
- usedFiles.push_back(aei->m_filename);
- }
- }
- fprintf(logfile, "\nEvents Requested that are missing information - BEGIN\n");
- for (lit = missingEvents.begin(); lit != missingEvents.end(); ++lit) {
- fprintf(logfile, "%s\n", (*lit).str());
- }
- fprintf(logfile, "\nEvents Requested that are missing information - END\n");
- fprintf(logfile, "\nFiles Used - BEGIN\n");
- for (lit = usedFiles.begin(); lit != usedFiles.end(); ++lit) {
- fprintf(logfile, "%s\n", (*lit).str());
- }
- fprintf(logfile, "\nFiles Used - END\n");
- }
- fprintf(logfile, "\nAudio Asset Report - END\n");
- fclose(logfile);
- logfile = NULL;
- }
- #endif
|