AUD_Events.cpp 87 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132
  1. /*
  2. ** Command & Conquer Generals(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /*****************************************************************************
  19. ** **
  20. ** Westwood Studios Pacific. **
  21. ** **
  22. ** Confidential Information **
  23. ** Copyright (C) 2000 - All Rights Reserved **
  24. ** **
  25. ******************************************************************************
  26. ** **
  27. ** Project: Dune Emperor **
  28. ** **
  29. ** Module: <module> (<prefix>_) **
  30. ** **
  31. ** Version: $ID$ **
  32. ** **
  33. ** File name: audevent.cpp **
  34. ** **
  35. ** Created by: 04/28/99 TR **
  36. ** **
  37. ** Description: <description> **
  38. ** **
  39. *****************************************************************************/
  40. /*****************************************************************************
  41. ** Includes **
  42. *****************************************************************************/
  43. #define _DEFINE_EVENT_TOKENS
  44. #include <stdlib.h>
  45. #include <stdio.h>
  46. #include <string.h>
  47. #include <wpaudio/altypes.h>
  48. #include <wpaudio/cache.h>
  49. #include <wpaudio/events.h>
  50. #include <wpaudio/level.h>
  51. #include <wpaudio/profiler.h>
  52. #include <wpaudio/channel.h>
  53. #include <wpaudio/device.h>
  54. #include <wpaudio/attributes.h>
  55. #include <wpaudio/handle.h>
  56. // 'assignment within condition expression'.
  57. #pragma warning(disable : 4706)
  58. DBG_DECLARE_TYPE ( AudioEventClass)
  59. DBG_DECLARE_TYPE ( AudioEvent )
  60. DBG_DECLARE_TYPE ( AudioEventHandle )
  61. /*****************************************************************************
  62. ** Externals **
  63. *****************************************************************************/
  64. /*****************************************************************************
  65. ** Defines **
  66. *****************************************************************************/
  67. #define DEBUG_EVENT_CONTENTION 0
  68. #define AUDIO_INVALID_STAMP 0
  69. #define MAX_EVENTS 100
  70. #define AVERAGE_LOUDNESS 10
  71. #define FULL_LOUDNESS 100
  72. #define VOLUME_QUANTIZE_LEVELS 10
  73. #define EVENT_MIN_DELAY 33 // milliseconds
  74. #define NUM_BUCKETS_PRI ( AUDIO_NUM_EVENT_PRIORITIES + 2 ) // Player sounds are +2!
  75. #define NUM_BUCKETS_VOL 10
  76. #define VOLUME_QUANTIZE ( AUDIO_LEVEL_MAX / NUM_BUCKETS_VOL )
  77. #define AUDIO_EVENT_DEFAULT_LIMIT 3
  78. #define ID_HANDLE ((int) &audioEventClasses)
  79. /*****************************************************************************
  80. ** Private Types **
  81. *****************************************************************************/
  82. typedef enum
  83. {
  84. AUDIO_EVENT_NEW, // event has not been serviced
  85. AUDIO_EVENT_START_PLAYING, // event is ready for playing
  86. AUDIO_EVENT_WAITING, // event is waiting
  87. AUDIO_EVENT_PLAYING, // event is playing
  88. AUDIO_EVENT_DONE // event is over
  89. } AudioEventState;
  90. struct AudioEventClassTag
  91. {
  92. ListNode nd;
  93. int valid; // TRUE if event class has been defined
  94. AudioEventControl control; // audio event control flags
  95. AudioLevel baseLevel; // base volume
  96. AudioPriority priority; // sound priority
  97. int count; // number of currently active events for this class
  98. int limit; // maximum number of active events allowed
  99. int limitLoop; // maximum iterations before looping ends (0 means never)
  100. int range; // energy level of sound
  101. int min_volume; // min volume for global event type
  102. uint minDelay; // minimum delay time (ms)
  103. uint maxDelay; // maximum delay time (ms)
  104. int minFShift; // max negative frequency shift percentage
  105. int maxFShift; // max positive frequency shift percentage
  106. int vShift; // volume shift percentage
  107. int volumeCompression;// should this event class be volume compressed
  108. AudioAttribs *fadeAttribs; // Fader to use for this event
  109. AudioAttribs *masterAttribs; // Master control to use for this event
  110. ListHead local; // local events list
  111. int lastFrame; // id of the last frame the local list was sorted
  112. uint lastBucketStamp; // id of the last frame this class was bucketed
  113. AudioPriority maxPri; // highest priority of any event of this class
  114. ListNode nodeVol; // for volume list
  115. uint maxVol; // current level of loudest event of this class
  116. // sample list
  117. char *sampleName[MAX_AUDIO_EVENT_SAMPLES];
  118. int numSamples;
  119. int attackCount;
  120. int decayCount;
  121. int morningCount;
  122. int eveningCount;
  123. int nightCount;
  124. char *name;
  125. void *data;
  126. #ifdef _DEBUG
  127. AudioFormat format; // format of last sample added;
  128. int format_same;
  129. #endif
  130. DBG_TYPE ()
  131. };
  132. //
  133. // AudioEvent
  134. //
  135. #define mAUDIO_EVENT_DEAD 0x00000001 // this event can be returned to the pool
  136. #define mAUDIO_EVENT_PLAYING 0x00000002 // playing a sample
  137. #define mAUDIO_EVENT_CHANNEL 0x00000004 // have a channel
  138. #define mAUDIO_EVENT_NO_ATTACK 0x00000008 // dont play attack sample if there is one
  139. #define mAUDIO_EVENT_NO_DECAY 0x00000010 // dont play decay sample if there is one
  140. #define mAUDIO_EVENT_END 0x00000020 // event to finish up
  141. #define mAUDIO_EVENT_DO_END 0x00000040 // end latch
  142. #define mAUDIO_EVENT_ALLOCATED 0x00000080 // struct was malloced
  143. struct AudioEventTag
  144. {
  145. ListNode nd; // global event list
  146. ListNode local; // local event list
  147. volatile int flags; // event control flags
  148. volatile AudioEventState state; // event current state
  149. volatile AudioEventState nextState; // next event state if waiting
  150. AudioEventClass *eclass; // event class info
  151. AudioCacheItem *item[MAX_AUDIO_EVENT_SAMPLES]; // audio cache item
  152. int numItems;
  153. int currentItem; // which sample of the event item list we are currently processing
  154. AudioChannel *channel; // audio channel we are playing on
  155. AudioAttribs attribs; // event playback attribs
  156. int stamp; // unique instance id
  157. volatile uint delay;
  158. volatile TimeStamp timeOut;
  159. AudioSample volatile*startSample;
  160. int fshift;
  161. int vshift;
  162. int adjustPriority; // priority modifier
  163. Lock paused;
  164. int sequence[MAX_AUDIO_EVENT_SAMPLES]; // play sequence
  165. int numSequence;
  166. int loopCount;
  167. int loadSequence[MAX_AUDIO_EVENT_SAMPLES];
  168. int numLoadSequence;
  169. int loadLoopCount;
  170. int loadNdx;
  171. int loadSaveNdx;
  172. int timeOfDay;
  173. AudioEventHandle *handle; // keep tack of handle
  174. DBG_TYPE ()
  175. };
  176. typedef struct EClassBucketTag
  177. {
  178. ListHead bucketVol[ NUM_BUCKETS_VOL ];
  179. } EClassBucket;
  180. /*****************************************************************************
  181. ** Private Data **
  182. *****************************************************************************/
  183. static ListHead audioEventClasses;
  184. static AudioCache *audioCache = NULL;
  185. static AudioDevice *audioDevice = NULL;
  186. static int initialized = FALSE;
  187. static int eventsOn = TRUE;
  188. static int eventsOK = FALSE;
  189. static ListHead audioEvents;
  190. static AudioMemoryPool *audioEventPool = NULL;
  191. static int audioStamp = AUDIO_INVALID_STAMP+1;
  192. static int frameStamp = 0;
  193. static uint bucketStamp = 0; // Never clear this!
  194. static EClassBucket eClassBucket[ NUM_BUCKETS_PRI ];
  195. static AudioAttribs audioCompressionAttribs;
  196. /*****************************************************************************
  197. ** Public Data **
  198. *****************************************************************************/
  199. int AudioEventsCount = 0;
  200. int AudioEventsPeak = 0;
  201. int AudioGameFrame = 0; // increment this every game frame
  202. /*****************************************************************************
  203. ** Private Prototypes **
  204. *****************************************************************************/
  205. static AudioChannel* audioPrepareChannel ( int pri, int flags );
  206. static int audioEventPrep ( AudioEvent *event );
  207. static int audioEventStart ( AudioEvent *event );
  208. static AudioSample* eventFirstSample ( AudioEvent *event );
  209. static AudioSample* eventNextSample ( AudioEvent *event );
  210. static void audioEventDestroy ( AudioEvent *event );
  211. static void eventUnlockSamples ( AudioEvent *event );
  212. /*****************************************************************************
  213. ** Private Functions **
  214. *****************************************************************************/
  215. /******************************************************************/
  216. /* */
  217. /* */
  218. /******************************************************************/
  219. static void audioInitEventClass ( AudioEventClass *eclass )
  220. {
  221. memset ( eclass, 0, sizeof(AudioEventClass ));
  222. ListNodeInit ( &eclass->nd );
  223. DBG_SET_TYPE ( eclass, AudioEventClass );
  224. AudioEventClassReset ( eclass );
  225. }
  226. /******************************************************************/
  227. /* */
  228. /* */
  229. /******************************************************************/
  230. static void eventAddLocalSort ( AudioEvent *new_event )
  231. {
  232. AudioEventClass *eclass;
  233. ListNode *node, *head;
  234. AudioEvent *event;
  235. uint volume, new_volume;
  236. DBG_ASSERT_TYPE ( new_event, AudioEvent );
  237. eclass = new_event->eclass;
  238. DBG_ASSERT_TYPE ( eclass, AudioEventClass );
  239. new_volume = AudioAttribsGetVolume ( &new_event->attribs );
  240. head = (ListNode*) &eclass->local;
  241. node = head->next;
  242. while ( node != head )
  243. {
  244. int dif, slack;
  245. uint baseLev;
  246. event = (AudioEvent *) ( (uint) node - ((uint) &new_event->local - (uint) new_event ));
  247. volume = AudioAttribsGetVolume ( &event->attribs );
  248. baseLev = (uint) AudioLevelGet( &eclass->baseLevel );
  249. DBG_ASSERT( volume <= baseLev );
  250. slack = baseLev / VOLUME_QUANTIZE_LEVELS;
  251. dif = (volume - new_volume);
  252. DBG_ASSERT_TYPE ( event, AudioEvent );
  253. if ( ((dif)>=0 ? dif : -dif ) < slack )
  254. {
  255. // we consider the events to be of the same volume
  256. if ( (eclass->control & AUDIO_EVENT_CTRL_INTERRUPT) )
  257. {
  258. // give new events priority over old ones
  259. if ( (event->state != AUDIO_EVENT_NEW) )
  260. {
  261. break;
  262. }
  263. }
  264. else
  265. {
  266. // give old events priority over new ones
  267. if ( (event->state == AUDIO_EVENT_NEW) )
  268. {
  269. break;
  270. }
  271. }
  272. }
  273. else if ( volume < new_volume )
  274. {
  275. break;
  276. }
  277. node = node->next;
  278. }
  279. ListNodeInit ( &new_event->local );
  280. ListNodeInsert ( node, &new_event->local );
  281. eclass->count++;
  282. if ( eclass->limit && (eclass->count > eclass->limit) )
  283. {
  284. event = (AudioEvent *) ( (uint) head->prev - ((uint) &new_event->local - (uint) new_event ));
  285. ListNodeRemove ( &event->local );
  286. AudioEventKill ( event );
  287. eclass->count--;
  288. DBG_ASSERT ( eclass->count == eclass->limit );
  289. }
  290. }
  291. /******************************************************************/
  292. /* */
  293. /* */
  294. /******************************************************************/
  295. static void eventWait ( AudioEvent *event, TimeStamp delay, AudioEventState nextState )
  296. {
  297. DBG_ASSERT_TYPE ( event, AudioEvent );
  298. event->nextState = nextState;
  299. if ( AudioEventIsPaused ( event ))
  300. {
  301. event->timeOut = delay;
  302. }
  303. else
  304. {
  305. event->timeOut = AudioGetTime() + delay;
  306. }
  307. event->state = AUDIO_EVENT_WAITING;
  308. }
  309. /******************************************************************/
  310. /* */
  311. /* */
  312. /******************************************************************/
  313. static AudioSample* eventFirstSample ( AudioEvent *event )
  314. {
  315. int j=0;
  316. int i;
  317. DBG_ASSERT_TYPE ( event, AudioEvent );
  318. if ( (event->numSequence = event->numItems) == 0 || event->flags & mAUDIO_EVENT_END )
  319. {
  320. return NULL;
  321. }
  322. if ( event->eclass->minDelay < EVENT_MIN_DELAY )
  323. {
  324. if ( event->eclass->control & AUDIO_EVENT_CTRL_ATTACK )
  325. {
  326. j++;
  327. event->numSequence--;
  328. event->currentItem = 0;
  329. }
  330. else
  331. {
  332. event->currentItem = -1;
  333. }
  334. if ( event->eclass->control & AUDIO_EVENT_CTRL_DECAY )
  335. {
  336. event->numSequence--;
  337. }
  338. if ( event->numSequence <= 0 )
  339. {
  340. event->eclass->valid = FALSE;
  341. return NULL;
  342. }
  343. for ( i=0 ; i < event->numSequence; i++, j++ )
  344. {
  345. event->sequence[ i ] = j;
  346. }
  347. if ( event->flags & mAUDIO_EVENT_NO_ATTACK || !(event->eclass->control & AUDIO_EVENT_CTRL_ATTACK) )
  348. {
  349. return eventNextSample ( event );
  350. }
  351. }
  352. return AudioCacheItemSample ( event->item[0] );
  353. }
  354. /******************************************************************/
  355. /* */
  356. /* */
  357. /******************************************************************/
  358. static AudioSample* eventNextSample ( AudioEvent *event )
  359. {
  360. int i;
  361. AudioEventControl control;
  362. DBG_ASSERT_TYPE ( event, AudioEvent );
  363. control = event->eclass->control;
  364. if ( event->eclass->minDelay >= EVENT_MIN_DELAY && !(event->flags & mAUDIO_EVENT_END) )
  365. {
  366. return NULL;
  367. }
  368. if ( event->numSequence == 0 || event->flags & mAUDIO_EVENT_END )
  369. {
  370. // end of sequence
  371. if ( control & AUDIO_EVENT_CTRL_LOOP && !(event->flags & mAUDIO_EVENT_END))
  372. {
  373. if ( !event->eclass->limitLoop || (event->loopCount < event->eclass->limitLoop - 1) )
  374. {
  375. event->loopCount++;
  376. return eventFirstSample ( event ); // begin again
  377. }
  378. }
  379. // the end
  380. if ( (!(event->eclass->control & AUDIO_EVENT_CTRL_DECAY) || event->flags & mAUDIO_EVENT_NO_DECAY)
  381. || event->numItems < 1 )
  382. {
  383. return NULL;
  384. }
  385. FLAGS_SET ( event->flags , mAUDIO_EVENT_NO_DECAY ); // only want the decay to play once
  386. return AudioCacheItemSample ( event->item[event->numItems-1] );
  387. }
  388. // choose the nex sample to play
  389. if ( control & AUDIO_EVENT_CTRL_RANDOM )
  390. {
  391. int ndx;
  392. ndx = AudioRandomPick( 0, event->numSequence -1 );
  393. event->currentItem =event->sequence[ndx];
  394. // remove from sequence
  395. for ( i=ndx; i < event->numSequence -1 ; i++)
  396. {
  397. event->sequence[i] = event->sequence[i+1];
  398. }
  399. }
  400. else
  401. {
  402. event->currentItem++;
  403. }
  404. event->numSequence--;
  405. return AudioCacheItemSample ( event->item[event->currentItem] );
  406. }
  407. /******************************************************************/
  408. /* */
  409. /* */
  410. /******************************************************************/
  411. static int todAdjustStart( AudioEvent *event )
  412. {
  413. int afternoonCount = AudioEventClassNumSound(event->eclass) - (event->eclass->morningCount + event->eclass->eveningCount + event->eclass->nightCount + event->eclass->attackCount + event->eclass->decayCount);
  414. if (event->timeOfDay == 1) {
  415. // morning
  416. return 0;
  417. }
  418. if (event->timeOfDay == 2) {
  419. // afternoon
  420. return event->eclass->morningCount;
  421. }
  422. if (event->timeOfDay == 3) {
  423. // evening
  424. if (event->eclass->eveningCount != 0) {
  425. return event->eclass->morningCount + afternoonCount;
  426. }
  427. }
  428. if (event->timeOfDay == 4) {
  429. // night
  430. if (event->eclass->nightCount != 0) {
  431. return event->eclass->morningCount + afternoonCount + event->eclass->eveningCount;
  432. }
  433. }
  434. // default to returning the afternoon sounds
  435. return event->eclass->morningCount;
  436. }
  437. /******************************************************************/
  438. /* */
  439. /* */
  440. /******************************************************************/
  441. static int todAdjustEnd( AudioEvent *event )
  442. {
  443. int afternoonCount = AudioEventClassNumSound(event->eclass) - (event->eclass->morningCount + event->eclass->eveningCount + event->eclass->nightCount + event->eclass->attackCount + event->eclass->decayCount);
  444. if (event->timeOfDay == 1) {
  445. // morning
  446. if (event->eclass->morningCount != 0) {
  447. return afternoonCount + event->eclass->eveningCount + event->eclass->nightCount;
  448. }
  449. }
  450. if (event->timeOfDay == 2) {
  451. // afternoon
  452. return event->eclass->eveningCount + event->eclass->nightCount;
  453. }
  454. if (event->timeOfDay == 3) {
  455. // evening
  456. if (event->eclass->eveningCount != 0) {
  457. return event->eclass->nightCount;
  458. }
  459. }
  460. if (event->timeOfDay == 4) {
  461. // night
  462. if (event->eclass->nightCount != 0) {
  463. return 0;
  464. }
  465. }
  466. // default to returning the afternoon sounds
  467. return event->eclass->eveningCount + event->eclass->nightCount;
  468. }
  469. /******************************************************************/
  470. /* */
  471. /* */
  472. /******************************************************************/
  473. static int eventLoadSchedule( AudioEvent *event )
  474. {
  475. AudioEventClass *eclass;
  476. AudioEventControl control;
  477. int i;
  478. int item_ndx;
  479. eclass = event->eclass;
  480. control = eclass->control;
  481. if ( event->numLoadSequence == event->loadNdx )
  482. {
  483. int ndx = 0;
  484. if ( (!(eclass->control & AUDIO_EVENT_CTRL_LOOP) && event->loadLoopCount == 1 )
  485. || ((eclass->control & AUDIO_EVENT_CTRL_LOOP) && eclass->limitLoop && (event->loadLoopCount) >= eclass->limitLoop ))
  486. {
  487. return -1; // sequence is finished
  488. }
  489. // Time to create a new schedule.
  490. if ( eclass->attackCount && !(event->flags & mAUDIO_EVENT_NO_ATTACK))
  491. {
  492. event->loadSequence[ndx++] = AudioRandomPick ( 0, eclass->attackCount-1);
  493. }
  494. if ( eclass->control & AUDIO_EVENT_CTRL_ALL )
  495. {
  496. for ( i = eclass->attackCount + todAdjustStart(event); i < eclass->numSamples - (eclass->decayCount + todAdjustEnd(event)); i++ )
  497. {
  498. event->loadSequence[ ndx++ ] = i;
  499. }
  500. }
  501. else if ( eclass->control & AUDIO_EVENT_CTRL_RANDOM )
  502. {
  503. if ( event->loadLoopCount == 0 )
  504. {
  505. i = AudioRandomPick ( eclass->attackCount + todAdjustStart(event), eclass->numSamples - (eclass->decayCount + todAdjustEnd(event) + 1));
  506. event->loadSaveNdx = i;
  507. }
  508. else
  509. {
  510. i = event->loadSaveNdx;
  511. }
  512. event->loadSequence[ ndx++ ] = i;
  513. }
  514. else
  515. {
  516. event->loadSequence[ ndx++ ] = eclass->attackCount;
  517. }
  518. event->numLoadSequence = ndx;
  519. event->loadNdx = 0;
  520. event->loadLoopCount++;
  521. }
  522. // carry out the existing schedule
  523. if ( control & AUDIO_EVENT_CTRL_RANDOM &&
  524. ( (!eclass->attackCount || (event->flags & mAUDIO_EVENT_NO_ATTACK)) || event->loadNdx > 0 ))
  525. {
  526. int ndx, currentSampleIndex;
  527. ndx = AudioRandomPick( (!eclass->attackCount || (event->flags & mAUDIO_EVENT_NO_ATTACK)) ? 0 : 1, event->numLoadSequence - 1 );
  528. item_ndx = currentSampleIndex = event->loadSequence[ ndx ];
  529. // remove from sequence
  530. for ( i = ndx; i < event->numLoadSequence - 1; i++ )
  531. {
  532. event->loadSequence[ i ] = event->loadSequence[ i + 1 ];
  533. }
  534. event->numLoadSequence--;
  535. }
  536. else
  537. {
  538. item_ndx = event->loadSequence[ event->loadNdx ];
  539. event->loadNdx++;
  540. }
  541. return item_ndx;
  542. }
  543. /******************************************************************/
  544. /* */
  545. /* */
  546. /******************************************************************/
  547. static void eventLoadItem( AudioEvent *event, int sampleIndex )
  548. {
  549. if ( event->item[ event->numItems ]
  550. = AudioCacheLoadItem( audioCache, event->eclass->sampleName[ sampleIndex ] ) )
  551. {
  552. AudioCacheItemLock( event->item[ event->numItems ] );
  553. event->numItems++;
  554. }
  555. #if DEBUG_EVENT_CONTENTION
  556. else
  557. {
  558. if ( event->channel->Control.Priority >= AUDIO_EVENT_CRITICAL_PRIORITY )
  559. {
  560. DBGPRINTF(( "eventLoadItem: '%s' could not load critical sample.\n", AudioEventName ( event ) ));
  561. }
  562. }
  563. #endif
  564. }
  565. /******************************************************************/
  566. /* */
  567. /* */
  568. /******************************************************************/
  569. static void eventLoadAndLockSamples ( AudioEvent *event )
  570. {
  571. int i, ndx;
  572. AudioEventControl control;
  573. AudioEventClass *eclass;
  574. DBG_ASSERT_TYPE ( event, AudioEvent );
  575. control = event->eclass->control;
  576. eclass = event->eclass;
  577. DBG_ASSERT_TYPE ( eclass, AudioEventClass );
  578. // This function will get called repeatedly for events with delay,
  579. // because these events re-enter state EVENT_START_PLAYING.
  580. // We need to load only the sample that's about to be used.
  581. if ( event->numItems )
  582. {
  583. if ( eclass->minDelay >= EVENT_MIN_DELAY )
  584. {
  585. eventUnlockSamples( event );
  586. }
  587. else
  588. {
  589. /// @todo, workout what this comment means
  590. // Shouldn't happen, but if it does, we're protected from
  591. // gobbling cache permanently by forgetting our old load...
  592. DBGPRINTF(( "eventLoadAndLockSamples: You are not reading this.\n" ));
  593. return;
  594. }
  595. }
  596. if ( eclass->minDelay < EVENT_MIN_DELAY )
  597. {
  598. // we are going to be using all samples
  599. if ( eclass->attackCount )
  600. {
  601. eventLoadItem ( event, AudioRandomPick ( 0, eclass->attackCount -1 ));
  602. }
  603. if ( eclass->control & AUDIO_EVENT_CTRL_ALL )
  604. {
  605. for ( i=eclass->attackCount + todAdjustStart(event); i < eclass->numSamples - (eclass->decayCount + todAdjustEnd(event)); i++ )
  606. {
  607. eventLoadItem( event, i );
  608. }
  609. }
  610. else if ( eclass->control & AUDIO_EVENT_CTRL_RANDOM )
  611. {
  612. i = AudioRandomPick ( eclass->attackCount + todAdjustStart(event), eclass->numSamples - (eclass->decayCount + todAdjustEnd(event) + 1) );
  613. eventLoadItem( event, i );
  614. }
  615. else
  616. {
  617. eventLoadItem( event, eclass->attackCount );
  618. }
  619. if ( eclass->decayCount )
  620. {
  621. eventLoadItem ( event, AudioRandomPick ( eclass->numSamples - eclass->decayCount, eclass->numSamples -1 ));
  622. }
  623. }
  624. else
  625. {
  626. int decay_ndx = -1;
  627. if ( eclass->decayCount && eclass->control & AUDIO_EVENT_CTRL_DECAY )
  628. {
  629. decay_ndx = AudioRandomPick ( eclass->numSamples - eclass->decayCount, eclass->numSamples-1);
  630. }
  631. // This event has delay. Load only the sample about to be used.
  632. // Note: we will leave the existing scheduling mechanism in place.
  633. // With only one sample loaded, however, it will have no decisions
  634. // to make. We will decide the true schedule in the function below.
  635. if ( (ndx = eventLoadSchedule( event )) >= 0 )
  636. {
  637. eventLoadItem( event, ndx );
  638. if ( decay_ndx != -1 )
  639. {
  640. eventLoadItem( event, decay_ndx ); // add it incase it is needed
  641. }
  642. }
  643. else
  644. {
  645. // end of sequence, must play decay if needed
  646. if ( decay_ndx != -1 && !(event->flags & mAUDIO_EVENT_NO_DECAY))
  647. {
  648. eventLoadItem( event, decay_ndx );
  649. FLAGS_SET ( event->flags, mAUDIO_EVENT_NO_DECAY );
  650. }
  651. }
  652. }
  653. }
  654. /******************************************************************/
  655. /* */
  656. /* */
  657. /******************************************************************/
  658. static void eventUnlockSamples ( AudioEvent *event )
  659. {
  660. int i;
  661. DBG_ASSERT_TYPE ( event, AudioEvent );
  662. for ( i=0; i < event->numItems; i++ )
  663. {
  664. AudioCacheItemUnlock ( event->item[i] );
  665. event->item[i] = NULL;
  666. }
  667. event->numItems = 0;
  668. }
  669. /******************************************************************/
  670. /* */
  671. /* */
  672. /******************************************************************/
  673. static void eventReleaseChannel ( AudioEvent *event )
  674. {
  675. DBG_ASSERT_TYPE ( event, AudioEvent );
  676. if ( event->channel && (event == (AudioEvent *) event->channel->Data) )
  677. {
  678. if ( event->flags & mAUDIO_EVENT_PLAYING )
  679. {
  680. AudioChannelStop ( event->channel );
  681. DBG_ASSERT ( !(event->flags & mAUDIO_EVENT_PLAYING) );
  682. }
  683. AudioChannelNoUse ( event->channel );
  684. event->channel->Data = NULL;
  685. event->channel->CB_Stop = NULL;
  686. event->channel->CB_NextSample = NULL;
  687. event->channel->CB_SampleDone = NULL;
  688. event->channel->SfxAttribs = NULL;
  689. event->channel->CompAttribs = NULL;
  690. event->channel->FadeAttribs = NULL;
  691. event->channel = NULL;
  692. }
  693. }
  694. /******************************************************************/
  695. /* */
  696. /* */
  697. /******************************************************************/
  698. static int audioEventStop ( AudioChannel *chan )
  699. {
  700. AudioEvent *event = (AudioEvent *) chan->Data;
  701. DBG_ASSERT_TYPE ( event, AudioEvent );
  702. event->state = AUDIO_EVENT_DONE;
  703. return vNO_ERROR;
  704. }
  705. /******************************************************************/
  706. /* */
  707. /* */
  708. /******************************************************************/
  709. static void audioEventDestroy ( AudioEvent *event )
  710. {
  711. DBG_ASSERT_TYPE ( event, AudioEvent );
  712. DBG_MSGASSERT ( event->flags & mAUDIO_EVENT_DEAD, ("trying to destroy an event that is not dead"));
  713. ListNodeRemove ( &event->nd );
  714. event->stamp = AUDIO_INVALID_STAMP;
  715. DBG_INVALIDATE_TYPE ( event );
  716. if ( event->flags & mAUDIO_EVENT_ALLOCATED )
  717. {
  718. MEM_Free (event);
  719. }
  720. else
  721. {
  722. MemoryPoolReturnItem ( audioEventPool, event );
  723. }
  724. AudioEventsCount--;
  725. }
  726. /******************************************************************/
  727. /* */
  728. /* */
  729. /******************************************************************/
  730. static int audioEventSampleDone ( AudioChannel *chan )
  731. {
  732. AudioEvent *event = (AudioEvent *) chan->Data;
  733. AudioEventState new_state;
  734. DBG_ASSERT_TYPE ( event, AudioEvent );
  735. FLAGS_CLEAR ( event->flags, mAUDIO_EVENT_PLAYING );
  736. if ( event->state == AUDIO_EVENT_DONE )
  737. {
  738. return vNO_ERROR;
  739. }
  740. if ( event->startSample // If EVENT_CTRL_LOOP, preceding will be true even if load-sequenced
  741. || event->numLoadSequence || event->delay )
  742. {
  743. new_state = AUDIO_EVENT_START_PLAYING;
  744. }
  745. else
  746. {
  747. new_state = AUDIO_EVENT_DONE ;
  748. event->delay = 0;
  749. }
  750. if ( event->delay )
  751. {
  752. eventWait ( event, MSECONDS (event->delay), new_state );
  753. event->delay = 0;
  754. }
  755. else
  756. {
  757. event->state = new_state;
  758. }
  759. return vNO_ERROR;
  760. }
  761. /******************************************************************/
  762. /* */
  763. /* */
  764. /******************************************************************/
  765. static int audioEventNextSample ( AudioChannel *chan )
  766. {
  767. AudioEvent *event = (AudioEvent *) chan->Data;
  768. AudioSample *sample;
  769. uint delay;
  770. sample = eventNextSample ( event );
  771. if ( event->eclass->maxDelay < EVENT_MIN_DELAY )
  772. {
  773. // There is no delay
  774. AudioChannelSetSample ( chan, sample );
  775. return vNO_ERROR;
  776. }
  777. // There is a delay value. However see if it applies to this sample
  778. if ( sample )
  779. {
  780. // because there is a next sample we are in the middle of a event sequence.
  781. // We only delay samples within the sequence if it is ambient
  782. if ( !(event->eclass->control & (AUDIO_EVENT_CTRL_AMBIENT)) )
  783. {
  784. // this is not an ambient seqeuence so no delay
  785. AudioChannelSetSample ( chan, sample );
  786. return vNO_ERROR;
  787. }
  788. }
  789. else
  790. {
  791. // There is no next sample so we are at the end of the sequence
  792. // If this is NOT a postdelay event the don't delay
  793. if ( !(event->eclass->control & (AUDIO_EVENT_CTRL_POSTDELAY)) )
  794. {
  795. AudioChannelSetSample ( chan, NULL );
  796. return vNO_ERROR;
  797. }
  798. }
  799. // we are required to wait before going on to the next sample
  800. AudioChannelSetSample ( chan, NULL );
  801. delay = (uint) AudioRandomPick ( event->eclass->minDelay, event->eclass->maxDelay );
  802. if ( delay < EVENT_MIN_DELAY )
  803. {
  804. AudioChannelSetSample ( chan, sample );
  805. return vNO_ERROR;
  806. }
  807. event->delay = delay;
  808. event->startSample = sample;
  809. return vNO_ERROR;
  810. }
  811. /******************************************************************/
  812. /* */
  813. /* */
  814. /******************************************************************/
  815. //
  816. // We use buckets to sort event classes by priority and volume.
  817. // This is a new frame. Forget all previous sorting information.
  818. //
  819. static void bucketReset( void )
  820. {
  821. int i, k;
  822. EClassBucket *ecb;
  823. for ( i = 0, ecb = eClassBucket; i < NUM_BUCKETS_PRI; i++, ecb++ )
  824. {
  825. for ( k = 0; k < NUM_BUCKETS_VOL; k++ )
  826. {
  827. ListInit( &ecb->bucketVol[ k ] );
  828. }
  829. }
  830. bucketStamp++;
  831. }
  832. /******************************************************************/
  833. /* */
  834. /* */
  835. /******************************************************************/
  836. //
  837. // Place this event into buckets according to priority and volume.
  838. // This will be used to choose event classes for sacrifice.
  839. //
  840. static void bucketAdd( AudioEvent *event )
  841. {
  842. EClassBucket *ecb;
  843. AudioEventClass *eclass;
  844. AudioPriority pri;
  845. uint vol;
  846. eclass = event->eclass;
  847. pri = (AudioPriority) ((uint) eclass->priority + (uint) event->adjustPriority);
  848. DBG_ASSERT( pri < NUM_BUCKETS_PRI );
  849. vol = AudioAttribsGetVolume( &event->attribs ) / VOLUME_QUANTIZE;
  850. ecb = &eClassBucket[ pri ];
  851. if ( eclass->lastBucketStamp == bucketStamp )
  852. {
  853. // Already in buckets. Check if re-sorting necessary.
  854. if ( pri > eclass->maxPri )
  855. {
  856. eclass->maxPri = pri;
  857. eclass->maxVol = vol;
  858. // Remove and re-insert.
  859. ListNodeRemove( &eclass->nodeVol );
  860. ListNodeInsert( &ecb->bucketVol[ vol ], &eclass->nodeVol );
  861. }
  862. else if ( pri == eclass->maxPri )
  863. {
  864. if ( vol > eclass->maxVol )
  865. {
  866. eclass->maxVol = vol;
  867. // Remove and re-insert.
  868. ListNodeRemove( &eclass->nodeVol );
  869. ListNodeInsert( &ecb->bucketVol[ vol ], &eclass->nodeVol );
  870. }
  871. }
  872. }
  873. else
  874. {
  875. // First use this frame. Initialize and put in buckets.
  876. eclass->lastBucketStamp = bucketStamp;
  877. eclass->maxPri = pri;
  878. eclass->maxVol = vol;
  879. ListNodeInit( &eclass->nodeVol );
  880. ListNodeInsert( &ecb->bucketVol[ vol ], &eclass->nodeVol );
  881. }
  882. }
  883. /******************************************************************/
  884. /* */
  885. /* */
  886. /******************************************************************/
  887. static void bucketRemove( AudioEventClass *eclass )
  888. {
  889. ListNodeRemove( &eclass->nodeVol );
  890. }
  891. /******************************************************************/
  892. /* */
  893. /* */
  894. /******************************************************************/
  895. //
  896. // Get a "weaker" event class from the buckets. It must have
  897. // lower priority than 'pri'. Find the quietest such class.
  898. //
  899. static AudioEventClass *bucketGetWeaker( AudioPriority pri )
  900. {
  901. EClassBucket *ecb;
  902. ListNode *node;
  903. int i, v;
  904. for ( i = 0, ecb = eClassBucket; i < pri; i++, ecb++ )
  905. {
  906. for ( v = 0; v < NUM_BUCKETS_VOL; v++ )
  907. {
  908. node = ListFirstItem( &ecb->bucketVol[ v ] );
  909. if ( node )
  910. {
  911. AudioEventClass *event = (AudioEventClass*) node;
  912. event = (AudioEventClass*) ( (uint) event - ( (uint) &event->nodeVol - (uint) event ));
  913. return event;
  914. }
  915. }
  916. }
  917. return NULL;
  918. }
  919. /******************************************************************/
  920. /* */
  921. /* */
  922. /******************************************************************/
  923. //
  924. // Destroy an entire class of events to make room for newEvent.
  925. // Returns TRUE if any events were killed, FALSE otherwise.
  926. //
  927. static int eventClassSacrifice( AudioEvent *newEvent )
  928. {
  929. AudioEvent *event, *next, *head;
  930. AudioEventClass *eclassSacrifice = NULL;
  931. int killed = FALSE;
  932. eclassSacrifice = bucketGetWeaker( (AudioPriority) ( (uint) newEvent->eclass->priority
  933. + (uint) newEvent->adjustPriority) );
  934. if ( eclassSacrifice == NULL )
  935. {
  936. return FALSE;
  937. }
  938. #if DEBUG_EVENT_CONTENTION
  939. DBGPRINTF(( "eventClassSacrifice: class '%s' killed by class '%s'.\n",
  940. AudioEventClassName (eclassSacrifice), AudioEventName ( newEvent)));
  941. #endif
  942. bucketRemove( eclassSacrifice );
  943. head = (AudioEvent *) &audioEvents;
  944. event = (AudioEvent *) head->nd.next;
  945. while ( event != head )
  946. {
  947. next = (AudioEvent *) event->nd.next;
  948. if ( event->eclass == eclassSacrifice )
  949. {
  950. AudioEventKill( event );
  951. audioEventDestroy( event );
  952. killed = TRUE;
  953. }
  954. event = next;
  955. }
  956. return killed; // Technically, if we get here, should always be TRUE.
  957. }
  958. /******************************************************************/
  959. /* */
  960. /* */
  961. /******************************************************************/
  962. static AudioChannel* audioPrepareChannel ( int pri, int flags )
  963. {
  964. AudioChannel *chan = NULL;
  965. if ( audioDevice && ( chan = AudioDeviceGetChannel( audioDevice, AUDIO_CHANNEL_TYPE_STD )))
  966. {
  967. if ( !(chan->Control.Status & (mAUDIO_CTRL_PLAYING|mAUDIO_CTRL_PAUSED|mAUDIO_CTRL_INUSE) ) || chan->Control.Priority <= pri )
  968. {
  969. #ifdef _DEBUGx
  970. if (chan->Control.Status & (mAUDIO_CTRL_PLAYING|mAUDIO_CTRL_PAUSED|mAUDIO_CTRL_INUSE) )
  971. {
  972. DBGPRINTF (("Stealing channel 0x%08x\n", chan));
  973. }
  974. #endif
  975. AudioChannelStop ( chan );
  976. chan->Control.Priority = pri;
  977. if (flags & mAUDIO_LOOP )
  978. {
  979. chan->Control.LoopCount = AUDIO_CTRL_LOOP_FOREVER;
  980. }
  981. else
  982. {
  983. chan->Control.LoopCount = 0;
  984. }
  985. }
  986. else
  987. {
  988. goto error;
  989. }
  990. }
  991. #if 0
  992. else
  993. {
  994. DBGPRINTF(( "Could not get a channel\n" ));
  995. }
  996. #endif
  997. return chan;
  998. error:
  999. return NULL;
  1000. }
  1001. /******************************************************************/
  1002. /* */
  1003. /* */
  1004. /******************************************************************/
  1005. static int audioEventPrep ( AudioEvent *event )
  1006. {
  1007. AudioEventClass *eclass;
  1008. DBG_ASSERT_TYPE ( event, AudioEvent );
  1009. eclass = event->eclass;
  1010. DBG_ASSERT_TYPE ( eclass, AudioEventClass );
  1011. if ( eclass->numSamples == 0 || !eclass->valid)
  1012. {
  1013. return FALSE;
  1014. }
  1015. event->loopCount = 0;
  1016. if ( !(event->channel = audioPrepareChannel ( eclass->priority + event->adjustPriority, 0 ) ))
  1017. {
  1018. return FALSE;
  1019. }
  1020. event->fshift = 100 + AudioRandomPick( eclass->minFShift, eclass->maxFShift );
  1021. event->vshift = AudioRandomPick( 0, eclass->vShift );
  1022. AudioChannelUse ( event->channel );
  1023. event->channel->Data = event;
  1024. event->channel->CB_NextSample = audioEventNextSample;
  1025. event->channel->CB_SampleDone = audioEventSampleDone;
  1026. event->channel->CB_Stop = audioEventStop;
  1027. event->state = AUDIO_EVENT_START_PLAYING;
  1028. event->channel->SfxAttribs = &event->attribs;
  1029. event->channel->CompAttribs = eclass->volumeCompression ? &audioCompressionAttribs : NULL ;
  1030. event->channel->FadeAttribs = eclass->fadeAttribs;
  1031. event->channel->GroupAttribs = eclass->masterAttribs;
  1032. if ( eclass->maxDelay > EVENT_MIN_DELAY )
  1033. {
  1034. if ( !(eclass->control & (AUDIO_EVENT_CTRL_POSTDELAY)))
  1035. {
  1036. int delay;
  1037. delay = AudioRandomPick( (eclass->control&AUDIO_EVENT_CTRL_AMBIENT) ? EVENT_MIN_DELAY : eclass->minDelay, eclass->maxDelay );
  1038. if ( delay >= EVENT_MIN_DELAY )
  1039. {
  1040. eventWait ( event, MSECONDS(delay), AUDIO_EVENT_START_PLAYING );
  1041. }
  1042. }
  1043. }
  1044. // NOTE: we do not actually start the event playing
  1045. return TRUE;
  1046. }
  1047. /******************************************************************/
  1048. /* */
  1049. /* */
  1050. /******************************************************************/
  1051. static int audioEventStart ( AudioEvent *event )
  1052. {
  1053. AudioSample *sample;
  1054. DBG_ASSERT_TYPE ( event, AudioEvent );
  1055. DBG_MSGASSERT ( event->state == AUDIO_EVENT_START_PLAYING, ("event in a bad state"));
  1056. DBG_MSGASSERT ( !AudioEventIsPaused(event), ("trying to start a paused event"));
  1057. if ( event != (AudioEvent *)event->channel->Data )
  1058. {
  1059. // channel was stolen;
  1060. return FALSE;
  1061. }
  1062. // IMPORTANT: set state to playing before starting the channel
  1063. // It is possible that the channel could finish before we get to set the
  1064. // new state.
  1065. AudioChannelLock ( event->channel );
  1066. msg_assert ( !(event->channel->Control.Status & mAUDIO_CTRL_ACTIVE ), ("bad assert. Show this to Tommy immediately!!"));
  1067. sample = (AudioSample *) event->startSample;
  1068. FLAGS_SET ( event->flags, mAUDIO_EVENT_NO_ATTACK );
  1069. AudioChannelSetSample ( event->channel, sample );
  1070. AudioChannelSetPitch ( event->channel, event->fshift );
  1071. int volume = AUDIO_LEVEL_MAX;
  1072. if ( event->vshift > 0 )
  1073. {
  1074. volume -= (AUDIO_LEVEL_MAX * event->vshift)/100;
  1075. }
  1076. AudioChannelSetVolume ( event->channel, volume );
  1077. event->state = AUDIO_EVENT_PLAYING;
  1078. FLAGS_SET ( event->flags, mAUDIO_EVENT_PLAYING );
  1079. event->startSample = NULL;
  1080. if ( AudioChannelStart ( event->channel ) != vNO_ERROR )
  1081. {
  1082. event->state = AUDIO_EVENT_START_PLAYING;
  1083. event->startSample = sample;
  1084. FLAGS_CLEAR ( event->flags, mAUDIO_EVENT_PLAYING );
  1085. AudioChannelUnlock ( event->channel );
  1086. return FALSE;
  1087. }
  1088. AudioChannelUnlock ( event->channel );
  1089. return TRUE;
  1090. }
  1091. /******************************************************************/
  1092. /* */
  1093. /* */
  1094. /******************************************************************/
  1095. static uint eventCalcVolume ( AudioEvent *event, int new_volume )
  1096. {
  1097. uint volume;
  1098. DBG_ASSERT_TYPE ( event, AudioEvent );
  1099. DBG_ASSERT_TYPE ( event->eclass, AudioEventClass );
  1100. if ( new_volume > AUDIO_VOLUME_MAX )
  1101. {
  1102. new_volume = AUDIO_VOLUME_MAX;
  1103. }
  1104. else if ( new_volume < AUDIO_VOLUME_MIN )
  1105. {
  1106. new_volume = AUDIO_VOLUME_MIN;
  1107. }
  1108. volume = AudioLevelApply( &event->eclass->baseLevel, new_volume );
  1109. return volume;
  1110. }
  1111. /*****************************************************************************
  1112. ** Public Functions **
  1113. *****************************************************************************/
  1114. /******************************************************************/
  1115. /* */
  1116. /* */
  1117. /******************************************************************/
  1118. int AudioEventSetUp( AudioDevice *device, AudioCache *cache )
  1119. {
  1120. ListInit ( &audioEvents );
  1121. ListInit ( &audioEventClasses );
  1122. audioDevice = device;
  1123. AudioAttribsInit ( &audioCompressionAttribs );
  1124. AudioEventsCount = AudioEventsPeak = 0;
  1125. initialized = TRUE;
  1126. eventsOn = TRUE;
  1127. eventsOK = FALSE;
  1128. audioCache = cache;
  1129. if ( !audioCache || !audioDevice )
  1130. {
  1131. return FALSE;
  1132. }
  1133. audioEventPool = MemoryPoolCreate ( MAX_EVENTS, sizeof ( AudioEvent ) );
  1134. DBGPRINTF (( "event mempool size = %d\n", MAX_EVENTS * sizeof (AudioEvent )));
  1135. eventsOK = audioEventPool != NULL;
  1136. return TRUE;
  1137. }
  1138. /******************************************************************/
  1139. /* */
  1140. /* */
  1141. /******************************************************************/
  1142. void AudioEventCloseDown( void )
  1143. {
  1144. AudioEventClass *eclass;
  1145. AudioKillAllEvents ( );
  1146. AudioFlushAllDeadEvents ();
  1147. while ( eclass = (AudioEventClass *) ListFirstItem ( &audioEventClasses ))
  1148. {
  1149. ListNodeRemove ( &eclass->nd );
  1150. for( Int i = 0 ; i < MAX_AUDIO_EVENT_SAMPLES; i++ )
  1151. {
  1152. if ( eclass->sampleName[i] )
  1153. {
  1154. // allocated with strdup
  1155. free( eclass->sampleName[i] );
  1156. }
  1157. }
  1158. MEM_Free ( eclass );
  1159. }
  1160. if ( audioCache )
  1161. {
  1162. audioCache = NULL;
  1163. }
  1164. if ( audioEventPool )
  1165. {
  1166. MemoryPoolDestroy ( audioEventPool );
  1167. audioEventPool = NULL;
  1168. }
  1169. eventsOK = FALSE;
  1170. initialized = FALSE;
  1171. }
  1172. /******************************************************************/
  1173. /* */
  1174. /* */
  1175. /******************************************************************/
  1176. void AudioServiceAllEvents ( void )
  1177. {
  1178. static int in = FALSE;
  1179. AudioEvent *event, *next, *head;
  1180. int loudness;
  1181. int activeEvents = 0;
  1182. int prepedEvents = 0;
  1183. int processedEvents = 0;
  1184. if ( !initialized || in )
  1185. {
  1186. return;
  1187. }
  1188. in = TRUE;
  1189. #ifndef IG_FINAL_RELEASE
  1190. {
  1191. static int lastFrame = 0;
  1192. if ( lastFrame != AudioGameFrame )
  1193. {
  1194. if ( audioCache )
  1195. {
  1196. ProfCacheNewFrame ( &audioCache->profile );
  1197. }
  1198. lastFrame = AudioGameFrame;
  1199. }
  1200. }
  1201. #endif
  1202. frameStamp++; // new frame
  1203. // because of volume compression we require two passes
  1204. // because of channel stealing we require three passes
  1205. // because of event culling we require four passes
  1206. head = (AudioEvent *) &audioEvents;
  1207. // FIRST PASS: sort events locally by volume
  1208. event = (AudioEvent *) head->nd.next;
  1209. while ( event != head )
  1210. {
  1211. DBG_ASSERT_TYPE ( event, AudioEvent );
  1212. DBG_ASSERT_TYPE ( event->eclass, AudioEventClass );
  1213. if ( event->eclass->lastFrame != frameStamp )
  1214. {
  1215. // reset local list
  1216. ListInit ( &event->eclass->local);
  1217. event->eclass->count = 0;
  1218. event->eclass->lastFrame = frameStamp;
  1219. }
  1220. AudioAttribsUpdate ( &event->attribs );
  1221. if ( event->state != AUDIO_EVENT_DONE )
  1222. {
  1223. eventAddLocalSort ( event );
  1224. }
  1225. event = (AudioEvent *) event->nd.next;
  1226. }
  1227. // SECOND PASS: service all events so that we know what
  1228. // we are required to do
  1229. event = (AudioEvent *) head->nd.next;
  1230. while ( event != head )
  1231. {
  1232. if ( event->state != AUDIO_EVENT_DONE )
  1233. {
  1234. processedEvents ++;
  1235. }
  1236. AudioEventService ( event );
  1237. event = (AudioEvent *) event->nd.next;
  1238. }
  1239. // THIRD PASS: workout the volume compression level
  1240. // and remove dead events
  1241. event = (AudioEvent *) head->nd.next;
  1242. loudness = 0;
  1243. bucketReset(); // clear our memory of what classes are in use
  1244. while ( event != head )
  1245. {
  1246. next = (AudioEvent *) event->nd.next;
  1247. if ( !event->channel
  1248. || event != (AudioEvent *) event->channel->Data )
  1249. {
  1250. #if DEBUG_EVENT_CONTENTION
  1251. {
  1252. AudioEvent thief;
  1253. if ( event->channel )
  1254. {
  1255. // Channel must have been stolen, then.
  1256. thief = (AudioEvent *) event->channel->Data;
  1257. DBGPRINTF(( "AudioServiceAllEvents: class '%s' stole channel from '%s'.\n",
  1258. AudioEventName ( thief ), AudioEventName ( event ) ));
  1259. }
  1260. }
  1261. #endif
  1262. // We have no channel. No point in going on.
  1263. AudioEventKill( event );
  1264. }
  1265. if ( event->flags & mAUDIO_EVENT_DEAD )
  1266. {
  1267. audioEventDestroy( event );
  1268. }
  1269. else
  1270. {
  1271. if ( !AudioEventIsPaused ( event ))
  1272. {
  1273. loudness += AudioLevelApply ( &event->eclass->baseLevel, AVERAGE_LOUDNESS );
  1274. }
  1275. bucketAdd( event );
  1276. }
  1277. event = next;
  1278. }
  1279. if ( loudness > FULL_LOUDNESS )
  1280. {
  1281. AudioAttribsAdjustVolume ( &audioCompressionAttribs, (AUDIO_LEVEL_MAX * FULL_LOUDNESS)/loudness );
  1282. }
  1283. else
  1284. {
  1285. AudioAttribsAdjustVolume ( &audioCompressionAttribs, AUDIO_LEVEL_MAX);
  1286. }
  1287. AudioAttribsUpdate ( &audioCompressionAttribs );
  1288. // FOURTH PASS: now that the compression level has been set
  1289. // start any events that have been preped
  1290. event = (AudioEvent *) head->nd.next;
  1291. while ( event != head )
  1292. {
  1293. next = (AudioEvent *) event->nd.next;
  1294. if ( event->state == AUDIO_EVENT_START_PLAYING && !AudioEventIsPaused( event ) )
  1295. {
  1296. eventLoadAndLockSamples ( event );
  1297. while ( !( event->startSample = eventFirstSample( event ) ) )
  1298. {
  1299. // The time for subtlety has passed. Attempt to clear
  1300. // enough cache space for this event by destroying an
  1301. // entire event class of lower priority (if any). Do
  1302. // this until our event gets into the cache.
  1303. if ( eventClassSacrifice( event ) )
  1304. {
  1305. next = (AudioEvent *) event->nd.next; // May have been killed.
  1306. eventLoadAndLockSamples ( event );
  1307. }
  1308. else
  1309. {
  1310. #if DEBUG_EVENT_CONTENTION
  1311. // We could not find an event class of lower priority.
  1312. DBGPRINTF(( "AudioServiceAllEvents: class '%s' could not get cache.\n",
  1313. AudioEventName ( event->eclass) ));
  1314. if ( event->channel->Control.Priority >= AUDIO_EVENT_CRITICAL_PRIORITY )
  1315. {
  1316. AudioEvent event2, next2, head2;
  1317. DBGPRINTF(( "Event dump -- these events are alive and own cache:\n" ));
  1318. head2 = (AudioEvent *) &audioEvents;
  1319. event2 = (AudioEvent *) head2->nd.next;
  1320. while ( event2 != head2 )
  1321. {
  1322. next2 = (AudioEvent *) event2->nd.next;
  1323. if ( event2 != event )
  1324. {
  1325. DBGPRINTF(( "- '%s'\n", AudioEventName ( event2 ) ));
  1326. }
  1327. event2 = next2;
  1328. }
  1329. }
  1330. #endif
  1331. break;
  1332. }
  1333. }
  1334. if ( !( event->startSample = eventFirstSample( event ) )
  1335. || !audioEventStart( event ) )
  1336. {
  1337. AudioEventKill ( event );
  1338. audioEventDestroy ( event );
  1339. }
  1340. else
  1341. {
  1342. activeEvents++;
  1343. }
  1344. prepedEvents++;
  1345. }
  1346. event = next;
  1347. }
  1348. // DBGPRINTF (("compression = %3d (%5d) - active events = %3d of %3d; preped = %3d\n",
  1349. // (AudioAttribsGetVolume ( &audioCompressionAttribs ) *100) /AUDIO_LEVEL_MAX,
  1350. // loudness, activeEvents, processedEvents, prepedEvents));
  1351. in = FALSE;
  1352. }
  1353. /******************************************************************/
  1354. /* */
  1355. /* */
  1356. /******************************************************************/
  1357. void AudioKillAllEvents ( void )
  1358. {
  1359. AudioEvent *event, *next, *head;
  1360. if ( !initialized )
  1361. {
  1362. return;
  1363. }
  1364. head = (AudioEvent *) &audioEvents;
  1365. event = (AudioEvent *) head->nd.next;
  1366. while ( event != head )
  1367. {
  1368. next = (AudioEvent *) event->nd.next;
  1369. AudioEventKill ( event );
  1370. audioEventDestroy ( event );
  1371. event = next;
  1372. }
  1373. }
  1374. /******************************************************************/
  1375. /* */
  1376. /* */
  1377. /******************************************************************/
  1378. void AudioPauseAllEvents ( void )
  1379. {
  1380. AudioEvent *event, *head;
  1381. if ( !initialized )
  1382. {
  1383. return;
  1384. }
  1385. head = (AudioEvent *) &audioEvents;
  1386. event = (AudioEvent *) head->nd.next;
  1387. while ( event != head )
  1388. {
  1389. AudioEventPause ( event );
  1390. event = (AudioEvent *) event->nd.next;
  1391. }
  1392. }
  1393. /******************************************************************/
  1394. /* */
  1395. /* */
  1396. /******************************************************************/
  1397. void AudioResumeAllEvents ( void )
  1398. {
  1399. AudioEvent *event, *head;
  1400. if ( !initialized )
  1401. {
  1402. return;
  1403. }
  1404. head = (AudioEvent *) &audioEvents;
  1405. event = (AudioEvent *) head->nd.next;
  1406. while ( event != head )
  1407. {
  1408. AudioEventResume ( event );
  1409. event = (AudioEvent *) event->nd.next;
  1410. }
  1411. }
  1412. /******************************************************************/
  1413. /* */
  1414. /* */
  1415. /******************************************************************/
  1416. void AudioFlushAllDeadEvents ( void )
  1417. {
  1418. AudioEvent *event, *next, *head;
  1419. if ( !initialized )
  1420. {
  1421. return;
  1422. }
  1423. head = (AudioEvent *) &audioEvents;
  1424. event = (AudioEvent *) head->nd.next;
  1425. while ( event != head )
  1426. {
  1427. next = (AudioEvent *) event->nd.next;
  1428. if ( event->flags & mAUDIO_EVENT_DEAD )
  1429. {
  1430. audioEventDestroy ( event );
  1431. }
  1432. event = next;
  1433. }
  1434. }
  1435. /******************************************************************/
  1436. /* */
  1437. /* */
  1438. /******************************************************************/
  1439. void AudioValidateAllEventClasses ( void )
  1440. {
  1441. AudioEventClass *eclass;
  1442. eclass = (AudioEventClass *) ListFirstItem ( &audioEventClasses );
  1443. while ( eclass )
  1444. {
  1445. DBG_ASSERT_TYPE ( eclass, AudioEventClass );
  1446. eclass->valid = TRUE;
  1447. eclass = (AudioEventClass *) ListNextItem ( &eclass->nd);
  1448. }
  1449. }
  1450. /******************************************************************/
  1451. /* */
  1452. /* */
  1453. /******************************************************************/
  1454. Int AudioEventCount( void )
  1455. {
  1456. return ListCountItems( &audioEventClasses );
  1457. }
  1458. /******************************************************************/
  1459. /* */
  1460. /* */
  1461. /******************************************************************/
  1462. AudioEventClass*AudioGetFirstEventClass( void )
  1463. {
  1464. return (AudioEventClass *) ListFirstItem ( &audioEventClasses );
  1465. }
  1466. /******************************************************************/
  1467. /* */
  1468. /* */
  1469. /******************************************************************/
  1470. AudioEventClass*AudioEventClassNext ( AudioEventClass *eclass )
  1471. {
  1472. if ( eclass )
  1473. {
  1474. return (AudioEventClass *) ListNextItem ( &eclass->nd);
  1475. }
  1476. return NULL;
  1477. }
  1478. /******************************************************************/
  1479. /* */
  1480. /* */
  1481. /******************************************************************/
  1482. int AudioEventClassRange ( AudioEventClass *eclass )
  1483. {
  1484. DBG_ASSERT_TYPE ( eclass, AudioEventClass );
  1485. if ( !initialized )
  1486. {
  1487. return 0;
  1488. }
  1489. return eclass->range;
  1490. }
  1491. /******************************************************************/
  1492. /* */
  1493. /* */
  1494. /******************************************************************/
  1495. int AudioEventClassMinVolume ( AudioEventClass *eclass )
  1496. {
  1497. DBG_ASSERT_TYPE ( eclass, AudioEventClass );
  1498. if ( !initialized )
  1499. {
  1500. return 0;
  1501. }
  1502. return eclass->min_volume;
  1503. }
  1504. /******************************************************************/
  1505. /* */
  1506. /* */
  1507. /******************************************************************/
  1508. int AudioEventClassValid ( AudioEventClass *eclass )
  1509. {
  1510. DBG_ASSERT_TYPE ( eclass, AudioEventClass );
  1511. if ( !initialized )
  1512. {
  1513. return FALSE;
  1514. }
  1515. return eclass->valid;
  1516. }
  1517. /******************************************************************/
  1518. /* */
  1519. /* */
  1520. /******************************************************************/
  1521. AudioEvent *AudioEventCreate ( AudioEventClass *eclass )
  1522. {
  1523. AudioEvent *event;
  1524. int allocated = FALSE;
  1525. if ( !eventsOn || !eventsOK )
  1526. {
  1527. return NULL;
  1528. }
  1529. DBG_ASSERT_TYPE ( eclass, AudioEventClass );
  1530. if ( !eclass->valid )
  1531. {
  1532. return NULL;
  1533. }
  1534. if ( !(event = (AudioEvent *) MemoryPoolGetItem ( audioEventPool )))
  1535. {
  1536. AudioFlushAllDeadEvents ( );
  1537. if ( !(event = (AudioEvent *) MemoryPoolGetItem ( audioEventPool )))
  1538. {
  1539. ALLOC_STRUCT ( event, AudioEvent);
  1540. allocated = TRUE;
  1541. if ( !event )
  1542. {
  1543. DBGPRINTF (("event pool overflow\n"));
  1544. return NULL;
  1545. }
  1546. }
  1547. }
  1548. AudioEventsCount++;
  1549. if ( AudioEventsCount > AudioEventsPeak )
  1550. {
  1551. AudioEventsPeak = AudioEventsCount;
  1552. }
  1553. // initialise the event
  1554. memset ( event, 0, sizeof ( AudioEvent ));
  1555. event->eclass = eclass;
  1556. ListNodeInit ( &event->nd );
  1557. event->state = AUDIO_EVENT_NEW;
  1558. event->adjustPriority = 0;
  1559. event->numItems = event->numSequence = event->numLoadSequence = 0;
  1560. AudioAttribsInit ( &event->attribs );
  1561. LockInit ( &event->paused );
  1562. DBG_SET_TYPE ( event, AudioEvent );
  1563. ListAddToTail ( &audioEvents, &event->nd );
  1564. event->stamp = audioStamp++;
  1565. if ( allocated )
  1566. {
  1567. FLAGS_SET ( event->flags, mAUDIO_EVENT_ALLOCATED );
  1568. }
  1569. return event;
  1570. }
  1571. /******************************************************************/
  1572. /* */
  1573. /* */
  1574. /******************************************************************/
  1575. void AudioEventNoAttack ( AudioEvent *event )
  1576. {
  1577. DBG_ASSERT_TYPE ( event, AudioEvent );
  1578. DBG_ASSERT ( initialized );
  1579. FLAGS_SET ( event->flags, mAUDIO_EVENT_NO_ATTACK );
  1580. }
  1581. /******************************************************************/
  1582. /* */
  1583. /* */
  1584. /******************************************************************/
  1585. void AudioEventKill ( AudioEvent *event )
  1586. {
  1587. DBG_ASSERT_TYPE ( event, AudioEvent );
  1588. DBG_ASSERT ( initialized );
  1589. if ( event->flags & mAUDIO_EVENT_DEAD )
  1590. {
  1591. return;
  1592. }
  1593. eventReleaseChannel ( event );
  1594. eventUnlockSamples ( event );
  1595. event->state = AUDIO_EVENT_DONE;
  1596. event->stamp = AUDIO_INVALID_STAMP;
  1597. event->handle = NULL;
  1598. FLAGS_SET ( event->flags, mAUDIO_EVENT_DEAD );
  1599. }
  1600. /******************************************************************/
  1601. /* */
  1602. /* */
  1603. /******************************************************************/
  1604. void AudioEventPause ( AudioEvent *event )
  1605. {
  1606. DBG_ASSERT_TYPE ( event, AudioEvent );
  1607. DBG_ASSERT ( initialized );
  1608. if ( !AudioEventIsPaused ( event ))
  1609. {
  1610. if ( event->state == AUDIO_EVENT_WAITING )
  1611. {
  1612. event->timeOut -= AudioGetTime ();
  1613. }
  1614. }
  1615. LockAcquire ( &event->paused );
  1616. }
  1617. /******************************************************************/
  1618. /* */
  1619. /* */
  1620. /******************************************************************/
  1621. void AudioEventResume ( AudioEvent *event )
  1622. {
  1623. DBG_ASSERT_TYPE ( event, AudioEvent );
  1624. DBG_ASSERT ( initialized );
  1625. if ( AudioEventIsPaused ( event ))
  1626. {
  1627. LockRelease ( &event->paused );
  1628. if ( !AudioEventIsPaused ( event ) )
  1629. {
  1630. if ( event->state == AUDIO_EVENT_WAITING )
  1631. {
  1632. event->timeOut += AudioGetTime();
  1633. }
  1634. }
  1635. }
  1636. }
  1637. /******************************************************************/
  1638. /* */
  1639. /* */
  1640. /******************************************************************/
  1641. int AudioEventIsPaused ( AudioEvent *event )
  1642. {
  1643. DBG_ASSERT_TYPE ( event, AudioEvent );
  1644. return Locked ( &event->paused );
  1645. }
  1646. /******************************************************************/
  1647. /* */
  1648. /* */
  1649. /******************************************************************/
  1650. void AudioEventEnd ( AudioEvent *event )
  1651. {
  1652. DBG_ASSERT_TYPE ( event, AudioEvent );
  1653. DBG_ASSERT ( initialized );
  1654. if ( event->flags & mAUDIO_EVENT_END )
  1655. {
  1656. return;
  1657. }
  1658. if ( event->channel && event == (AudioEvent *) event->channel->Data )
  1659. {
  1660. AudioChannelLock ( event->channel );
  1661. FLAGS_SET ( event->flags, mAUDIO_EVENT_END | mAUDIO_EVENT_DO_END );
  1662. AudioChannelUnlock ( event->channel );
  1663. }
  1664. else
  1665. {
  1666. FLAGS_SET ( event->flags, mAUDIO_EVENT_END | mAUDIO_EVENT_DO_END );
  1667. }
  1668. }
  1669. /******************************************************************/
  1670. /* */
  1671. /* */
  1672. /******************************************************************/
  1673. void AudioEventService ( AudioEvent *event )
  1674. {
  1675. DBG_ASSERT_TYPE ( event, AudioEvent );
  1676. DBG_ASSERT ( initialized );
  1677. if ( !eventsOn )
  1678. {
  1679. event->state = AUDIO_EVENT_DONE;
  1680. }
  1681. retry:
  1682. switch ( event->state )
  1683. {
  1684. case AUDIO_EVENT_NEW:
  1685. {
  1686. if ( !audioEventPrep ( event ) )
  1687. {
  1688. AudioEventKill ( event );
  1689. }
  1690. }
  1691. break;
  1692. case AUDIO_EVENT_START_PLAYING:
  1693. break;
  1694. case AUDIO_EVENT_PLAYING:
  1695. // check for rogue looping event
  1696. if ( AudioEventNeverEnds ( event ) )
  1697. {
  1698. if ( !(event->flags & mAUDIO_EVENT_END ) && (!event->handle || AudioEventHandleGet ( event->handle ) != event))
  1699. {
  1700. // we have a looping smaple that has no handle attacked to it.
  1701. // this means that the event can never be stopped (unless it gets bumped
  1702. // by a higher priority event), which probable means that something has got wrong
  1703. msg_assert ( FALSE, ("A looping audio event '%s' is playing but has no handle. \n\nPlease tell Tommy about this assert. It is ok to ignore this assert", AudioEventName ( event )));
  1704. AudioEventKill ( event );
  1705. }
  1706. }
  1707. if ( event->flags & mAUDIO_EVENT_DO_END )
  1708. {
  1709. do_ending:
  1710. AudioChannel *chan = event->channel;
  1711. if ( chan )
  1712. {
  1713. AudioChannelLock ( chan );
  1714. FLAGS_CLEAR ( event->flags , mAUDIO_EVENT_DO_END );
  1715. AudioChannelStop ( event->channel );
  1716. if ( event->eclass->control & AUDIO_EVENT_CTRL_DECAY && !(event->flags & mAUDIO_EVENT_NO_DECAY))
  1717. {
  1718. event->state = AUDIO_EVENT_START_PLAYING;
  1719. event->startSample = eventNextSample ( event );
  1720. //msg_warning ( event->startSample, ("You can safely ignore this assert, but let me know about it.\n\nThanks, Tommy - ext 205"));
  1721. if ( !AudioEventIsPaused ( event ))
  1722. {
  1723. if ( !audioEventStart ( event ) )
  1724. {
  1725. AudioEventKill ( event );
  1726. }
  1727. }
  1728. }
  1729. AudioChannelUnlock ( chan );
  1730. }
  1731. else
  1732. {
  1733. FLAGS_CLEAR ( event->flags , mAUDIO_EVENT_DO_END );
  1734. }
  1735. }
  1736. break;
  1737. case AUDIO_EVENT_WAITING:
  1738. {
  1739. if ( event->flags & mAUDIO_EVENT_DO_END )
  1740. {
  1741. goto do_ending;
  1742. }
  1743. if ( !AudioEventIsPaused( event ) && AudioGetTime () > event->timeOut )
  1744. {
  1745. event->state = event->nextState;
  1746. goto retry;
  1747. }
  1748. }
  1749. break;
  1750. case AUDIO_EVENT_DONE:
  1751. {
  1752. AudioEventKill ( event );
  1753. }
  1754. break;
  1755. default:
  1756. DBG_MSGASSERT ( FALSE, ("bad event type"));
  1757. }
  1758. }
  1759. /******************************************************************/
  1760. /* */
  1761. /* */
  1762. /******************************************************************/
  1763. void AudioEventHandleInit ( AudioEventHandle *handle )
  1764. {
  1765. DBG_ASSERT_PTR ( handle );
  1766. handle->event = NULL;
  1767. handle->stamp = AUDIO_INVALID_STAMP;
  1768. handle->eclass = NULL;
  1769. handle->id = ID_HANDLE;
  1770. DBG_SET_TYPE ( handle, AudioEventHandle );
  1771. }
  1772. /******************************************************************/
  1773. /* */
  1774. /* */
  1775. /******************************************************************/
  1776. void AudioEventHandleDeinit ( AudioEventHandle *handle )
  1777. {
  1778. DBG_ASSERT_TYPE ( handle, AudioEventHandle );
  1779. AudioEventHandleStop ( handle );
  1780. handle->id = 0;
  1781. DBG_INVALIDATE_TYPE ( handle );
  1782. }
  1783. /******************************************************************/
  1784. /* */
  1785. /* */
  1786. /******************************************************************/
  1787. void AudioEventHandleStop ( AudioEventHandle *handle )
  1788. {
  1789. DBG_ASSERT_TYPE ( handle, AudioEventHandle );
  1790. AudioEvent *event = AudioEventHandleGet ( handle );
  1791. if ( event )
  1792. {
  1793. AudioEventKill ( event );
  1794. handle->event = NULL;
  1795. }
  1796. handle->eclass = NULL;
  1797. }
  1798. /******************************************************************/
  1799. /* */
  1800. /* */
  1801. /******************************************************************/
  1802. void AudioEventHandleStopLooping ( AudioEventHandle *handle )
  1803. {
  1804. DBG_ASSERT_TYPE ( handle, AudioEventHandle );
  1805. AudioEvent *event = AudioEventHandleGet ( handle );
  1806. if ( event && AudioEventNeverEnds ( event ))
  1807. {
  1808. AudioEventKill ( event );
  1809. handle->event = NULL;
  1810. }
  1811. handle->eclass = NULL;
  1812. }
  1813. /******************************************************************/
  1814. /* */
  1815. /* */
  1816. /******************************************************************/
  1817. void AudioEventHandleEnd ( AudioEventHandle *handle )
  1818. {
  1819. DBG_ASSERT_TYPE ( handle, AudioEventHandle );
  1820. AudioEvent *event = AudioEventHandleGet ( handle );
  1821. if ( event )
  1822. {
  1823. AudioEventEnd ( event );
  1824. handle->event = NULL;
  1825. }
  1826. handle->eclass = NULL;
  1827. }
  1828. /******************************************************************/
  1829. /* */
  1830. /* */
  1831. /******************************************************************/
  1832. void AudioEventHandleEndLooping ( AudioEventHandle *handle )
  1833. {
  1834. DBG_ASSERT_TYPE ( handle, AudioEventHandle );
  1835. AudioEvent *event = AudioEventHandleGet ( handle );
  1836. if ( event && AudioEventNeverEnds ( event ))
  1837. {
  1838. AudioEventEnd ( event );
  1839. handle->event = NULL;
  1840. }
  1841. handle->eclass = NULL;
  1842. }
  1843. /******************************************************************/
  1844. /* */
  1845. /* */
  1846. /******************************************************************/
  1847. void AudioEventHandleSet ( AudioEventHandle *handle, AudioEvent *event, AudioEventClass *eclass )
  1848. {
  1849. DBG_ASSERT_TYPE( handle, AudioEventHandle );
  1850. if ( handle->id != ID_HANDLE )
  1851. {
  1852. return;
  1853. }
  1854. handle->eclass = eclass;
  1855. if ( ( handle->event = event ))
  1856. {
  1857. DBG_ASSERT_TYPE ( event, AudioEvent );
  1858. handle->stamp = event->stamp;
  1859. if ( !eclass )
  1860. {
  1861. handle->eclass = event->eclass;
  1862. }
  1863. event->handle = handle;
  1864. }
  1865. }
  1866. /******************************************************************/
  1867. /* */
  1868. /* */
  1869. /******************************************************************/
  1870. AudioEvent* AudioEventHandleGet ( AudioEventHandle *handle )
  1871. {
  1872. AudioEvent *event;
  1873. DBG_ASSERT_TYPE ( handle, AudioEventHandle );
  1874. if (!initialized || handle->id != ID_HANDLE )
  1875. {
  1876. return NULL;
  1877. }
  1878. if ( ( event = handle->event) )
  1879. {
  1880. if ( ( handle->eclass != event->eclass ) || handle->stamp != event->stamp )
  1881. {
  1882. handle->event = event = NULL;
  1883. }
  1884. }
  1885. return event;
  1886. }
  1887. /******************************************************************/
  1888. /* */
  1889. /* */
  1890. /******************************************************************/
  1891. AudioEventClass* AudioEventHandleGetClass ( AudioEventHandle *handle )
  1892. {
  1893. DBG_ASSERT_TYPE ( handle, AudioEventHandle );
  1894. if (!initialized || handle->id != ID_HANDLE )
  1895. {
  1896. return NULL;
  1897. }
  1898. return handle->eclass;
  1899. }
  1900. /******************************************************************/
  1901. /* */
  1902. /* */
  1903. /******************************************************************/
  1904. void AudioEventSetVolume ( AudioEvent *event, int new_volume )
  1905. {
  1906. DBG_ASSERT_TYPE ( event, AudioEvent );
  1907. AudioLevelSet ( &event->attribs.VolumeLevel, eventCalcVolume ( event, new_volume) );
  1908. AudioLevelUpdate ( &event->attribs.VolumeLevel );
  1909. }
  1910. /******************************************************************/
  1911. /* */
  1912. /* */
  1913. /******************************************************************/
  1914. void AudioEventAdjustVolume ( AudioEvent *event, int new_volume )
  1915. {
  1916. DBG_ASSERT_TYPE ( event, AudioEvent );
  1917. if ( event->state == AUDIO_EVENT_PLAYING )
  1918. {
  1919. AudioLevelAdjust ( &event->attribs.VolumeLevel, eventCalcVolume ( event, new_volume) );
  1920. }
  1921. else
  1922. {
  1923. AudioEventSetVolume ( event, new_volume );
  1924. }
  1925. }
  1926. /******************************************************************/
  1927. /* */
  1928. /* */
  1929. /******************************************************************/
  1930. static uint eventCalcPan ( int new_pan )
  1931. {
  1932. // convert to audiolevel pan
  1933. if ( new_pan > AUDIO_PAN_RIGHT )
  1934. {
  1935. new_pan = AUDIO_PAN_RIGHT;
  1936. }
  1937. else if ( new_pan < AUDIO_PAN_LEFT )
  1938. {
  1939. new_pan = AUDIO_PAN_LEFT;
  1940. }
  1941. return new_pan;
  1942. }
  1943. /******************************************************************/
  1944. /* */
  1945. /* */
  1946. /******************************************************************/
  1947. void AudioEventSetPan ( AudioEvent *event, int new_pan )
  1948. {
  1949. DBG_ASSERT_TYPE ( event, AudioEvent );
  1950. AudioLevelSet ( &event->attribs.PanPosition, eventCalcPan ( new_pan ) );
  1951. }
  1952. /******************************************************************/
  1953. /* */
  1954. /* */
  1955. /******************************************************************/
  1956. void AudioEventAdjustPan ( AudioEvent *event, int new_pan )
  1957. {
  1958. DBG_ASSERT_TYPE ( event, AudioEvent );
  1959. if ( event->state == AUDIO_EVENT_PLAYING )
  1960. {
  1961. AudioLevelAdjust ( &event->attribs.PanPosition, eventCalcPan ( new_pan ) );
  1962. }
  1963. else
  1964. {
  1965. AudioEventSetPan ( event, new_pan );
  1966. }
  1967. }
  1968. /******************************************************************/
  1969. /* */
  1970. /* */
  1971. /******************************************************************/
  1972. void AudioEventSetAdjustDuration ( AudioEvent *event, TimeStamp time )
  1973. {
  1974. DBG_ASSERT_TYPE ( event, AudioEvent );
  1975. AudioLevelSetDuration ( &event->attribs.VolumeLevel, time, AUDIO_LEVEL_MAX );
  1976. AudioLevelSetDuration ( &event->attribs.PitchLevel, time, AUDIO_LEVEL_MAX );
  1977. AudioLevelSetDuration ( &event->attribs.PanPosition, time, AUDIO_LEVEL_MAX );
  1978. }
  1979. /******************************************************************/
  1980. /* */
  1981. /* */
  1982. /******************************************************************/
  1983. AudioEventClass* AudioEventGetClass ( AudioEvent *event )
  1984. {
  1985. DBG_ASSERT_TYPE ( event, AudioEvent );
  1986. return event->eclass;
  1987. }
  1988. /******************************************************************/
  1989. /* */
  1990. /* */
  1991. /******************************************************************/
  1992. int AudioEventNeverEnds ( AudioEvent *event )
  1993. {
  1994. DBG_ASSERT_TYPE ( event, AudioEvent );
  1995. return AudioEventClassNeverEnds ( event->eclass );
  1996. }
  1997. /******************************************************************/
  1998. /* */
  1999. /* */
  2000. /******************************************************************/
  2001. void AudioEventSetTimeOfDay ( AudioEvent *event, int new_tod )
  2002. {
  2003. DBG_ASSERT_TYPE ( event, AudioEvent );
  2004. event->timeOfDay = new_tod;
  2005. }
  2006. /******************************************************************/
  2007. /* */
  2008. /* */
  2009. /******************************************************************/
  2010. char* AudioEventName ( AudioEvent *event )
  2011. {
  2012. DBG_ASSERT_TYPE ( event, AudioEvent );
  2013. if ( !initialized )
  2014. {
  2015. return "no events";
  2016. }
  2017. if ( !event->eclass )
  2018. {
  2019. return "unknown";
  2020. }
  2021. return AudioEventClassName ( event->eclass);
  2022. }
  2023. /******************************************************************/
  2024. /* */
  2025. /* */
  2026. /******************************************************************/
  2027. char* AudioEventClassName ( AudioEventClass *eclass )
  2028. {
  2029. DBG_ASSERT_TYPE ( eclass, AudioEventClass );
  2030. if ( !initialized )
  2031. {
  2032. return "no events";
  2033. }
  2034. if ( !eclass->name )
  2035. {
  2036. return "(null)";
  2037. }
  2038. return eclass->name;
  2039. }
  2040. /******************************************************************/
  2041. /* */
  2042. /* */
  2043. /******************************************************************/
  2044. void AudioEventClassSetName ( AudioEventClass *eclass, char *new_name )
  2045. {
  2046. DBG_ASSERT_TYPE ( eclass, AudioEventClass );
  2047. eclass->name = new_name;
  2048. }
  2049. /******************************************************************/
  2050. /* */
  2051. /* */
  2052. /******************************************************************/
  2053. void AudioEventClassSetFadeAttribs ( AudioEventClass *eclass, AudioAttribs *attribs )
  2054. {
  2055. DBG_ASSERT_TYPE ( eclass, AudioEventClass );
  2056. eclass->fadeAttribs = attribs;
  2057. }
  2058. /******************************************************************/
  2059. /* */
  2060. /* */
  2061. /******************************************************************/
  2062. void AudioEventClassSetMasterAttribs ( AudioEventClass *eclass, AudioAttribs *attribs )
  2063. {
  2064. DBG_ASSERT_TYPE ( eclass, AudioEventClass );
  2065. eclass->masterAttribs = attribs;
  2066. }
  2067. /******************************************************************/
  2068. /* */
  2069. /* */
  2070. /******************************************************************/
  2071. void AudioEventClassSetData ( AudioEventClass *eclass, void *data)
  2072. {
  2073. DBG_ASSERT_TYPE ( eclass, AudioEventClass );
  2074. eclass->data = data;
  2075. }
  2076. /******************************************************************/
  2077. /* */
  2078. /* */
  2079. /******************************************************************/
  2080. void* AudioEventClassGetData ( AudioEventClass *eclass )
  2081. {
  2082. DBG_ASSERT_TYPE ( eclass, AudioEventClass );
  2083. return eclass->data;
  2084. }
  2085. /******************************************************************/
  2086. /* */
  2087. /* */
  2088. /******************************************************************/
  2089. const char* AudioEventClassGetSoundName ( AudioEventClass *eclass, int index )
  2090. {
  2091. static const char *bogus = "";
  2092. DBG_ASSERT_TYPE ( eclass, AudioEventClass );
  2093. if (index < 0 || index >= eclass->numSamples) {
  2094. return bogus;
  2095. }
  2096. return eclass->sampleName[index];
  2097. }
  2098. /******************************************************************/
  2099. /* */
  2100. /* */
  2101. /******************************************************************/
  2102. AudioEventClass *AudioEventClassCreate ( void )
  2103. {
  2104. AudioEventClass *eclass;
  2105. if ( !initialized )
  2106. {
  2107. return NULL;
  2108. }
  2109. ALLOC_STRUCT ( eclass, AudioEventClass );
  2110. audioInitEventClass ( eclass );
  2111. ListAddToTail ( &audioEventClasses, &eclass->nd );
  2112. return eclass;
  2113. }
  2114. /******************************************************************/
  2115. /* */
  2116. /* */
  2117. /******************************************************************/
  2118. int AudioEventClassAddSound ( AudioEventClass *eclass, const char *name )
  2119. {
  2120. DBG_ASSERT_TYPE ( eclass, AudioEventClass );
  2121. if ( eclass->numSamples == MAX_AUDIO_EVENT_SAMPLES )
  2122. {
  2123. msg_warning ( FALSE, ("Too many samples in audio event '%s' (Max %d)", AudioEventClassName ( eclass), MAX_AUDIO_EVENT_SAMPLES ));
  2124. return FALSE;
  2125. }
  2126. if ( initialized )
  2127. {
  2128. if ( name != NULL )
  2129. {
  2130. eclass->sampleName[eclass->numSamples++] = strdup( name );
  2131. }
  2132. else
  2133. {
  2134. //DBGPRINTF (("Missing sample %s\n", name ));
  2135. eclass->valid = FALSE;
  2136. return FALSE;
  2137. }
  2138. }
  2139. return TRUE;
  2140. }
  2141. /******************************************************************/
  2142. /* */
  2143. /* */
  2144. /******************************************************************/
  2145. int AudioEventClassNumSound ( AudioEventClass *eclass )
  2146. {
  2147. DBG_ASSERT_TYPE ( eclass, AudioEventClass );
  2148. return eclass->numSamples;
  2149. }
  2150. /******************************************************************/
  2151. /* */
  2152. /* */
  2153. /******************************************************************/
  2154. void AudioEventClassSetAttackCount ( AudioEventClass *eclass, int count )
  2155. {
  2156. DBG_ASSERT_TYPE ( eclass, AudioEventClass );
  2157. msg_assert ( count >= 0,("Attack count must be positive") );
  2158. eclass->attackCount = count;
  2159. }
  2160. /******************************************************************/
  2161. /* */
  2162. /* */
  2163. /******************************************************************/
  2164. void AudioEventClassSetDecayCount ( AudioEventClass *eclass, int count )
  2165. {
  2166. DBG_ASSERT_TYPE ( eclass, AudioEventClass );
  2167. msg_assert ( count >= 0,("Decay count must be positive") );
  2168. eclass->decayCount = count;
  2169. }
  2170. /******************************************************************/
  2171. /* */
  2172. /* */
  2173. /******************************************************************/
  2174. void AudioEventClassSetMorningSoundCount( AudioEventClass *eclass, int count )
  2175. {
  2176. DBG_ASSERT_TYPE ( eclass, AudioEventClass );
  2177. msg_assert ( count >= 0,("Morning Sound count must be positive") );
  2178. eclass->morningCount = count;
  2179. }
  2180. /******************************************************************/
  2181. /* */
  2182. /* */
  2183. /******************************************************************/
  2184. void AudioEventClassSetEveningSoundCount( AudioEventClass *eclass, int count )
  2185. {
  2186. DBG_ASSERT_TYPE ( eclass, AudioEventClass );
  2187. msg_assert ( count >= 0,("Evening Sound count must be positive") );
  2188. eclass->eveningCount = count;
  2189. }
  2190. /******************************************************************/
  2191. /* */
  2192. /* */
  2193. /******************************************************************/
  2194. void AudioEventClassSetNightSoundCount( AudioEventClass *eclass, int count )
  2195. {
  2196. DBG_ASSERT_TYPE ( eclass, AudioEventClass );
  2197. msg_assert ( count >= 0,("Night Sound count must be positive") );
  2198. eclass->nightCount = count;
  2199. }
  2200. /******************************************************************/
  2201. /* */
  2202. /* */
  2203. /******************************************************************/
  2204. void AudioEventClassSetPriority ( AudioEventClass *eclass, AudioPriority pri )
  2205. {
  2206. DBG_ASSERT_TYPE ( eclass, AudioEventClass );
  2207. eclass->priority = pri;
  2208. }
  2209. /******************************************************************/
  2210. /* */
  2211. /* */
  2212. /******************************************************************/
  2213. void AudioEventClassSetVolume ( AudioEventClass *eclass, int vol )
  2214. {
  2215. DBG_ASSERT_TYPE ( eclass, AudioEventClass );
  2216. AudioLevelSet ( &eclass->baseLevel, vol );
  2217. AudioLevelUpdate ( &eclass->baseLevel );
  2218. }
  2219. /******************************************************************/
  2220. /* */
  2221. /* */
  2222. /******************************************************************/
  2223. void AudioEventClassSetControl ( AudioEventClass *eclass, AudioEventControl control )
  2224. {
  2225. DBG_ASSERT_TYPE ( eclass, AudioEventClass );
  2226. eclass->control = control;
  2227. #ifdef _DEBUG
  2228. msg_warning ( !( !eclass->format_same
  2229. && (control & (AUDIO_EVENT_CTRL_LOOP|AUDIO_EVENT_CTRL_ALL )
  2230. == (AUDIO_EVENT_CTRL_LOOP|AUDIO_EVENT_CTRL_ALL ) )),
  2231. ("Audio event \"%s\" set to \"loop all\", however not all sounds are of the same format\n"
  2232. "\nSame format means they must have the same Playback rate, same original sample width, and same number of channels", AudioEventClassName (eclass) ));
  2233. #endif //_DEBUG
  2234. if ( eclass->control & AUDIO_EVENT_CTRL_ATTACK )
  2235. {
  2236. if ( eclass->attackCount == 0)
  2237. {
  2238. eclass->attackCount = 1 ;
  2239. }
  2240. }
  2241. else
  2242. {
  2243. eclass->attackCount = 0;
  2244. }
  2245. if ( eclass->control & AUDIO_EVENT_CTRL_DECAY )
  2246. {
  2247. if ( eclass->decayCount == 0)
  2248. {
  2249. eclass->decayCount = 1;
  2250. }
  2251. }
  2252. else
  2253. {
  2254. eclass->decayCount = 0;
  2255. }
  2256. }
  2257. /******************************************************************/
  2258. /* */
  2259. /* */
  2260. /******************************************************************/
  2261. void AudioEventClassSetLimit ( AudioEventClass *eclass, int limit )
  2262. {
  2263. DBG_ASSERT_TYPE ( eclass, AudioEventClass );
  2264. eclass->limit = limit;
  2265. }
  2266. /******************************************************************/
  2267. /* */
  2268. /* */
  2269. /******************************************************************/
  2270. void AudioEventClassSetRange ( AudioEventClass *eclass, int range )
  2271. {
  2272. DBG_ASSERT_TYPE ( eclass, AudioEventClass );
  2273. eclass->range = range;
  2274. }
  2275. /******************************************************************/
  2276. /* */
  2277. /* */
  2278. /******************************************************************/
  2279. void AudioEventClassSetMinVolume ( AudioEventClass *eclass, int min_vol )
  2280. {
  2281. DBG_ASSERT_TYPE ( eclass, AudioEventClass );
  2282. eclass->min_volume = min_vol;
  2283. }
  2284. /******************************************************************/
  2285. /* */
  2286. /* */
  2287. /******************************************************************/
  2288. void AudioEventClassSetDelay ( AudioEventClass *eclass, int minDelay, int maxDelay )
  2289. {
  2290. DBG_ASSERT_TYPE ( eclass, AudioEventClass );
  2291. msg_assert ( maxDelay >= minDelay, ("bad parameters on SetDelay"));
  2292. eclass->minDelay = minDelay;
  2293. eclass->maxDelay = maxDelay;
  2294. }
  2295. /******************************************************************/
  2296. /* */
  2297. /* */
  2298. /******************************************************************/
  2299. void AudioEventClassSetPitchShift ( AudioEventClass *eclass, int minShift, int maxShift )
  2300. {
  2301. DBG_ASSERT_TYPE ( eclass, AudioEventClass );
  2302. msg_assert ( maxShift >= minShift, ("bad parameters on SetPitchShift"));
  2303. eclass->minFShift = minShift;
  2304. eclass->maxFShift = maxShift;
  2305. }
  2306. /******************************************************************/
  2307. /* */
  2308. /* */
  2309. /******************************************************************/
  2310. void AudioEventClassSetVolumeShift ( AudioEventClass *eclass, int VShift)
  2311. {
  2312. DBG_ASSERT_TYPE ( eclass, AudioEventClass );
  2313. if ( VShift > 100 )
  2314. {
  2315. VShift = 100;
  2316. }
  2317. else if ( VShift < 0 )
  2318. {
  2319. VShift = 0;
  2320. }
  2321. eclass->vShift = VShift;
  2322. }
  2323. //============================================================================
  2324. // AudioEventClassSetVolumeCompression
  2325. //============================================================================
  2326. void AudioEventClassSetVolumeCompression ( AudioEventClass *eclass, int on)
  2327. {
  2328. DBG_ASSERT_TYPE ( eclass, AudioEventClass );
  2329. eclass->volumeCompression = on;
  2330. }
  2331. /******************************************************************/
  2332. /* */
  2333. /* */
  2334. /******************************************************************/
  2335. void AudioEventClassReset ( AudioEventClass *eclass )
  2336. {
  2337. DBG_ASSERT_TYPE ( eclass, AudioEventClass );
  2338. ListNode nd;
  2339. char *name;
  2340. AudioAttribs *fadeAttribs;
  2341. AudioAttribs *masterAttribs;
  2342. // save fields that do not change
  2343. nd = eclass->nd;
  2344. name = eclass->name;
  2345. masterAttribs = eclass->masterAttribs;
  2346. fadeAttribs = eclass->fadeAttribs;
  2347. memset ( eclass, 0, sizeof(AudioEventClass ));
  2348. eclass->nd = nd;
  2349. eclass->masterAttribs = masterAttribs;
  2350. eclass->fadeAttribs = fadeAttribs;
  2351. DBG_SET_TYPE ( eclass, AudioEventClass );
  2352. eclass->valid = TRUE;
  2353. eclass->control = AUDIO_EVENT_CTRL_NONE;
  2354. eclass->limit = AUDIO_EVENT_DEFAULT_LIMIT;
  2355. eclass->priority = AUDIO_EVENT_NORMAL_PRIORITY;
  2356. eclass->range = 10; // in cells
  2357. eclass->min_volume = 40;
  2358. AudioLevelInit ( &eclass->baseLevel, AUDIO_LEVEL_MAX );
  2359. #ifdef _DEBUG
  2360. eclass->format_same = TRUE;
  2361. AudioFormatInit ( &eclass->format );
  2362. #endif
  2363. }
  2364. /******************************************************************/
  2365. /* */
  2366. /* */
  2367. /******************************************************************/
  2368. void AudioEventClassSetLoopCount ( AudioEventClass *eclass, int count )
  2369. {
  2370. DBG_ASSERT_TYPE ( eclass, AudioEventClass );
  2371. eclass->limitLoop = count;
  2372. }
  2373. /******************************************************************/
  2374. /* */
  2375. /* */
  2376. /******************************************************************/
  2377. int AudioEventClassNeverEnds ( AudioEventClass *eclass )
  2378. {
  2379. DBG_ASSERT_TYPE ( eclass, AudioEventClass );
  2380. return ((eclass->control & AUDIO_EVENT_CTRL_LOOP) && !eclass->limitLoop);
  2381. }
  2382. /******************************************************************/
  2383. /* */
  2384. /* */
  2385. /******************************************************************/
  2386. void AudioEventTurnOff ( void )
  2387. {
  2388. eventsOn = FALSE;
  2389. }
  2390. /******************************************************************/
  2391. /* */
  2392. /* */
  2393. /******************************************************************/
  2394. void AudioEventTurnOn ( void )
  2395. {
  2396. eventsOn = TRUE;
  2397. }
  2398. /******************************************************************/
  2399. /* */
  2400. /* */
  2401. /******************************************************************/
  2402. int AudioEventOn ( void )
  2403. {
  2404. return eventsOn;
  2405. }
  2406. /******************************************************************/
  2407. /* */
  2408. /* */
  2409. /******************************************************************/
  2410. void AudioEventsDump ( void (*print) ( char *text ))
  2411. {
  2412. if ( audioCache )
  2413. {
  2414. char buffer[200];
  2415. ProfCacheText ( &audioCache->profile, print );
  2416. sprintf ( buffer, "AudioEvents : %05d - Max: %05d\n", AudioEventsCount, AudioEventsPeak);
  2417. print ( buffer );
  2418. }
  2419. }
  2420. /******************************************************************/
  2421. /* */
  2422. /* */
  2423. /******************************************************************/
  2424. void AudioFlushCache ( void )
  2425. {
  2426. if ( audioCache )
  2427. {
  2428. AudioCacheInvalidate ( audioCache );
  2429. while ( AudioCacheFreeOldestItem( audioCache ) );
  2430. }
  2431. }