snd_dma.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215
  1. /*
  2. Copyright (C) 1997-2001 Id Software, Inc.
  3. This program is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU General Public License
  5. as published by the Free Software Foundation; either version 2
  6. of the License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. See the GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  14. */
  15. // snd_dma.c -- main control for any streaming sound output device
  16. #include "client.h"
  17. #include "snd_loc.h"
  18. void S_Play(void);
  19. void S_SoundList(void);
  20. void S_Update_();
  21. void S_StopAllSounds(void);
  22. // =======================================================================
  23. // Internal sound data & structures
  24. // =======================================================================
  25. // only begin attenuating sound volumes when outside the FULLVOLUME range
  26. #define SOUND_FULLVOLUME 80
  27. #define SOUND_LOOPATTENUATE 0.003
  28. int s_registration_sequence;
  29. channel_t channels[MAX_CHANNELS];
  30. qboolean snd_initialized = false;
  31. int sound_started=0;
  32. dma_t dma;
  33. vec3_t listener_origin;
  34. vec3_t listener_forward;
  35. vec3_t listener_right;
  36. vec3_t listener_up;
  37. qboolean s_registering;
  38. int soundtime; // sample PAIRS
  39. int paintedtime; // sample PAIRS
  40. // during registration it is possible to have more sounds
  41. // than could actually be referenced during gameplay,
  42. // because we don't want to free anything until we are
  43. // sure we won't need it.
  44. #define MAX_SFX (MAX_SOUNDS*2)
  45. sfx_t known_sfx[MAX_SFX];
  46. int num_sfx;
  47. #define MAX_PLAYSOUNDS 128
  48. playsound_t s_playsounds[MAX_PLAYSOUNDS];
  49. playsound_t s_freeplays;
  50. playsound_t s_pendingplays;
  51. int s_beginofs;
  52. cvar_t *s_volume;
  53. cvar_t *s_testsound;
  54. cvar_t *s_loadas8bit;
  55. cvar_t *s_khz;
  56. cvar_t *s_show;
  57. cvar_t *s_mixahead;
  58. cvar_t *s_primary;
  59. int s_rawend;
  60. portable_samplepair_t s_rawsamples[MAX_RAW_SAMPLES];
  61. // ====================================================================
  62. // User-setable variables
  63. // ====================================================================
  64. void S_SoundInfo_f(void)
  65. {
  66. if (!sound_started)
  67. {
  68. Com_Printf ("sound system not started\n");
  69. return;
  70. }
  71. Com_Printf("%5d stereo\n", dma.channels - 1);
  72. Com_Printf("%5d samples\n", dma.samples);
  73. Com_Printf("%5d samplepos\n", dma.samplepos);
  74. Com_Printf("%5d samplebits\n", dma.samplebits);
  75. Com_Printf("%5d submission_chunk\n", dma.submission_chunk);
  76. Com_Printf("%5d speed\n", dma.speed);
  77. Com_Printf("0x%x dma buffer\n", dma.buffer);
  78. }
  79. /*
  80. ================
  81. S_Init
  82. ================
  83. */
  84. void S_Init (void)
  85. {
  86. cvar_t *cv;
  87. Com_Printf("\n------- sound initialization -------\n");
  88. cv = Cvar_Get ("s_initsound", "1", 0);
  89. if (!cv->value)
  90. Com_Printf ("not initializing.\n");
  91. else
  92. {
  93. s_volume = Cvar_Get ("s_volume", "0.7", CVAR_ARCHIVE);
  94. s_khz = Cvar_Get ("s_khz", "11", CVAR_ARCHIVE);
  95. s_loadas8bit = Cvar_Get ("s_loadas8bit", "1", CVAR_ARCHIVE);
  96. s_mixahead = Cvar_Get ("s_mixahead", "0.2", CVAR_ARCHIVE);
  97. s_show = Cvar_Get ("s_show", "0", 0);
  98. s_testsound = Cvar_Get ("s_testsound", "0", 0);
  99. s_primary = Cvar_Get ("s_primary", "0", CVAR_ARCHIVE); // win32 specific
  100. Cmd_AddCommand("play", S_Play);
  101. Cmd_AddCommand("stopsound", S_StopAllSounds);
  102. Cmd_AddCommand("soundlist", S_SoundList);
  103. Cmd_AddCommand("soundinfo", S_SoundInfo_f);
  104. if (!SNDDMA_Init())
  105. return;
  106. S_InitScaletable ();
  107. sound_started = 1;
  108. num_sfx = 0;
  109. soundtime = 0;
  110. paintedtime = 0;
  111. Com_Printf ("sound sampling rate: %i\n", dma.speed);
  112. S_StopAllSounds ();
  113. }
  114. Com_Printf("------------------------------------\n");
  115. }
  116. // =======================================================================
  117. // Shutdown sound engine
  118. // =======================================================================
  119. void S_Shutdown(void)
  120. {
  121. int i;
  122. sfx_t *sfx;
  123. if (!sound_started)
  124. return;
  125. SNDDMA_Shutdown();
  126. sound_started = 0;
  127. Cmd_RemoveCommand("play");
  128. Cmd_RemoveCommand("stopsound");
  129. Cmd_RemoveCommand("soundlist");
  130. Cmd_RemoveCommand("soundinfo");
  131. // free all sounds
  132. for (i=0, sfx=known_sfx ; i < num_sfx ; i++,sfx++)
  133. {
  134. if (!sfx->name[0])
  135. continue;
  136. if (sfx->cache)
  137. Z_Free (sfx->cache);
  138. memset (sfx, 0, sizeof(*sfx));
  139. }
  140. num_sfx = 0;
  141. }
  142. // =======================================================================
  143. // Load a sound
  144. // =======================================================================
  145. /*
  146. ==================
  147. S_FindName
  148. ==================
  149. */
  150. sfx_t *S_FindName (char *name, qboolean create)
  151. {
  152. int i;
  153. sfx_t *sfx;
  154. if (!name)
  155. Com_Error (ERR_FATAL, "S_FindName: NULL\n");
  156. if (!name[0])
  157. Com_Error (ERR_FATAL, "S_FindName: empty name\n");
  158. if (strlen(name) >= MAX_QPATH)
  159. Com_Error (ERR_FATAL, "Sound name too long: %s", name);
  160. // see if already loaded
  161. for (i=0 ; i < num_sfx ; i++)
  162. if (!strcmp(known_sfx[i].name, name))
  163. {
  164. return &known_sfx[i];
  165. }
  166. if (!create)
  167. return NULL;
  168. // find a free sfx
  169. for (i=0 ; i < num_sfx ; i++)
  170. if (!known_sfx[i].name[0])
  171. // registration_sequence < s_registration_sequence)
  172. break;
  173. if (i == num_sfx)
  174. {
  175. if (num_sfx == MAX_SFX)
  176. Com_Error (ERR_FATAL, "S_FindName: out of sfx_t");
  177. num_sfx++;
  178. }
  179. sfx = &known_sfx[i];
  180. memset (sfx, 0, sizeof(*sfx));
  181. strcpy (sfx->name, name);
  182. sfx->registration_sequence = s_registration_sequence;
  183. return sfx;
  184. }
  185. /*
  186. ==================
  187. S_AliasName
  188. ==================
  189. */
  190. sfx_t *S_AliasName (char *aliasname, char *truename)
  191. {
  192. sfx_t *sfx;
  193. char *s;
  194. int i;
  195. s = Z_Malloc (MAX_QPATH);
  196. strcpy (s, truename);
  197. // find a free sfx
  198. for (i=0 ; i < num_sfx ; i++)
  199. if (!known_sfx[i].name[0])
  200. break;
  201. if (i == num_sfx)
  202. {
  203. if (num_sfx == MAX_SFX)
  204. Com_Error (ERR_FATAL, "S_FindName: out of sfx_t");
  205. num_sfx++;
  206. }
  207. sfx = &known_sfx[i];
  208. memset (sfx, 0, sizeof(*sfx));
  209. strcpy (sfx->name, aliasname);
  210. sfx->registration_sequence = s_registration_sequence;
  211. sfx->truename = s;
  212. return sfx;
  213. }
  214. /*
  215. =====================
  216. S_BeginRegistration
  217. =====================
  218. */
  219. void S_BeginRegistration (void)
  220. {
  221. s_registration_sequence++;
  222. s_registering = true;
  223. }
  224. /*
  225. ==================
  226. S_RegisterSound
  227. ==================
  228. */
  229. sfx_t *S_RegisterSound (char *name)
  230. {
  231. sfx_t *sfx;
  232. if (!sound_started)
  233. return NULL;
  234. sfx = S_FindName (name, true);
  235. sfx->registration_sequence = s_registration_sequence;
  236. if (!s_registering)
  237. S_LoadSound (sfx);
  238. return sfx;
  239. }
  240. /*
  241. =====================
  242. S_EndRegistration
  243. =====================
  244. */
  245. void S_EndRegistration (void)
  246. {
  247. int i;
  248. sfx_t *sfx;
  249. int size;
  250. // free any sounds not from this registration sequence
  251. for (i=0, sfx=known_sfx ; i < num_sfx ; i++,sfx++)
  252. {
  253. if (!sfx->name[0])
  254. continue;
  255. if (sfx->registration_sequence != s_registration_sequence)
  256. { // don't need this sound
  257. if (sfx->cache) // it is possible to have a leftover
  258. Z_Free (sfx->cache); // from a server that didn't finish loading
  259. memset (sfx, 0, sizeof(*sfx));
  260. }
  261. else
  262. { // make sure it is paged in
  263. if (sfx->cache)
  264. {
  265. size = sfx->cache->length*sfx->cache->width;
  266. Com_PageInMemory ((byte *)sfx->cache, size);
  267. }
  268. }
  269. }
  270. // load everything in
  271. for (i=0, sfx=known_sfx ; i < num_sfx ; i++,sfx++)
  272. {
  273. if (!sfx->name[0])
  274. continue;
  275. S_LoadSound (sfx);
  276. }
  277. s_registering = false;
  278. }
  279. //=============================================================================
  280. /*
  281. =================
  282. S_PickChannel
  283. =================
  284. */
  285. channel_t *S_PickChannel(int entnum, int entchannel)
  286. {
  287. int ch_idx;
  288. int first_to_die;
  289. int life_left;
  290. channel_t *ch;
  291. if (entchannel<0)
  292. Com_Error (ERR_DROP, "S_PickChannel: entchannel<0");
  293. // Check for replacement sound, or find the best one to replace
  294. first_to_die = -1;
  295. life_left = 0x7fffffff;
  296. for (ch_idx=0 ; ch_idx < MAX_CHANNELS ; ch_idx++)
  297. {
  298. if (entchannel != 0 // channel 0 never overrides
  299. && channels[ch_idx].entnum == entnum
  300. && channels[ch_idx].entchannel == entchannel)
  301. { // always override sound from same entity
  302. first_to_die = ch_idx;
  303. break;
  304. }
  305. // don't let monster sounds override player sounds
  306. if (channels[ch_idx].entnum == cl.playernum+1 && entnum != cl.playernum+1 && channels[ch_idx].sfx)
  307. continue;
  308. if (channels[ch_idx].end - paintedtime < life_left)
  309. {
  310. life_left = channels[ch_idx].end - paintedtime;
  311. first_to_die = ch_idx;
  312. }
  313. }
  314. if (first_to_die == -1)
  315. return NULL;
  316. ch = &channels[first_to_die];
  317. memset (ch, 0, sizeof(*ch));
  318. return ch;
  319. }
  320. /*
  321. =================
  322. S_SpatializeOrigin
  323. Used for spatializing channels and autosounds
  324. =================
  325. */
  326. void S_SpatializeOrigin (vec3_t origin, float master_vol, float dist_mult, int *left_vol, int *right_vol)
  327. {
  328. vec_t dot;
  329. vec_t dist;
  330. vec_t lscale, rscale, scale;
  331. vec3_t source_vec;
  332. if (cls.state != ca_active)
  333. {
  334. *left_vol = *right_vol = 255;
  335. return;
  336. }
  337. // calculate stereo seperation and distance attenuation
  338. VectorSubtract(origin, listener_origin, source_vec);
  339. dist = VectorNormalize(source_vec);
  340. dist -= SOUND_FULLVOLUME;
  341. if (dist < 0)
  342. dist = 0; // close enough to be at full volume
  343. dist *= dist_mult; // different attenuation levels
  344. dot = DotProduct(listener_right, source_vec);
  345. if (dma.channels == 1 || !dist_mult)
  346. { // no attenuation = no spatialization
  347. rscale = 1.0;
  348. lscale = 1.0;
  349. }
  350. else
  351. {
  352. rscale = 0.5 * (1.0 + dot);
  353. lscale = 0.5*(1.0 - dot);
  354. }
  355. // add in distance effect
  356. scale = (1.0 - dist) * rscale;
  357. *right_vol = (int) (master_vol * scale);
  358. if (*right_vol < 0)
  359. *right_vol = 0;
  360. scale = (1.0 - dist) * lscale;
  361. *left_vol = (int) (master_vol * scale);
  362. if (*left_vol < 0)
  363. *left_vol = 0;
  364. }
  365. /*
  366. =================
  367. S_Spatialize
  368. =================
  369. */
  370. void S_Spatialize(channel_t *ch)
  371. {
  372. vec3_t origin;
  373. // anything coming from the view entity will always be full volume
  374. if (ch->entnum == cl.playernum+1)
  375. {
  376. ch->leftvol = ch->master_vol;
  377. ch->rightvol = ch->master_vol;
  378. return;
  379. }
  380. if (ch->fixed_origin)
  381. {
  382. VectorCopy (ch->origin, origin);
  383. }
  384. else
  385. CL_GetEntitySoundOrigin (ch->entnum, origin);
  386. S_SpatializeOrigin (origin, ch->master_vol, ch->dist_mult, &ch->leftvol, &ch->rightvol);
  387. }
  388. /*
  389. =================
  390. S_AllocPlaysound
  391. =================
  392. */
  393. playsound_t *S_AllocPlaysound (void)
  394. {
  395. playsound_t *ps;
  396. ps = s_freeplays.next;
  397. if (ps == &s_freeplays)
  398. return NULL; // no free playsounds
  399. // unlink from freelist
  400. ps->prev->next = ps->next;
  401. ps->next->prev = ps->prev;
  402. return ps;
  403. }
  404. /*
  405. =================
  406. S_FreePlaysound
  407. =================
  408. */
  409. void S_FreePlaysound (playsound_t *ps)
  410. {
  411. // unlink from channel
  412. ps->prev->next = ps->next;
  413. ps->next->prev = ps->prev;
  414. // add to free list
  415. ps->next = s_freeplays.next;
  416. s_freeplays.next->prev = ps;
  417. ps->prev = &s_freeplays;
  418. s_freeplays.next = ps;
  419. }
  420. /*
  421. ===============
  422. S_IssuePlaysound
  423. Take the next playsound and begin it on the channel
  424. This is never called directly by S_Play*, but only
  425. by the update loop.
  426. ===============
  427. */
  428. void S_IssuePlaysound (playsound_t *ps)
  429. {
  430. channel_t *ch;
  431. sfxcache_t *sc;
  432. if (s_show->value)
  433. Com_Printf ("Issue %i\n", ps->begin);
  434. // pick a channel to play on
  435. ch = S_PickChannel(ps->entnum, ps->entchannel);
  436. if (!ch)
  437. {
  438. S_FreePlaysound (ps);
  439. return;
  440. }
  441. // spatialize
  442. if (ps->attenuation == ATTN_STATIC)
  443. ch->dist_mult = ps->attenuation * 0.001;
  444. else
  445. ch->dist_mult = ps->attenuation * 0.0005;
  446. ch->master_vol = ps->volume;
  447. ch->entnum = ps->entnum;
  448. ch->entchannel = ps->entchannel;
  449. ch->sfx = ps->sfx;
  450. VectorCopy (ps->origin, ch->origin);
  451. ch->fixed_origin = ps->fixed_origin;
  452. S_Spatialize(ch);
  453. ch->pos = 0;
  454. sc = S_LoadSound (ch->sfx);
  455. ch->end = paintedtime + sc->length;
  456. // free the playsound
  457. S_FreePlaysound (ps);
  458. }
  459. struct sfx_s *S_RegisterSexedSound (entity_state_t *ent, char *base)
  460. {
  461. int n;
  462. char *p;
  463. struct sfx_s *sfx;
  464. FILE *f;
  465. char model[MAX_QPATH];
  466. char sexedFilename[MAX_QPATH];
  467. char maleFilename[MAX_QPATH];
  468. // determine what model the client is using
  469. model[0] = 0;
  470. n = CS_PLAYERSKINS + ent->number - 1;
  471. if (cl.configstrings[n][0])
  472. {
  473. p = strchr(cl.configstrings[n], '\\');
  474. if (p)
  475. {
  476. p += 1;
  477. strcpy(model, p);
  478. p = strchr(model, '/');
  479. if (p)
  480. *p = 0;
  481. }
  482. }
  483. // if we can't figure it out, they're male
  484. if (!model[0])
  485. strcpy(model, "male");
  486. // see if we already know of the model specific sound
  487. Com_sprintf (sexedFilename, sizeof(sexedFilename), "#players/%s/%s", model, base+1);
  488. sfx = S_FindName (sexedFilename, false);
  489. if (!sfx)
  490. {
  491. // no, so see if it exists
  492. FS_FOpenFile (&sexedFilename[1], &f);
  493. if (f)
  494. {
  495. // yes, close the file and register it
  496. FS_FCloseFile (f);
  497. sfx = S_RegisterSound (sexedFilename);
  498. }
  499. else
  500. {
  501. // no, revert to the male sound in the pak0.pak
  502. Com_sprintf (maleFilename, sizeof(maleFilename), "player/%s/%s", "male", base+1);
  503. sfx = S_AliasName (sexedFilename, maleFilename);
  504. }
  505. }
  506. return sfx;
  507. }
  508. // =======================================================================
  509. // Start a sound effect
  510. // =======================================================================
  511. /*
  512. ====================
  513. S_StartSound
  514. Validates the parms and ques the sound up
  515. if pos is NULL, the sound will be dynamically sourced from the entity
  516. Entchannel 0 will never override a playing sound
  517. ====================
  518. */
  519. void S_StartSound(vec3_t origin, int entnum, int entchannel, sfx_t *sfx, float fvol, float attenuation, float timeofs)
  520. {
  521. sfxcache_t *sc;
  522. int vol;
  523. playsound_t *ps, *sort;
  524. int start;
  525. if (!sound_started)
  526. return;
  527. if (!sfx)
  528. return;
  529. if (sfx->name[0] == '*')
  530. sfx = S_RegisterSexedSound(&cl_entities[entnum].current, sfx->name);
  531. // make sure the sound is loaded
  532. sc = S_LoadSound (sfx);
  533. if (!sc)
  534. return; // couldn't load the sound's data
  535. vol = fvol*255;
  536. // make the playsound_t
  537. ps = S_AllocPlaysound ();
  538. if (!ps)
  539. return;
  540. if (origin)
  541. {
  542. VectorCopy (origin, ps->origin);
  543. ps->fixed_origin = true;
  544. }
  545. else
  546. ps->fixed_origin = false;
  547. ps->entnum = entnum;
  548. ps->entchannel = entchannel;
  549. ps->attenuation = attenuation;
  550. ps->volume = vol;
  551. ps->sfx = sfx;
  552. // drift s_beginofs
  553. start = cl.frame.servertime * 0.001 * dma.speed + s_beginofs;
  554. if (start < paintedtime)
  555. {
  556. start = paintedtime;
  557. s_beginofs = start - (cl.frame.servertime * 0.001 * dma.speed);
  558. }
  559. else if (start > paintedtime + 0.3 * dma.speed)
  560. {
  561. start = paintedtime + 0.1 * dma.speed;
  562. s_beginofs = start - (cl.frame.servertime * 0.001 * dma.speed);
  563. }
  564. else
  565. {
  566. s_beginofs-=10;
  567. }
  568. if (!timeofs)
  569. ps->begin = paintedtime;
  570. else
  571. ps->begin = start + timeofs * dma.speed;
  572. // sort into the pending sound list
  573. for (sort = s_pendingplays.next ;
  574. sort != &s_pendingplays && sort->begin < ps->begin ;
  575. sort = sort->next)
  576. ;
  577. ps->next = sort;
  578. ps->prev = sort->prev;
  579. ps->next->prev = ps;
  580. ps->prev->next = ps;
  581. }
  582. /*
  583. ==================
  584. S_StartLocalSound
  585. ==================
  586. */
  587. void S_StartLocalSound (char *sound)
  588. {
  589. sfx_t *sfx;
  590. if (!sound_started)
  591. return;
  592. sfx = S_RegisterSound (sound);
  593. if (!sfx)
  594. {
  595. Com_Printf ("S_StartLocalSound: can't cache %s\n", sound);
  596. return;
  597. }
  598. S_StartSound (NULL, cl.playernum+1, 0, sfx, 1, 1, 0);
  599. }
  600. /*
  601. ==================
  602. S_ClearBuffer
  603. ==================
  604. */
  605. void S_ClearBuffer (void)
  606. {
  607. int clear;
  608. if (!sound_started)
  609. return;
  610. s_rawend = 0;
  611. if (dma.samplebits == 8)
  612. clear = 0x80;
  613. else
  614. clear = 0;
  615. SNDDMA_BeginPainting ();
  616. if (dma.buffer)
  617. memset(dma.buffer, clear, dma.samples * dma.samplebits/8);
  618. SNDDMA_Submit ();
  619. }
  620. /*
  621. ==================
  622. S_StopAllSounds
  623. ==================
  624. */
  625. void S_StopAllSounds(void)
  626. {
  627. int i;
  628. if (!sound_started)
  629. return;
  630. // clear all the playsounds
  631. memset(s_playsounds, 0, sizeof(s_playsounds));
  632. s_freeplays.next = s_freeplays.prev = &s_freeplays;
  633. s_pendingplays.next = s_pendingplays.prev = &s_pendingplays;
  634. for (i=0 ; i<MAX_PLAYSOUNDS ; i++)
  635. {
  636. s_playsounds[i].prev = &s_freeplays;
  637. s_playsounds[i].next = s_freeplays.next;
  638. s_playsounds[i].prev->next = &s_playsounds[i];
  639. s_playsounds[i].next->prev = &s_playsounds[i];
  640. }
  641. // clear all the channels
  642. memset(channels, 0, sizeof(channels));
  643. S_ClearBuffer ();
  644. }
  645. /*
  646. ==================
  647. S_AddLoopSounds
  648. Entities with a ->sound field will generated looped sounds
  649. that are automatically started, stopped, and merged together
  650. as the entities are sent to the client
  651. ==================
  652. */
  653. void S_AddLoopSounds (void)
  654. {
  655. int i, j;
  656. int sounds[MAX_EDICTS];
  657. int left, right, left_total, right_total;
  658. channel_t *ch;
  659. sfx_t *sfx;
  660. sfxcache_t *sc;
  661. int num;
  662. entity_state_t *ent;
  663. if (cl_paused->value)
  664. return;
  665. if (cls.state != ca_active)
  666. return;
  667. if (!cl.sound_prepped)
  668. return;
  669. for (i=0 ; i<cl.frame.num_entities ; i++)
  670. {
  671. num = (cl.frame.parse_entities + i)&(MAX_PARSE_ENTITIES-1);
  672. ent = &cl_parse_entities[num];
  673. sounds[i] = ent->sound;
  674. }
  675. for (i=0 ; i<cl.frame.num_entities ; i++)
  676. {
  677. if (!sounds[i])
  678. continue;
  679. sfx = cl.sound_precache[sounds[i]];
  680. if (!sfx)
  681. continue; // bad sound effect
  682. sc = sfx->cache;
  683. if (!sc)
  684. continue;
  685. num = (cl.frame.parse_entities + i)&(MAX_PARSE_ENTITIES-1);
  686. ent = &cl_parse_entities[num];
  687. // find the total contribution of all sounds of this type
  688. S_SpatializeOrigin (ent->origin, 255.0, SOUND_LOOPATTENUATE,
  689. &left_total, &right_total);
  690. for (j=i+1 ; j<cl.frame.num_entities ; j++)
  691. {
  692. if (sounds[j] != sounds[i])
  693. continue;
  694. sounds[j] = 0; // don't check this again later
  695. num = (cl.frame.parse_entities + j)&(MAX_PARSE_ENTITIES-1);
  696. ent = &cl_parse_entities[num];
  697. S_SpatializeOrigin (ent->origin, 255.0, SOUND_LOOPATTENUATE,
  698. &left, &right);
  699. left_total += left;
  700. right_total += right;
  701. }
  702. if (left_total == 0 && right_total == 0)
  703. continue; // not audible
  704. // allocate a channel
  705. ch = S_PickChannel(0, 0);
  706. if (!ch)
  707. return;
  708. if (left_total > 255)
  709. left_total = 255;
  710. if (right_total > 255)
  711. right_total = 255;
  712. ch->leftvol = left_total;
  713. ch->rightvol = right_total;
  714. ch->autosound = true; // remove next frame
  715. ch->sfx = sfx;
  716. ch->pos = paintedtime % sc->length;
  717. ch->end = paintedtime + sc->length - ch->pos;
  718. }
  719. }
  720. //=============================================================================
  721. /*
  722. ============
  723. S_RawSamples
  724. Cinematic streaming and voice over network
  725. ============
  726. */
  727. void S_RawSamples (int samples, int rate, int width, int channels, byte *data)
  728. {
  729. int i;
  730. int src, dst;
  731. float scale;
  732. if (!sound_started)
  733. return;
  734. if (s_rawend < paintedtime)
  735. s_rawend = paintedtime;
  736. scale = (float)rate / dma.speed;
  737. //Com_Printf ("%i < %i < %i\n", soundtime, paintedtime, s_rawend);
  738. if (channels == 2 && width == 2)
  739. {
  740. if (scale == 1.0)
  741. { // optimized case
  742. for (i=0 ; i<samples ; i++)
  743. {
  744. dst = s_rawend&(MAX_RAW_SAMPLES-1);
  745. s_rawend++;
  746. s_rawsamples[dst].left =
  747. LittleShort(((short *)data)[i*2]) << 8;
  748. s_rawsamples[dst].right =
  749. LittleShort(((short *)data)[i*2+1]) << 8;
  750. }
  751. }
  752. else
  753. {
  754. for (i=0 ; ; i++)
  755. {
  756. src = i*scale;
  757. if (src >= samples)
  758. break;
  759. dst = s_rawend&(MAX_RAW_SAMPLES-1);
  760. s_rawend++;
  761. s_rawsamples[dst].left =
  762. LittleShort(((short *)data)[src*2]) << 8;
  763. s_rawsamples[dst].right =
  764. LittleShort(((short *)data)[src*2+1]) << 8;
  765. }
  766. }
  767. }
  768. else if (channels == 1 && width == 2)
  769. {
  770. for (i=0 ; ; i++)
  771. {
  772. src = i*scale;
  773. if (src >= samples)
  774. break;
  775. dst = s_rawend&(MAX_RAW_SAMPLES-1);
  776. s_rawend++;
  777. s_rawsamples[dst].left =
  778. LittleShort(((short *)data)[src]) << 8;
  779. s_rawsamples[dst].right =
  780. LittleShort(((short *)data)[src]) << 8;
  781. }
  782. }
  783. else if (channels == 2 && width == 1)
  784. {
  785. for (i=0 ; ; i++)
  786. {
  787. src = i*scale;
  788. if (src >= samples)
  789. break;
  790. dst = s_rawend&(MAX_RAW_SAMPLES-1);
  791. s_rawend++;
  792. s_rawsamples[dst].left =
  793. ((char *)data)[src*2] << 16;
  794. s_rawsamples[dst].right =
  795. ((char *)data)[src*2+1] << 16;
  796. }
  797. }
  798. else if (channels == 1 && width == 1)
  799. {
  800. for (i=0 ; ; i++)
  801. {
  802. src = i*scale;
  803. if (src >= samples)
  804. break;
  805. dst = s_rawend&(MAX_RAW_SAMPLES-1);
  806. s_rawend++;
  807. s_rawsamples[dst].left =
  808. (((byte *)data)[src]-128) << 16;
  809. s_rawsamples[dst].right = (((byte *)data)[src]-128) << 16;
  810. }
  811. }
  812. }
  813. //=============================================================================
  814. /*
  815. ============
  816. S_Update
  817. Called once each time through the main loop
  818. ============
  819. */
  820. void S_Update(vec3_t origin, vec3_t forward, vec3_t right, vec3_t up)
  821. {
  822. int i;
  823. int total;
  824. channel_t *ch;
  825. channel_t *combine;
  826. if (!sound_started)
  827. return;
  828. // if the laoding plaque is up, clear everything
  829. // out to make sure we aren't looping a dirty
  830. // dma buffer while loading
  831. if (cls.disable_screen)
  832. {
  833. S_ClearBuffer ();
  834. return;
  835. }
  836. // rebuild scale tables if volume is modified
  837. if (s_volume->modified)
  838. S_InitScaletable ();
  839. VectorCopy(origin, listener_origin);
  840. VectorCopy(forward, listener_forward);
  841. VectorCopy(right, listener_right);
  842. VectorCopy(up, listener_up);
  843. combine = NULL;
  844. // update spatialization for dynamic sounds
  845. ch = channels;
  846. for (i=0 ; i<MAX_CHANNELS; i++, ch++)
  847. {
  848. if (!ch->sfx)
  849. continue;
  850. if (ch->autosound)
  851. { // autosounds are regenerated fresh each frame
  852. memset (ch, 0, sizeof(*ch));
  853. continue;
  854. }
  855. S_Spatialize(ch); // respatialize channel
  856. if (!ch->leftvol && !ch->rightvol)
  857. {
  858. memset (ch, 0, sizeof(*ch));
  859. continue;
  860. }
  861. }
  862. // add loopsounds
  863. S_AddLoopSounds ();
  864. //
  865. // debugging output
  866. //
  867. if (s_show->value)
  868. {
  869. total = 0;
  870. ch = channels;
  871. for (i=0 ; i<MAX_CHANNELS; i++, ch++)
  872. if (ch->sfx && (ch->leftvol || ch->rightvol) )
  873. {
  874. Com_Printf ("%3i %3i %s\n", ch->leftvol, ch->rightvol, ch->sfx->name);
  875. total++;
  876. }
  877. Com_Printf ("----(%i)---- painted: %i\n", total, paintedtime);
  878. }
  879. // mix some sound
  880. S_Update_();
  881. }
  882. void GetSoundtime(void)
  883. {
  884. int samplepos;
  885. static int buffers;
  886. static int oldsamplepos;
  887. int fullsamples;
  888. fullsamples = dma.samples / dma.channels;
  889. // it is possible to miscount buffers if it has wrapped twice between
  890. // calls to S_Update. Oh well.
  891. samplepos = SNDDMA_GetDMAPos();
  892. if (samplepos < oldsamplepos)
  893. {
  894. buffers++; // buffer wrapped
  895. if (paintedtime > 0x40000000)
  896. { // time to chop things off to avoid 32 bit limits
  897. buffers = 0;
  898. paintedtime = fullsamples;
  899. S_StopAllSounds ();
  900. }
  901. }
  902. oldsamplepos = samplepos;
  903. soundtime = buffers*fullsamples + samplepos/dma.channels;
  904. }
  905. void S_Update_(void)
  906. {
  907. unsigned endtime;
  908. int samps;
  909. if (!sound_started)
  910. return;
  911. SNDDMA_BeginPainting ();
  912. if (!dma.buffer)
  913. return;
  914. // Updates DMA time
  915. GetSoundtime();
  916. // check to make sure that we haven't overshot
  917. if (paintedtime < soundtime)
  918. {
  919. Com_DPrintf ("S_Update_ : overflow\n");
  920. paintedtime = soundtime;
  921. }
  922. // mix ahead of current position
  923. endtime = soundtime + s_mixahead->value * dma.speed;
  924. //endtime = (soundtime + 4096) & ~4095;
  925. // mix to an even submission block size
  926. endtime = (endtime + dma.submission_chunk-1)
  927. & ~(dma.submission_chunk-1);
  928. samps = dma.samples >> (dma.channels-1);
  929. if (endtime - soundtime > samps)
  930. endtime = soundtime + samps;
  931. S_PaintChannels (endtime);
  932. SNDDMA_Submit ();
  933. }
  934. /*
  935. ===============================================================================
  936. console functions
  937. ===============================================================================
  938. */
  939. void S_Play(void)
  940. {
  941. int i;
  942. char name[256];
  943. sfx_t *sfx;
  944. i = 1;
  945. while (i<Cmd_Argc())
  946. {
  947. if (!strrchr(Cmd_Argv(i), '.'))
  948. {
  949. strcpy(name, Cmd_Argv(i));
  950. strcat(name, ".wav");
  951. }
  952. else
  953. strcpy(name, Cmd_Argv(i));
  954. sfx = S_RegisterSound(name);
  955. S_StartSound(NULL, cl.playernum+1, 0, sfx, 1.0, 1.0, 0);
  956. i++;
  957. }
  958. }
  959. void S_SoundList(void)
  960. {
  961. int i;
  962. sfx_t *sfx;
  963. sfxcache_t *sc;
  964. int size, total;
  965. total = 0;
  966. for (sfx=known_sfx, i=0 ; i<num_sfx ; i++, sfx++)
  967. {
  968. if (!sfx->registration_sequence)
  969. continue;
  970. sc = sfx->cache;
  971. if (sc)
  972. {
  973. size = sc->length*sc->width*(sc->stereo+1);
  974. total += size;
  975. if (sc->loopstart >= 0)
  976. Com_Printf ("L");
  977. else
  978. Com_Printf (" ");
  979. Com_Printf("(%2db) %6i : %s\n",sc->width*8, size, sfx->name);
  980. }
  981. else
  982. {
  983. if (sfx->name[0] == '*')
  984. Com_Printf(" placeholder : %s\n", sfx->name);
  985. else
  986. Com_Printf(" not loaded : %s\n", sfx->name);
  987. }
  988. }
  989. Com_Printf ("Total resident: %i\n", total);
  990. }