sstream.c 36 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385
  1. /*=============================================================================
  2. Name : sstream.c
  3. Purpose : Low level audio streamer routines
  4. Created 01/10/1998 by salfreds
  5. Copyright Relic Entertainment, Inc. All rights reserved.
  6. =============================================================================*/
  7. #define WIN32_LEAN_AND_MEAN
  8. #include <windows.h>
  9. #include <string.h>
  10. #include <mmsystem.h>
  11. #include <dsound.h>
  12. #include <process.h>
  13. #include "types.h"
  14. #include "switches.h"
  15. #include "debug.h"
  16. #include "soundlow.h"
  17. #include "soundcmn.h"
  18. #include "file.h"
  19. #include "fqeffect.h"
  20. #include "soundstructs.h"
  21. #include "speechevent.h"
  22. #include "subtitle.h"
  23. /* functions */
  24. sdword isoundstreamreadheader(STREAM *pstream);
  25. /* variables */
  26. streamprintfunction debugfunction = NULL;
  27. char debugtext[256];
  28. //filehandle streamfile;
  29. CHANNEL speechchannels[SOUND_MAX_STREAM_BUFFERS];
  30. STREAM streams[SOUND_MAX_STREAM_BUFFERS];
  31. sdword numstreams;
  32. #if VCE_BACKWARDS_COMPATIBLE
  33. bool ssOldFormatVCE = FALSE;
  34. #endif
  35. extern LPDIRECTSOUND lpDirectSound;
  36. extern CHANNEL channels[];
  37. extern SENTENCELUT *SentenceLUT;
  38. extern bool soundinited;
  39. extern SOUNDCOMPONENT streamer;
  40. extern udword mixerticks;
  41. extern bool bSoundPaused;
  42. extern bool bSoundDeactivated;
  43. /*-----------------------------------------------------------------------------
  44. Name :
  45. Description :
  46. Inputs :
  47. Outputs :
  48. Return :
  49. ----------------------------------------------------------------------------*/
  50. void soundstreamquery(sdword maxstreams, sdword *pbuffersize, sdword *pstreamersize)
  51. {
  52. if (maxstreams > SOUND_MAX_STREAM_BUFFERS)
  53. {
  54. *pstreamersize = 0;
  55. *pbuffersize = 0;
  56. return;
  57. }
  58. numstreams = maxstreams;
  59. /* figure out how much memory we need for the array of stream structures */
  60. *pstreamersize = (sdword)(maxstreams * sizeof(STREAM));
  61. /* figure out how big each stream buffer needs to be */
  62. *pbuffersize = SOUND_STREAM_BUFFER_SIZE + 4; // needs 4 extra bytes for dequantizing.
  63. }
  64. sdword streamStartThread(void)
  65. {
  66. _beginthread(isoundstreamupdate, 0, NULL);
  67. streamer.status = SOUND_PLAYING;
  68. return (SOUND_OK);
  69. }
  70. /*-----------------------------------------------------------------------------
  71. Name :
  72. Description :
  73. Inputs :
  74. Outputs :
  75. Return :
  76. ----------------------------------------------------------------------------*/
  77. sdword soundstreaminit(void *pstreamer, sdword size, sdword nostreams, streamprintfunction printfunction)
  78. {
  79. sdword i, j;
  80. STREAM *pstream;
  81. memset(pstreamer, 0, size);
  82. dbgAssert(streamer.status == SOUND_FREE);
  83. /* go through stream structures and init */
  84. for (i = 0; i < numstreams; i++)
  85. {
  86. pstream = &streams[i];
  87. pstream->buffer = NULL;
  88. for (j = 0; j < SOUND_MAX_STREAM_QUEUE; j++)
  89. {
  90. pstream->queue[j].fhandle = SOUND_ERR;
  91. pstream->queue[j].offset = SOUND_ERR;
  92. }
  93. pstream->numqueued = 0;
  94. pstream->numtoplay = 0;
  95. if (i < SentenceLUT->numactors)
  96. {
  97. pstream->dataPeriod = SND_BLOCK_TIME / (SentenceLUT->compbitrate[i] / 8);
  98. }
  99. else
  100. {
  101. pstream->dataPeriod = SND_BLOCK_TIME / (SentenceLUT->compbitrate[0] / 8);
  102. }
  103. speechchannels[i].status = SOUND_FREE;
  104. }
  105. if (printfunction != NULL)
  106. {
  107. debugfunction = printfunction;
  108. }
  109. streamStartThread();
  110. return (SOUND_OK);
  111. }
  112. /*-----------------------------------------------------------------------------
  113. Name :
  114. Description :
  115. Inputs :
  116. Outputs :
  117. Return :
  118. ----------------------------------------------------------------------------*/
  119. udword soundstreamopenfile(char *pszStreamFile, sdword *handle)
  120. {
  121. filehandle streamfile;
  122. udword identifier;
  123. udword checksum;
  124. udword flags;
  125. /* Check Data dir on HD... */
  126. flags = 0;
  127. if (!fileExists(pszStreamFile, flags))
  128. {
  129. /* Check first CDROM drive... */
  130. flags = FF_CDROM;
  131. if (!fileExists(pszStreamFile, flags))
  132. {
  133. /* Death, destruction and general chaos! Should never happen (taken care of in utyGameSystemsInit()...*/
  134. dbgFatalf(DBG_Loc, "Homeworld CD not detected.");
  135. }
  136. }
  137. streamfile = fileOpen(pszStreamFile, flags);
  138. *handle = streamfile;
  139. #if VCE_BACKWARDS_COMPATIBLE
  140. fileBlockRead(streamfile, &identifier, sizeof(identifier));//read in an identifier
  141. if (identifier == ID_STREAM_DATA)
  142. { //if it's 'DATA'
  143. ssOldFormatVCE = TRUE;
  144. }
  145. #else
  146. fileSeek(streamfile, 4, FS_Start);
  147. #endif
  148. fileBlockRead(streamfile, &checksum, sizeof(checksum));
  149. fileSeek(streamfile, 0, FS_Start);
  150. return (checksum);
  151. }
  152. /*-----------------------------------------------------------------------------
  153. Name : soundstreamcreatebuffer
  154. Description :
  155. Inputs : pstreambuffer: pointer to a buffer allocated by the game
  156. size: the size of streambuffer
  157. Outputs :
  158. Return : the handle to the stream
  159. ----------------------------------------------------------------------------*/
  160. sdword soundstreamcreatebuffer(void *pstreambuffer, sdword size, uword bitrate)
  161. {
  162. sdword channel = 0;
  163. CHANNEL *pchan;
  164. STREAM *pstream;
  165. sdword i;
  166. for (i = 0; i < numstreams; i++)
  167. {
  168. if (streams[i].status == SOUND_STREAM_FREE)
  169. {
  170. pchan = &speechchannels[i];
  171. pstream = &streams[i];
  172. channel = i;
  173. pstream->status = SOUND_STREAM_INUSE;
  174. pstream->buffersize = SOUND_STREAM_BUFFER_SIZE;
  175. pstream->buffer = pstreambuffer;
  176. pstream->playing = FALSE;
  177. memset(pstream->buffer, 0, pstream->buffersize);
  178. fqAcModel(NULL, NULL, 0, pstream->delaybuffer1, DELAY_BUF_SIZE, &(pstream->delaypos1));
  179. fqAcModel(NULL, NULL, 0, pstream->delaybuffer2, DELAY_BUF_SIZE, &(pstream->delaypos2));
  180. break;
  181. }
  182. }
  183. if (pstream == NULL)
  184. {
  185. SNDreleasebuffer(pchan);
  186. }
  187. if (pstream->buffersize % ((bitrate >> 3) * 4))
  188. {
  189. pstream->buffersize /= ((bitrate >> 3) * 4);
  190. pstream->buffersize *= ((bitrate >> 3) * 4);
  191. }
  192. pchan->currentpos = pchan->freqdata = (sbyte *)pstream->buffer;
  193. pchan->endpos = (sbyte *)(pstream->buffer + pstream->buffersize);
  194. pchan->fqsize = FQ_HSIZE;
  195. pstream->writepos = pstream->buffer;
  196. pstream->readblock = 0;
  197. pstream->writeblock = 0;
  198. pstream->blocksize = pstream->buffersize / 2;
  199. pchan->handle = SNDcreatehandle(channel);
  200. pstream->handle = pchan->handle;
  201. return (pchan->handle);
  202. }
  203. /*-----------------------------------------------------------------------------
  204. Name :
  205. Description :
  206. Inputs :
  207. Outputs :
  208. Return :
  209. ----------------------------------------------------------------------------*/
  210. sdword soundstreamnumqueued(sdword streamhandle)
  211. {
  212. #if 1
  213. if (speechchannels[SNDchannel(streamhandle)].status <= SOUND_INUSE)
  214. {
  215. return (0);
  216. }
  217. else
  218. {
  219. return (1);
  220. }
  221. #endif
  222. return (streams[SNDchannel(streamhandle)].numqueued);
  223. }
  224. /*-----------------------------------------------------------------------------
  225. Name :
  226. Description :
  227. Inputs :
  228. Outputs :
  229. Return :
  230. ----------------------------------------------------------------------------*/
  231. void soundstreamstopall(real32 fadetime)
  232. {
  233. sdword i;
  234. for (i = 0; i < numstreams; i++)
  235. {
  236. soundstreamvolume(speechchannels[i].handle, SOUND_VOL_AUTOSTOP, fadetime);
  237. // streams[i].status = SOUND_STREAM_INUSE;
  238. // streams[i].queueindex = 0;
  239. // streams[i].writeindex = 0;
  240. // streams[i].playindex = 0;
  241. // speechchannels[i].status = SOUND_FREE;
  242. }
  243. }
  244. sdword soundstreamover(sdword streamhandle)
  245. {
  246. sdword channel;
  247. if (!soundinited)
  248. {
  249. return (TRUE);
  250. }
  251. if (streamer.status != SOUND_PLAYING)
  252. {
  253. return (TRUE);
  254. }
  255. channel = SNDchannel(streamhandle);
  256. if (channel >= SOUND_OK)
  257. {
  258. if (speechchannels[SNDchannel(streamhandle)].status <= SOUND_STOPPED)
  259. {
  260. return (TRUE);
  261. }
  262. }
  263. return (FALSE);
  264. }
  265. sdword soundstreamfading(sdword streamhandle)
  266. {
  267. sdword channel;
  268. if (!soundinited)
  269. {
  270. return (FALSE);
  271. }
  272. if (streamer.status != SOUND_PLAYING)
  273. {
  274. return (FALSE);
  275. }
  276. channel = SNDchannel(streamhandle);
  277. if (channel >= SOUND_OK)
  278. {
  279. if (speechchannels[channel].volfade != 0.0f)
  280. {
  281. return (TRUE);
  282. }
  283. }
  284. return (FALSE);
  285. }
  286. /*-----------------------------------------------------------------------------
  287. Name :
  288. Description :
  289. Inputs : actornum - actor index of event we're queueing up
  290. Outputs :
  291. Return :
  292. ----------------------------------------------------------------------------*/
  293. sdword soundstreamqueuePatch(sdword streamhandle, sdword filehandle, sdword offset, udword flags, sword vol, sword pan, sword numchannels, sword bitrate, EFFECT *peffect, STREAMEQ *pEQ, STREAMDELAY *pdelay, void *pmixpatch, sdword level, real32 silence, real32 fadetime, sdword actornum, sdword speechEvent, bool bWait)
  294. {
  295. sdword chan;
  296. STREAM *pstream;
  297. PATCH *ppatch;
  298. STREAMQUEUE *pqueue;
  299. // make sure the damn offset is valid.
  300. #ifdef salfreds
  301. if (!(flags & SOUND_FLAGS_QUEUESILENCE))
  302. {
  303. dbgAssert(offset >= 0);
  304. }
  305. #endif
  306. if (streamer.status == SOUND_STOPPING)
  307. {
  308. return (SOUND_ERR);
  309. }
  310. chan = SNDchannel(streamhandle);
  311. dbgAssert(chan >= 0);
  312. pstream = &streams[chan];
  313. if (pstream->handle != streamhandle)
  314. {
  315. /* hmmm, bad. do something */
  316. return (SOUND_ERR);
  317. }
  318. if ((pstream->queueindex == pstream->playindex) && (pstream->status > SOUND_STREAM_INUSE))
  319. {
  320. return (SOUND_ERR);
  321. }
  322. if ((flags & SOUND_FLAGS_QUEUESTREAM) || (flags & SOUND_FLAGS_QUEUESILENCE))
  323. {
  324. if (pstream->numqueued < (SOUND_MAX_STREAM_QUEUE - 1))
  325. {
  326. pqueue = &pstream->queue[pstream->queueindex];
  327. pqueue->offset = offset;
  328. pqueue->flags = flags;
  329. pqueue->vol = vol;
  330. pqueue->pan = pan;
  331. pqueue->numchannels = numchannels;
  332. pqueue->bitrate = bitrate;
  333. pqueue->fadetime = fadetime;
  334. pqueue->volfactorL = (real32)vol / SOUND_VOL_MAX;
  335. pqueue->volfactorR = (real32)vol / SOUND_VOL_MAX;
  336. pqueue->silencetime = silence;
  337. pqueue->actornum = actornum;
  338. pqueue->speechEvent = speechEvent;
  339. if (pmixpatch != NULL)
  340. {
  341. pqueue->pmixPatch = (PATCH *)pmixpatch;
  342. pqueue->mixLevel = level;
  343. }
  344. else
  345. {
  346. pqueue->pmixPatch = NULL;
  347. pqueue->mixLevel = SOUND_VOL_MIN;
  348. }
  349. pqueue->mixHandle = SOUND_DEFAULT;
  350. if (pan < SOUND_PAN_CENTER)
  351. {
  352. /* panned left so attenuate right */
  353. pqueue->volfactorR *= (real32)(SOUND_PAN_RIGHT + pan) / SOUND_PAN_RIGHT;
  354. }
  355. else if (pan > SOUND_PAN_CENTER)
  356. {
  357. /* panned right so attenuate left */
  358. pqueue->volfactorL *= (real32)(SOUND_PAN_RIGHT - pan) / SOUND_PAN_RIGHT;
  359. }
  360. if (pEQ != NULL)
  361. {
  362. pqueue->eq = pEQ;
  363. }
  364. else
  365. {
  366. pqueue->eq = NULL;
  367. }
  368. if (pdelay != NULL)
  369. {
  370. pqueue->delay = pdelay;
  371. }
  372. else
  373. {
  374. pqueue->delay = NULL;
  375. }
  376. if (peffect != NULL)
  377. {
  378. pqueue->effect = peffect;
  379. }
  380. else
  381. {
  382. pqueue->effect = NULL;
  383. }
  384. pstream->numqueued++;
  385. pstream->numtoplay++;
  386. pstream->queueindex++;
  387. if (pstream->queueindex >= SOUND_MAX_STREAM_QUEUE)
  388. {
  389. pstream->queueindex = 0;
  390. }
  391. pqueue->fhandle = filehandle;
  392. if ((pstream->status == SOUND_STREAM_INUSE) && !bWait)
  393. {
  394. pstream->blockstatus[0] = 0;
  395. pstream->blockstatus[1] = 0;
  396. pstream->readblock = 0;
  397. pstream->writeblock = 0;
  398. pstream->writepos = 0;
  399. pstream->status = SOUND_STREAM_STARTING;
  400. }
  401. }
  402. }
  403. else if (flags & SOUND_FLAGS_QUEUEPATCH)
  404. {
  405. if (pstream->numqueued < (SOUND_MAX_STREAM_QUEUE - 1))
  406. {
  407. ppatch = SNDgetpatch((void *)filehandle, offset);
  408. if (ppatch != NULL)
  409. {
  410. pqueue = &pstream->queue[pstream->queueindex];
  411. pqueue->offset = (sdword)ppatch;
  412. pqueue->flags = flags;
  413. pqueue->vol = vol;
  414. pqueue->pan = pan;
  415. pqueue->numchannels = numchannels;
  416. pqueue->bitrate = ppatch->bitrate;
  417. pqueue->fadetime = 0.0f;
  418. pqueue->volfactorL = (real32)vol / SOUND_VOL_MAX;
  419. pqueue->volfactorR = (real32)vol / SOUND_VOL_MAX;
  420. pqueue->pmixPatch = NULL;
  421. pqueue->mixLevel = SOUND_VOL_MIN;
  422. pqueue->mixHandle = SOUND_DEFAULT;
  423. pqueue->actornum = actornum;
  424. if (pan < SOUND_PAN_CENTER)
  425. {
  426. /* panned left so attenuate right */
  427. pqueue->volfactorR *= (real32)(SOUND_PAN_RIGHT + pan) / SOUND_PAN_RIGHT;
  428. }
  429. else if (pan > SOUND_PAN_CENTER)
  430. {
  431. /* panned right so attenuate left */
  432. pqueue->volfactorL *= (real32)(SOUND_PAN_RIGHT - pan) / SOUND_PAN_RIGHT;
  433. }
  434. if (pEQ != NULL)
  435. {
  436. pqueue->eq = pEQ;
  437. }
  438. else
  439. {
  440. pqueue->eq = NULL;
  441. }
  442. if (pdelay != NULL)
  443. {
  444. pqueue->delay = pdelay;
  445. }
  446. else
  447. {
  448. pqueue->delay = NULL;
  449. }
  450. if (peffect != NULL)
  451. {
  452. pqueue->effect = peffect;
  453. }
  454. else
  455. {
  456. pqueue->effect = NULL;
  457. }
  458. pstream->numqueued++;
  459. pstream->numtoplay++;
  460. pstream->queueindex++;
  461. if (pstream->queueindex >= SOUND_MAX_STREAM_QUEUE)
  462. {
  463. pstream->queueindex = 0;
  464. }
  465. pqueue->fhandle = filehandle;
  466. if ((pstream->status == SOUND_STREAM_INUSE) && !bWait)
  467. {
  468. pstream->blockstatus[0] = 0;
  469. pstream->blockstatus[1] = 0;
  470. pstream->readblock = 0;
  471. pstream->writeblock = 0;
  472. pstream->writepos = 0;
  473. pstream->status = SOUND_STREAM_STARTING;
  474. }
  475. }
  476. }
  477. }
  478. return (SOUND_OK);
  479. }
  480. /*-----------------------------------------------------------------------------
  481. Name : soundstreamvolume
  482. Description :
  483. Inputs : handle - the handle to a sound returned by soundplay
  484. vol - the volume to set this sound to (range of SOUND_MIN_VOL - SOUND_MAX_VOL)
  485. Outputs :
  486. Return : SOUND_OK if successful, SOUND_ERR on error
  487. ----------------------------------------------------------------------------*/
  488. sdword soundstreamvolume(sdword handle, sword vol, real32 fadetime)
  489. {
  490. HRESULT hr = SOUND_ERR;
  491. CHANNEL *pchan;
  492. sdword channel;
  493. bool stop = FALSE;
  494. sdword fadeblocks = -1;
  495. STREAM *pstream;
  496. sdword i;
  497. if (!soundinited)
  498. {
  499. return (SOUND_ERR);
  500. }
  501. if (streamer.status != SOUND_PLAYING)
  502. {
  503. return (SOUND_ERR);
  504. }
  505. if (vol > SOUND_VOL_MAX)
  506. {
  507. vol = SOUND_VOL_MAX;
  508. }
  509. else if (vol == -1)
  510. {
  511. vol = SOUND_VOL_MIN;
  512. stop = TRUE;
  513. }
  514. else if (vol <= SOUND_VOL_MIN)
  515. {
  516. vol = SOUND_VOL_MIN;
  517. }
  518. channel = SNDchannel(handle);
  519. if (channel < 0)
  520. {
  521. return (SOUND_ERR);
  522. }
  523. pchan = &speechchannels[channel];
  524. if (pchan != NULL)
  525. {
  526. fadeblocks = (sdword)(fadetime * SOUND_FADE_TIMETOBLOCKS);
  527. if (fadeblocks < NUM_FADE_BLOCKS)
  528. {
  529. fadeblocks = NUM_FADE_BLOCKS;
  530. }
  531. if ((vol != pchan->voltarget) || stop)
  532. {
  533. if (vol == (sword)pchan->volume)
  534. {
  535. pchan->voltarget = vol;
  536. pchan->volticksleft = 1;
  537. pchan->volfade = 0.0f;
  538. }
  539. else if (fadeblocks > 0)
  540. {
  541. pchan->voltarget = vol;
  542. pchan->volticksleft = fadeblocks;
  543. pchan->volfade = (real32)(pchan->voltarget - pchan->volume) / (real32)pchan->volticksleft;
  544. if (pchan->volfade == 0.0f)
  545. {
  546. pchan->volfade = 0.01f;
  547. if (pchan->voltarget < pchan->volume)
  548. {
  549. pchan->volfade = -0.01f;
  550. }
  551. }
  552. }
  553. else if (fadeblocks == -1)
  554. {
  555. pchan->voltarget = vol;
  556. pchan->volfade = 0.01f;
  557. pchan->volticksleft = ((sword)pchan->volume - vol) * 100;
  558. if (pchan->volticksleft < 0)
  559. {
  560. pchan->volticksleft *= -1;
  561. }
  562. }
  563. else
  564. {
  565. pchan->volume = vol;
  566. pchan->voltarget = vol;
  567. pchan->volticksleft = 1;
  568. pchan->volfade = 0.0f;
  569. }
  570. if (stop)
  571. {
  572. pchan->status = SOUND_STOPPING;
  573. /* need to clean up the queue */
  574. pstream = &streams[channel];
  575. pstream->writeindex = pstream->playindex;
  576. if (pstream->status == SOUND_STREAM_INUSE)
  577. {
  578. pstream->queueindex = pstream->writeindex;
  579. }
  580. else
  581. {
  582. pstream->queueindex = pstream->writeindex + 1;
  583. if (pstream->queueindex >= SOUND_MAX_STREAM_QUEUE)
  584. {
  585. pstream->queueindex = 0;
  586. }
  587. }
  588. // pstream->queue[pstream->writeindex].fhandle = SOUND_ERR;
  589. pstream->numqueued = 0;
  590. for (i = 0; i < SOUND_MAX_STREAM_QUEUE; i++)
  591. {
  592. if (i != pstream->playindex)
  593. {
  594. pstream->queue[i].fhandle = SOUND_ERR;
  595. }
  596. }
  597. }
  598. }
  599. }
  600. return (SOUND_OK);
  601. }
  602. /*-----------------------------------------------------------------------------
  603. Name : ssSubtitleRead
  604. Description : Read in a subtitle and pass it on to the subtitle code.
  605. Inputs : handle - handle of the file to read from, queued up to the
  606. start of the subtitle
  607. actornum - index of actor or -1 if there is no actor
  608. speechEvent - what speechEvent this was
  609. dataPeriod - inverse of data rate, in seconds/byte
  610. Outputs : header - header for the data of the speech phrase. We need
  611. to read this here to determine the length of the phrase.
  612. Return : length of subtitle info read or -1 if there is no subtitle
  613. ----------------------------------------------------------------------------*/
  614. sdword ssSubtitleRead(STREAMHEADER *header, filehandle handle, sdword actornum, sdword speechEvent, real32 dataPeriod)
  615. {
  616. sdword length, length2;
  617. char subTitle[SUB_SubtitleLength];
  618. real32 time;
  619. #if VCE_BACKWARDS_COMPATIBLE
  620. STREAMHEADER header2, headerTemp;
  621. udword currentOffset;
  622. #endif //VCE_BACKWARDS_COMPATIBLE
  623. length = fileBlockRead(handle, header, sizeof(STREAMHEADER));//read in the "INFO" and length
  624. dbgAssert(length == sizeof(STREAMHEADER));
  625. if (header->ID != ID_STREAM_INFO)
  626. { //if we didn't read "INFO"
  627. //!!!dbgAssert(header->ID == ID_STREAM_DATA); //it must have been "DATA"
  628. if (header->ID != ID_STREAM_DATA)
  629. {
  630. return(sizeof(STREAMHEADER)); //skip the subtitle
  631. }
  632. #if VCE_BACKWARDS_COMPATIBLE
  633. if (ssOldFormatVCE)
  634. { //if it's an old-format file
  635. currentOffset = fileSeek(handle, 0, FS_Current);//get current location in file
  636. fileSeek(handle, header->size, FS_Current); //seek to end of data to read in the info
  637. length2 = fileBlockRead(handle, &header2, sizeof(STREAMHEADER));//read in the "INFO" and length
  638. if (header2.ID != ID_STREAM_INFO)
  639. { //if didn't find data
  640. fileSeek(handle, currentOffset, FS_Start); //seek back to start of data
  641. }
  642. else
  643. { //it did find the info
  644. headerTemp = *header;
  645. *header = header2;
  646. goto foundInfo;
  647. }
  648. }
  649. #endif //VCE_BACKWARDS_COMPATIBLE
  650. return(sizeof(STREAMHEADER)); //skip the subtitle
  651. }
  652. #if VCE_BACKWARDS_COMPATIBLE
  653. foundInfo:;
  654. #endif
  655. dbgAssert(header->size >= 0);
  656. dbgAssert(header->size < SUB_SubtitleLength);
  657. length = fileBlockRead(handle, subTitle, header->size); //read in the actual subtitle
  658. dbgAssert(length == header->size);
  659. subTitle[header->size] = 0; //NULL-terminate the string (it's not terminated in the file)
  660. //now read in the "DATA" header
  661. #if VCE_BACKWARDS_COMPATIBLE
  662. if (ssOldFormatVCE)
  663. { //if it's old format
  664. fileSeek(handle, currentOffset, FS_Start); //seek back to start of data
  665. *header = headerTemp; //restore the header
  666. length = -length2; //so neither of these will be reported in the return length
  667. }
  668. else
  669. {
  670. length2 = fileBlockRead(handle, header, sizeof(STREAMHEADER));
  671. }
  672. #endif
  673. dbgAssert(length2 == sizeof(STREAMHEADER));
  674. //!!!dbgAssert(header->ID == ID_STREAM_DATA);
  675. time = (real32)header->size * dataPeriod;
  676. if (actornum >= 0 && length > 0)
  677. {
  678. if (actornum == 0)
  679. { //all single-player voices are on the same channel
  680. if (bitTest(speechEvent, ACTOR_FLEETCOMMAND_FLAG))
  681. {
  682. actornum = STA_FleetCommand;
  683. }
  684. else if (bitTest(speechEvent, ACTOR_FLEETINTEL_FLAG))
  685. {
  686. actornum = STA_FleetIntel;
  687. }
  688. else if (bitTest(speechEvent, ACTOR_TRADERS_FLAG))
  689. {
  690. actornum = STA_Traders;
  691. }
  692. else if (bitTest(speechEvent, ACTOR_PIRATES2_FLAG))
  693. {
  694. actornum = STA_Pirates2;
  695. }
  696. else if (bitTest(speechEvent, ACTOR_ALLSHIPSENEMY_FLAG))
  697. {
  698. actornum = STA_AllEnemyShips;
  699. }
  700. else if (bitTest(speechEvent, ACTOR_AMBASSADOR_FLAG))
  701. {
  702. actornum = STA_Ambassador;
  703. }
  704. else if (bitTest(speechEvent, ACTOR_NARRATOR_FLAG))
  705. {
  706. actornum = STA_Narrator;
  707. }
  708. else if (bitTest(speechEvent, ACTOR_DEFECTOR_FLAG))
  709. {
  710. actornum = STA_Defector;
  711. }
  712. else if (bitTest(speechEvent, ACTOR_EMPEROR_FLAG))
  713. {
  714. actornum = STA_Emperor;
  715. }
  716. else if (bitTest(speechEvent, ACTOR_KHARSELIM_FLAG))
  717. {
  718. actornum = STA_KharSelim;
  719. }
  720. else
  721. {
  722. //dbgFatalf(DBG_Loc, "Invalid actor 0x%x with speech event 0x%x", actornum, speechEvent);
  723. ;//just assume fleet command!!!is this valid?
  724. }
  725. }
  726. subTitleAdd(actornum, speechEvent, subTitle, length, time);
  727. }
  728. return(length + length2 + sizeof(STREAMHEADER));
  729. }
  730. sword soundstreamgetvol(sdword handle)
  731. {
  732. sdword channel;
  733. if (!soundinited)
  734. {
  735. return (SOUND_ERR);
  736. }
  737. if (streamer.status != SOUND_PLAYING)
  738. {
  739. return (SOUND_ERR);
  740. }
  741. channel = SNDchannel(handle);
  742. if (channel >= SOUND_OK)
  743. {
  744. return ((sword)speechchannels[channel].volume);
  745. }
  746. return (SOUND_ERR);
  747. }
  748. sdword isoundstreamreadheader(STREAM *pstream)
  749. {
  750. sdword ret, length, i;
  751. STREAMQUEUE *pqueue;
  752. PATCH *ppatch;
  753. pqueue = &pstream->queue[pstream->writeindex];
  754. if (pqueue->fhandle == SOUND_ERR)
  755. {
  756. if (pstream->numqueued == 1)
  757. {
  758. for (i = 0; i < SOUND_MAX_STREAM_QUEUE; i++)
  759. {
  760. if (pstream->queue[i].fhandle > 0)
  761. {
  762. pstream->writeindex = i;
  763. pstream->playindex = i;
  764. pstream->queueindex = i + 1;
  765. if (pstream->queueindex >= SOUND_MAX_STREAM_QUEUE)
  766. {
  767. pstream->queueindex = 0;
  768. }
  769. pqueue = &pstream->queue[pstream->writeindex];
  770. break;
  771. }
  772. }
  773. if (i == SOUND_MAX_STREAM_QUEUE)
  774. {
  775. pstream->dataleft = 0;
  776. pstream->numqueued = 0;
  777. return (-4); //(SOUND_ERR);
  778. }
  779. }
  780. else
  781. {
  782. pstream->dataleft = 0;
  783. pstream->numqueued--;
  784. if (pstream->numqueued < 0)
  785. {
  786. pstream->numqueued = 0;
  787. }
  788. return (-1); //(SOUND_ERR);
  789. }
  790. }
  791. if (pqueue->flags & SOUND_FLAGS_QUEUESTREAM)
  792. {
  793. ret = fileSeek(pqueue->fhandle, pqueue->offset, FS_Start); //pstream->lastpos);
  794. if (ret != pqueue->offset)
  795. {
  796. /* yuck, bad */
  797. return (-2); //(SOUND_ERR);
  798. }
  799. //read in the subTitle, if there is any
  800. length = ssSubtitleRead(&pstream->header, pqueue->fhandle, pqueue->actornum, pqueue->speechEvent, pstream->dataPeriod); //read the subtitle
  801. pstream->lastpos = ret + length;
  802. if (pstream->header.ID != ID_STREAM_DATA)
  803. {
  804. /* this is not stream data */
  805. dbgMessage("\nsoundstreamreadheader: bad ID");
  806. return (-3); //(SOUND_ERR);
  807. }
  808. // need to assign a size to this item
  809. pqueue->size = pstream->header.size;
  810. if (pqueue->pmixPatch != NULL)
  811. {
  812. pqueue->mixHandle = splayMUTE((void *)pqueue->pmixPatch, SOUND_FLAGS_PATCHPOINTER, pqueue->pan, SOUND_PRIORITY_STREAM, pqueue->mixLevel);
  813. }
  814. }
  815. else if (pqueue->flags & SOUND_FLAGS_QUEUEPATCH)
  816. {
  817. ppatch = (PATCH *)pqueue->offset;
  818. pstream->header.ID = ppatch->id;
  819. pstream->header.size = ppatch->datasize - ppatch->dataoffset;
  820. pstream->lastpos = ppatch->dataoffset;
  821. // need to assign a size to this item
  822. pqueue->size = pstream->header.size;
  823. }
  824. else if (pqueue->flags & SOUND_FLAGS_QUEUESILENCE)
  825. {
  826. pstream->header.ID = 0;
  827. pstream->header.size = (sdword)(pqueue->silencetime * SOUND_FADE_TIMETOBLOCKS * (pqueue->bitrate >> 3)); // * bitrate?
  828. pstream->lastpos = 0;
  829. if (pqueue->pmixPatch != NULL)
  830. {
  831. pqueue->mixHandle = splayMUTE((void *)pqueue->pmixPatch, SOUND_FLAGS_PATCHPOINTER, pqueue->pan, SOUND_PRIORITY_STREAM, pqueue->mixLevel);
  832. }
  833. }
  834. pstream->dataleft = pstream->header.size;
  835. pstream->numqueued--;
  836. return (SOUND_OK);
  837. }
  838. sdword isoundstreamreadblock(STREAMQUEUE *pqueue, void *buffer, sdword position, sdword size)
  839. {
  840. sdword ret = SOUND_ERR;
  841. if (pqueue->fhandle == -1)
  842. {
  843. return (-1);
  844. }
  845. if (pqueue->flags & SOUND_FLAGS_QUEUESTREAM)
  846. {
  847. /* read a block of data */
  848. ret = fileSeek(pqueue->fhandle, position, FS_Start);
  849. if (ret != position)
  850. {
  851. /* yuck, bad */
  852. return (-2);
  853. }
  854. ret = fileBlockRead(pqueue->fhandle, buffer, size);
  855. if (ret != size)
  856. {
  857. /* yuck, bad */
  858. dbgMessagef("\nsoundstreamupdate95: couldn't read file block.");
  859. return (-3);
  860. }
  861. }
  862. else if (pqueue->flags & SOUND_FLAGS_QUEUEPATCH)
  863. {
  864. memcpy((sbyte *)buffer, (sbyte *)position, size);
  865. ret = size;
  866. }
  867. else if (pqueue->flags & SOUND_FLAGS_QUEUESILENCE)
  868. {
  869. // memset((sbyte *)buffer, 0, size);
  870. ret = size;
  871. }
  872. return (ret);
  873. }
  874. void isoundstreamcleanup(void)
  875. {
  876. sdword i;
  877. /* clean up all the streams */
  878. for (i = 0; i < numstreams; i++)
  879. {
  880. streams[i].status = SOUND_STREAM_INUSE;
  881. streams[i].buffersize = SOUND_STREAM_BUFFER_SIZE;
  882. memset(streams[i].buffer, 0, SOUND_STREAM_BUFFER_SIZE);
  883. speechchannels[i].currentpos = speechchannels[i].freqdata = (sbyte *)streams[i].buffer;
  884. streams[i].writepos = streams[i].buffer;
  885. streams[i].readblock = 0;
  886. streams[i].writeblock = 0;
  887. }
  888. }
  889. /*-----------------------------------------------------------------------------
  890. Name :
  891. Description :
  892. Inputs :
  893. Outputs :
  894. Return :
  895. ----------------------------------------------------------------------------*/
  896. void isoundstreamupdate(void *dummy)
  897. {
  898. sdword i;
  899. STREAM *pstream;
  900. CHANNEL *pchan;
  901. sdword ret;
  902. sdword readsize;
  903. BYTE *bufferpos;
  904. sdword bufsize;
  905. STREAMQUEUE *pqueue;
  906. if (streams == NULL)
  907. {
  908. /* not inited yet */
  909. return;
  910. }
  911. while (soundinited && (streamer.status >= SOUND_STOPPED))
  912. {
  913. if (streamer.status == SOUND_STOPPING)
  914. {
  915. /* check and see if its done yet */
  916. if (streamer.timeout <= mixerticks)
  917. {
  918. isoundstreamcleanup();
  919. streamer.timeout = 0;
  920. streamer.status = SOUND_STOPPED;
  921. }
  922. }
  923. if (bSoundDeactivated && (streamer.status == SOUND_PLAYING) && !bSoundPaused)
  924. {
  925. // isoundstreamcleanup();
  926. // streamer.status = SOUND_STOPPED;
  927. streamer.status = SOUND_PAUSED;
  928. }
  929. if ((streamer.status >= SOUND_PLAYING) && (streamer.status < SOUND_PAUSED))
  930. {
  931. if (bSoundPaused && (streamer.status == SOUND_PLAYING))
  932. {
  933. streamer.status = SOUND_STOPPING;
  934. }
  935. for (i = 0; i < numstreams; i++)
  936. {
  937. pstream = &streams[i];
  938. pchan = &speechchannels[i];
  939. pqueue = &pstream->queue[pstream->writeindex];
  940. if (pstream->status == SOUND_STREAM_STARTING)
  941. {
  942. pstream->playindex = pstream->writeindex;
  943. ret = isoundstreamreadheader(pstream);
  944. if (ret != SOUND_OK)
  945. {
  946. // bad
  947. /* dbgMessagef("\nsoundstreamupdate95: couldn't read stream header.");
  948. pqueue->fhandle = SOUND_ERR;
  949. dbgMessagef("\nisoundstreamreadheader returned %d\n", ret);
  950. dbgAssert(FALSE); */
  951. goto Recover;
  952. }
  953. else
  954. {
  955. if ((pstream->readblock != pstream->writeblock) && (pstream->blockstatus[pstream->readblock] == 0))
  956. {
  957. pstream->writeblock = pstream->readblock;
  958. }
  959. pstream->status = SOUND_STREAM_WRITING;
  960. pchan->volfactorL = pqueue->volfactorL;
  961. pchan->volfactorR = pqueue->volfactorR;
  962. pchan->voltarget = pqueue->vol;
  963. if (pqueue->fadetime != 0.0f)
  964. {
  965. pchan->volume = 0.0f;
  966. pchan->volticksleft = (sdword)(pqueue->fadetime * SOUND_FADE_TIMETOBLOCKS);
  967. pchan->volfade = (real32)(pchan->voltarget - pchan->volume) / (real32)pchan->volticksleft;
  968. if (pchan->volfade == 0.0f)
  969. {
  970. pchan->volfade = 0.01f;
  971. if (pchan->voltarget < pchan->volume)
  972. {
  973. pchan->volfade = -0.01f;
  974. }
  975. }
  976. }
  977. else
  978. {
  979. pchan->volume = (real32)pqueue->vol;
  980. pchan->volticksleft = 0;
  981. pchan->volfade = 0.0f;
  982. }
  983. pchan->pan = pqueue->pan;
  984. pchan->numchannels = pqueue->numchannels;
  985. pchan->bitrate = pqueue->bitrate;
  986. pchan->amountread = 0;
  987. bufsize = SOUND_STREAM_BUFFER_SIZE;
  988. if (bufsize % ((pchan->bitrate >> 3) * 8))
  989. {
  990. bufsize /= ((pchan->bitrate >> 3) * 8);
  991. bufsize *= ((pchan->bitrate >> 3) * 8);
  992. }
  993. pstream->buffersize = bufsize;
  994. pstream->blocksize = pstream->buffersize / 2;
  995. pchan->endpos = (sbyte *)(pstream->buffer + pstream->buffersize);
  996. pchan->currentpos = (sbyte *)pstream->buffer;
  997. pstream->numtoplay--;
  998. pchan->status = SOUND_PLAYING;
  999. }
  1000. }
  1001. if (pstream->status == SOUND_STREAM_WRITING)
  1002. {
  1003. if (pstream->blockstatus[pstream->writeblock] == 0)
  1004. {
  1005. if (pstream->dataleft == 0)
  1006. { /* HMMM, WE'RE OUT OF DATA HERE */
  1007. if (pqueue->flags & SOUND_FLAGS_LOOPING)
  1008. {
  1009. /* LOOKS LIKE A LOOPER, BACK TO THE START YOU GO */
  1010. isoundstreamreadheader(pstream);
  1011. }
  1012. else
  1013. {
  1014. /* IS THERE ANOTHER STREAM IN THE HOUSE? */
  1015. pqueue->fhandle = SOUND_ERR;
  1016. pqueue->nextplay = pstream->buffer + (pstream->blocksize * pstream->writeblock);
  1017. pstream->writeindex++;
  1018. if (pstream->writeindex >= SOUND_MAX_STREAM_QUEUE)
  1019. {
  1020. pstream->writeindex = 0;
  1021. }
  1022. pqueue = &pstream->queue[pstream->writeindex];
  1023. if (pqueue->fhandle != SOUND_ERR)
  1024. {
  1025. isoundstreamreadheader(pstream);
  1026. }
  1027. else
  1028. {
  1029. pstream->status = SOUND_STREAM_INUSE;
  1030. pstream->queueindex = 0;
  1031. pstream->writeindex = 0;
  1032. pstream->numqueued = 0;
  1033. pchan->status = SOUND_STOPPING;
  1034. continue;
  1035. }
  1036. }
  1037. }
  1038. if (pstream->dataleft >= pstream->blocksize)
  1039. {
  1040. /* WE HAVE LOTS OF DATA HERE */
  1041. ret = isoundstreamreadblock(pqueue, (void *)(pstream->buffer + (pstream->blocksize * pstream->writeblock)), pstream->lastpos, pstream->blocksize);
  1042. if (ret != pstream->blocksize)
  1043. {
  1044. /* yuck, bad */
  1045. /* dbgMessagef("\nsoundstreamupdate95: couldn't read file block.");*/
  1046. goto Recover;
  1047. }
  1048. pstream->lastpos += ret;
  1049. pstream->dataleft -= pstream->blocksize;
  1050. }
  1051. else
  1052. {
  1053. /* HMMM, GETTING KINDA LOW, NEED A TOP UP */
  1054. ret = isoundstreamreadblock(pqueue, (void *)(pstream->buffer + (pstream->blocksize * pstream->writeblock)), pstream->lastpos, pstream->dataleft);
  1055. if (ret != pstream->dataleft)
  1056. {
  1057. /* yuck, bad */
  1058. /* dbgMessagef("\nsoundstreamupdate95: couldn't read file block."); */
  1059. goto Recover;
  1060. }
  1061. pstream->lastpos += ret;
  1062. if (!(pqueue->flags & SOUND_FLAGS_LOOPING))
  1063. {
  1064. /* IS THERE ANOTHER STREAM IN THE HOUSE? */
  1065. pqueue->fhandle = SOUND_ERR;
  1066. pqueue->nextplay = pstream->buffer + (pstream->blocksize * pstream->writeblock) + pstream->dataleft;
  1067. pstream->writeindex++;
  1068. if (pstream->writeindex >= SOUND_MAX_STREAM_QUEUE)
  1069. {
  1070. pstream->writeindex = 0;
  1071. }
  1072. pqueue = &pstream->queue[pstream->writeindex];
  1073. }
  1074. readsize = pstream->blocksize - pstream->dataleft;
  1075. bufferpos = pstream->buffer + (pstream->blocksize * pstream->writeblock) + pstream->dataleft;
  1076. pstream->dataleft = 0;
  1077. if (pqueue->fhandle != SOUND_ERR)
  1078. {
  1079. /* LOOKS LIKE WE HAVE ANOTHER STREAM HERE */
  1080. isoundstreamreadheader(pstream);
  1081. if (pstream->dataleft >= readsize)
  1082. {
  1083. /* read a block of data */
  1084. ret = isoundstreamreadblock(pqueue, (void *)(bufferpos), pstream->lastpos, readsize);
  1085. if (ret != readsize)
  1086. {
  1087. /* yuck, bad */
  1088. }
  1089. pstream->lastpos += ret;
  1090. pstream->dataleft -= readsize;
  1091. }
  1092. else
  1093. {
  1094. ret = isoundstreamreadblock(pqueue, (void *)(bufferpos), pstream->lastpos, pstream->dataleft);
  1095. if (ret != pstream->dataleft)
  1096. {
  1097. /*bad*/
  1098. /* dbgAssert(FALSE); */
  1099. goto Recover;
  1100. }
  1101. if (pstream->writeindex + 1 >= SOUND_MAX_STREAM_QUEUE)
  1102. {
  1103. if (pstream->queue[0].fhandle != SOUND_ERR)
  1104. {
  1105. memset(bufferpos + pstream->dataleft, 0, readsize - pstream->dataleft);
  1106. }
  1107. else
  1108. {
  1109. pstream->writepos = bufferpos + pstream->dataleft;
  1110. }
  1111. }
  1112. else
  1113. {
  1114. if (pstream->queue[pstream->writeindex+1].fhandle != SOUND_ERR)
  1115. {
  1116. memset(bufferpos + pstream->dataleft, 0, readsize - pstream->dataleft);
  1117. }
  1118. else
  1119. {
  1120. pstream->writepos = bufferpos + pstream->dataleft;
  1121. }
  1122. }
  1123. pstream->lastpos += ret;
  1124. pstream->dataleft = 0;
  1125. }
  1126. }
  1127. else
  1128. {
  1129. /* NO MORE STREAMS FOR NOW, BYE, BYE */
  1130. pstream->writepos = bufferpos;
  1131. pstream->status = SOUND_STREAM_INUSE;
  1132. pstream->queueindex = 0;
  1133. pstream->writeindex = 0;
  1134. pstream->numqueued = 0;
  1135. pchan->status = SOUND_STOPPING;
  1136. }
  1137. }
  1138. pstream->blockstatus[pstream->writeblock++] = 1;
  1139. if (pstream->writeblock >= 2)
  1140. {
  1141. pstream->writeblock = 0;
  1142. }
  1143. }
  1144. }
  1145. continue;
  1146. Recover:
  1147. {
  1148. /* IS THERE ANOTHER STREAM IN THE HOUSE? */
  1149. pqueue->fhandle = SOUND_ERR;
  1150. pqueue->nextplay = pstream->buffer + (pstream->blocksize * pstream->writeblock);
  1151. pstream->writeindex++;
  1152. if (pstream->writeindex >= SOUND_MAX_STREAM_QUEUE)
  1153. {
  1154. pstream->writeindex = 0;
  1155. }
  1156. pqueue = &pstream->queue[pstream->writeindex];
  1157. if (pqueue->fhandle != SOUND_ERR)
  1158. {
  1159. isoundstreamreadheader(pstream);
  1160. }
  1161. else
  1162. {
  1163. pstream->status = SOUND_STREAM_INUSE;
  1164. pstream->queueindex = 0;
  1165. pstream->writeindex = 0;
  1166. pstream->numqueued = 0;
  1167. pchan->status = SOUND_STOPPING;
  1168. continue;
  1169. }
  1170. }
  1171. }
  1172. }
  1173. else if (streamer.status == SOUND_STOPPED)
  1174. {
  1175. /* mixer is paused so don't do nothing */
  1176. if (!bSoundPaused) // && (!bSoundDeactivated))
  1177. {
  1178. streamer.status = SOUND_PLAYING;
  1179. }
  1180. }
  1181. else if (streamer.status == SOUND_PAUSED)
  1182. {
  1183. if (!bSoundDeactivated)
  1184. {
  1185. streamer.status = SOUND_PLAYING;
  1186. }
  1187. }
  1188. Sleep(SOUND_STREAM_SLEEP);
  1189. }
  1190. /* clean up all the streams */
  1191. for (i = 0; i < numstreams; i++)
  1192. {
  1193. streams[i].status = SOUND_STREAM_INUSE;
  1194. streams[i].buffersize = SOUND_STREAM_BUFFER_SIZE;
  1195. memset(streams[i].buffer, 0, SOUND_STREAM_BUFFER_SIZE);
  1196. speechchannels[i].currentpos = speechchannels[i].freqdata = (sbyte *)streams[i].buffer;
  1197. streams[i].writepos = streams[i].buffer;
  1198. streams[i].readblock = 0;
  1199. streams[i].writeblock = 0;
  1200. }
  1201. streamer.status = SOUND_FREE;
  1202. _endthread();
  1203. }