sound.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206
  1. /* -*- mode: c; tab-width: 4; c-basic-offset: 3; c-file-style: "linux" -*- */
  2. //
  3. // Copyright (c) 2009, Wei Mingzhi <whistler_wmz@users.sf.net>.
  4. // All rights reserved.
  5. //
  6. // This file is part of SDLPAL.
  7. //
  8. // SDLPAL is free software: you can redistribute it and/or modify
  9. // it under the terms of the GNU General Public License as published by
  10. // the Free Software Foundation, either version 3 of the License, or
  11. // (at your option) any later version.
  12. //
  13. // This program is distributed in the hope that it will be useful,
  14. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. // GNU General Public License for more details.
  17. //
  18. // You should have received a copy of the GNU General Public License
  19. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. //
  21. #include "palcommon.h"
  22. #include "global.h"
  23. #include "palcfg.h"
  24. #include "sound.h"
  25. #include "players.h"
  26. #include "util.h"
  27. #include "resampler.h"
  28. #include "midi.h"
  29. #include <math.h>
  30. #if PAL_HAS_OGG
  31. #include <vorbis/codec.h>
  32. #endif
  33. #define PAL_CDTRACK_BASE 10000
  34. typedef LPCBYTE(*FNLoadSoundData)(LPCBYTE, DWORD, SDL_AudioSpec *);
  35. typedef struct tagWAVEPLAYER
  36. {
  37. FNLoadSoundData LoadSoundData;
  38. void *resampler;
  39. short *buf;
  40. int buf_len, pos, len;
  41. } WAVEPLAYER;
  42. typedef struct tagSNDPLAYER
  43. {
  44. FILE *mkf;
  45. SDL_AudioSpec spec;
  46. SDL_AudioCVT cvt;
  47. SDL_mutex *mtx;
  48. MUSICPLAYER *pMusPlayer;
  49. MUSICPLAYER *pCDPlayer;
  50. #if PAL_HAS_SDLCD
  51. SDL_CD *pCD;
  52. #endif
  53. WAVEPLAYER wavePlayer;
  54. BOOL fOpened;
  55. BOOL fMusicEnabled;
  56. BOOL fSoundEnabled;
  57. } SNDPLAYER;
  58. static SNDPLAYER gSndPlayer;
  59. PAL_FORCE_INLINE
  60. void
  61. AUDIO_MixNative(
  62. short *dst,
  63. short *src,
  64. int samples
  65. )
  66. {
  67. while (samples > 0)
  68. {
  69. int val = *src++ + *dst;
  70. if (val > SHRT_MAX)
  71. *dst++ = SHRT_MAX;
  72. else if (val < SHRT_MIN)
  73. *dst++ = SHRT_MIN;
  74. else
  75. *dst++ = (short)val;
  76. samples--;
  77. }
  78. }
  79. PAL_FORCE_INLINE
  80. void
  81. AUDIO_MixNativeVolume(
  82. short *dst,
  83. int iDstVolume,
  84. short *src,
  85. int iSrcVolume,
  86. int samples
  87. )
  88. {
  89. while (samples > 0)
  90. {
  91. int val = ((*src++) * iSrcVolume + *dst * iDstVolume) / PAL_MAX_VOLUME;
  92. if (val > SHRT_MAX)
  93. *dst++ = SHRT_MAX;
  94. else if (val < SHRT_MIN)
  95. *dst++ = SHRT_MIN;
  96. else
  97. *dst++ = (short)val;
  98. samples--;
  99. }
  100. }
  101. PAL_FORCE_INLINE
  102. void
  103. AUDIO_AdjustNativeVolume(
  104. short *srcdst,
  105. int iVolume,
  106. int samples
  107. )
  108. {
  109. while (samples > 0)
  110. {
  111. *srcdst = *srcdst * iVolume / PAL_MAX_VOLUME;
  112. samples--; srcdst++;
  113. }
  114. }
  115. #if (defined(_M_IX86) || defined(__i386__) || defined(_M_X64) || defined(__amd64__))
  116. PAL_FORCE_INLINE
  117. void
  118. AUDIO_MixNative_SSE2(
  119. short *dst,
  120. short *src,
  121. int samples
  122. )
  123. {
  124. while (samples > 0)
  125. {
  126. int val = *src++ + *dst;
  127. if (val > SHRT_MAX)
  128. *dst++ = SHRT_MAX;
  129. else if (val < SHRT_MIN)
  130. *dst++ = SHRT_MIN;
  131. else
  132. *dst++ = (short)val;
  133. samples--;
  134. }
  135. }
  136. PAL_FORCE_INLINE
  137. void
  138. AUDIO_MixNativeVolume_SSE2(
  139. short *dst,
  140. int iDstVolume,
  141. short *src,
  142. int iSrcVolume,
  143. int samples
  144. )
  145. {
  146. while (samples > 0)
  147. {
  148. int val = ((*src++) * iSrcVolume + *dst * iDstVolume) / PAL_MAX_VOLUME;
  149. if (val > SHRT_MAX)
  150. *dst++ = SHRT_MAX;
  151. else if (val < SHRT_MIN)
  152. *dst++ = SHRT_MIN;
  153. else
  154. *dst++ = (short)val;
  155. samples--;
  156. }
  157. }
  158. #endif
  159. typedef struct tagRIFFHEADER
  160. {
  161. DWORD riff_sig; /* 'RIFF' */
  162. DWORD data_length; /* Total length minus eight, little-endian */
  163. DWORD riff_type; /* 'WAVE' */
  164. } RIFFHEADER, *LPRIFFHEADER;
  165. typedef const RIFFHEADER *LPCRIFFHEADER;
  166. typedef struct tagRIFFCHUNK
  167. {
  168. DWORD chunk_type; /* 'fmt ' and so on */
  169. DWORD chunk_length; /* Total chunk length minus eight, little-endian */
  170. } RIFFCHUNK, *LPRIFFCHUNK;
  171. typedef const RIFFCHUNK *LPCRIFFCHUNK;
  172. typedef struct tagWAVEFORMATPCM
  173. {
  174. WORD wFormatTag; /* format type */
  175. WORD nChannels; /* number of channels (i.e. mono, stereo, etc.) */
  176. DWORD nSamplesPerSec; /* sample rate */
  177. DWORD nAvgBytesPerSec; /* for buffer estimation */
  178. WORD nBlockAlign; /* block size of data */
  179. WORD wBitsPerSample;
  180. } WAVEFORMATPCM, *LPWAVEFORMATPCM;
  181. typedef const WAVEFORMATPCM *LPCWAVEFORMATPCM;
  182. static LPCBYTE
  183. SOUND_LoadWAVEData(
  184. LPCBYTE lpData,
  185. DWORD dwLen,
  186. SDL_AudioSpec *lpSpec
  187. )
  188. /*++
  189. Purpose:
  190. Return the WAVE data pointer inside the input buffer.
  191. Parameters:
  192. [IN] lpData - pointer to the buffer of the WAVE file.
  193. [IN] dwLen - length of the buffer of the WAVE file.
  194. [OUT] lpSpec - pointer to the SDL_AudioSpec structure, which contains
  195. some basic information about the WAVE file.
  196. Return value:
  197. Pointer to the WAVE data inside the input buffer, NULL if failed.
  198. --*/
  199. {
  200. #if SDL_BYTEORDER == SDL_BIG_ENDIAN
  201. # define RIFF 'RIFF'
  202. # define WAVE 'WAVE'
  203. # define FMT 'fmt '
  204. # define DATA 'data'
  205. # define PCM 0x0100
  206. #else
  207. # define RIFF 'FFIR'
  208. # define WAVE 'EVAW'
  209. # define FMT ' tmf'
  210. # define DATA 'atad'
  211. # define PCM 0x0001
  212. #endif
  213. LPCRIFFHEADER lpRiff = (LPCRIFFHEADER)lpData;
  214. LPCRIFFCHUNK lpChunk;
  215. LPCWAVEFORMATPCM lpFormat = NULL;
  216. LPCBYTE lpWaveData = NULL;
  217. DWORD len;
  218. if (dwLen < sizeof(RIFFHEADER) || lpRiff->riff_sig != RIFF || lpRiff->riff_type != WAVE || dwLen < SDL_SwapLE32(lpRiff->data_length) + 8)
  219. {
  220. return NULL;
  221. }
  222. lpChunk = (LPCRIFFCHUNK)(lpRiff + 1); dwLen -= sizeof(RIFFHEADER);
  223. while (dwLen >= sizeof(RIFFCHUNK))
  224. {
  225. len = SDL_SwapLE32(lpChunk->chunk_length);
  226. if (dwLen >= sizeof(RIFFCHUNK) + len)
  227. dwLen -= sizeof(RIFFCHUNK) + len;
  228. else
  229. return NULL;
  230. switch (lpChunk->chunk_type)
  231. {
  232. case FMT:
  233. lpFormat = (LPCWAVEFORMATPCM)(lpChunk + 1);
  234. if (len != sizeof(WAVEFORMATPCM) || lpFormat->wFormatTag != PCM)
  235. {
  236. return NULL;
  237. }
  238. break;
  239. case DATA:
  240. lpWaveData = (LPCBYTE)(lpChunk + 1);
  241. dwLen = 0;
  242. break;
  243. }
  244. lpChunk = (LPCRIFFCHUNK)((LPCBYTE)(lpChunk + 1) + len);
  245. }
  246. if (lpFormat == NULL || lpWaveData == NULL)
  247. {
  248. return NULL;
  249. }
  250. lpSpec->channels = lpFormat->nChannels;
  251. lpSpec->format = (lpFormat->wBitsPerSample == 16) ? AUDIO_S16 : AUDIO_U8;
  252. lpSpec->freq = lpFormat->nSamplesPerSec;
  253. lpSpec->size = len;
  254. return lpWaveData;
  255. #undef RIFF
  256. #undef WAVE
  257. #undef FMT
  258. }
  259. typedef struct tagVOCHEADER
  260. {
  261. char signature[0x14]; /* "Creative Voice File\x1A" */
  262. WORD data_offset; /* little endian */
  263. WORD version;
  264. WORD version_checksum;
  265. } VOCHEADER, *LPVOCHEADER;
  266. typedef const VOCHEADER *LPCVOCHEADER;
  267. static LPCBYTE
  268. SOUND_LoadVOCData(
  269. LPCBYTE lpData,
  270. DWORD dwLen,
  271. SDL_AudioSpec *lpSpec
  272. )
  273. /*++
  274. Purpose:
  275. Return the VOC data pointer inside the input buffer. Currently supports type 01 block only.
  276. Parameters:
  277. [IN] lpData - pointer to the buffer of the VOC file.
  278. [IN] dwLen - length of the buffer of the VOC file.
  279. [OUT] lpSpec - pointer to the SDL_AudioSpec structure, which contains
  280. some basic information about the VOC file.
  281. Return value:
  282. Pointer to the WAVE data inside the input buffer, NULL if failed.
  283. Reference: http://sox.sourceforge.net/AudioFormats-11.html
  284. --*/
  285. {
  286. LPCVOCHEADER lpVOC = (LPCVOCHEADER)lpData;
  287. if (dwLen < sizeof(VOCHEADER) || memcmp(lpVOC->signature, "Creative Voice File\x1A", 0x14) || SDL_SwapLE16(lpVOC->data_offset) >= dwLen)
  288. {
  289. return NULL;
  290. }
  291. lpData += SDL_SwapLE16(lpVOC->data_offset);
  292. dwLen -= SDL_SwapLE16(lpVOC->data_offset);
  293. while (dwLen && *lpData)
  294. {
  295. DWORD len;
  296. if (dwLen >= 4)
  297. {
  298. len = lpData[1] | (lpData[2] << 8) | (lpData[3] << 16);
  299. if (dwLen >= len + 4)
  300. dwLen -= len + 4;
  301. else
  302. return NULL;
  303. }
  304. else
  305. {
  306. return NULL;
  307. }
  308. if (*lpData == 0x01)
  309. {
  310. if (lpData[5] != 0) return NULL; /* Only 8-bit is supported */
  311. lpSpec->format = AUDIO_U8;
  312. lpSpec->channels = 1;
  313. lpSpec->freq = ((1000000 / (256 - lpData[4]) + 99) / 100) * 100; /* Round to next 100Hz */
  314. lpSpec->size = len - 2;
  315. return lpData + 6;
  316. }
  317. else
  318. {
  319. lpData += len + 4;
  320. }
  321. }
  322. return NULL;
  323. }
  324. static void
  325. SOUND_ResampleU8(
  326. LPCBYTE lpData,
  327. const SDL_AudioSpec *lpSpec,
  328. LPBYTE lpBuffer,
  329. DWORD dwLen,
  330. void *resampler
  331. )
  332. /*++
  333. Purpose:
  334. Resample 8-bit unsigned PCM data into 16-bit signed (little-endian) PCM data.
  335. Parameters:
  336. [IN] lpData - pointer to the buffer of the input PCM data.
  337. [IN] lpSpec - pointer to the SDL_AudioSpec structure, which contains
  338. some basic information about the input PCM data.
  339. [IN] lpBuffer - pointer of the buffer of the output PCM data.
  340. [IN] dwLen - length of the buffer of the output PCM data, should be exactly
  341. the number of bytes needed of the resampled data.
  342. [IN] resampler - pointer of the resampler instance.
  343. Return value:
  344. None.
  345. --*/
  346. {
  347. int src_samples = lpSpec->size / lpSpec->channels, i;
  348. for (i = 0; i < lpSpec->channels; i++)
  349. {
  350. LPCBYTE src = lpData + i;
  351. short *dst = (short *)lpBuffer + i;
  352. int channel_len = dwLen / lpSpec->channels, total_bytes = 0;
  353. resampler_clear(resampler);
  354. while (total_bytes < channel_len && src_samples > 0)
  355. {
  356. int to_write, j;
  357. to_write = resampler_get_free_count(resampler);
  358. if (to_write > src_samples) to_write = src_samples;
  359. for (j = 0; j < to_write; j++)
  360. {
  361. resampler_write_sample(resampler, (*src ^ 0x80) << 8);
  362. src += lpSpec->channels;
  363. }
  364. src_samples -= to_write;
  365. while (total_bytes < channel_len && resampler_get_sample_count(resampler) > 0)
  366. {
  367. *dst = resampler_get_and_remove_sample(resampler);
  368. dst += lpSpec->channels; total_bytes += (SDL_AUDIO_BITSIZE(AUDIO_S16) >> 3);
  369. }
  370. }
  371. /* Flush resampler's output buffer */
  372. while (total_bytes < channel_len)
  373. {
  374. int j, to_write = resampler_get_free_count(resampler);
  375. for (j = 0; j < to_write; j++)
  376. resampler_write_sample(resampler, (src[-lpSpec->channels] ^ 0x80) << 8);
  377. while (total_bytes < channel_len && resampler_get_sample_count(resampler) > 0)
  378. {
  379. *dst = resampler_get_and_remove_sample(resampler);
  380. dst += lpSpec->channels; total_bytes += (SDL_AUDIO_BITSIZE(AUDIO_S16) >> 3);
  381. }
  382. }
  383. }
  384. }
  385. static void
  386. SOUND_ResampleS16(
  387. LPCBYTE lpData,
  388. const SDL_AudioSpec *lpSpec,
  389. LPBYTE lpBuffer,
  390. DWORD dwLen,
  391. void *resampler
  392. )
  393. /*++
  394. Purpose:
  395. Resample 16-bit signed (little-endian) PCM data into 16-bit signed (little-endian) PCM data.
  396. Parameters:
  397. [IN] lpData - pointer to the buffer of the input PCM data.
  398. [IN] lpSpec - pointer to the SDL_AudioSpec structure, which contains
  399. some basic information about the input PCM data.
  400. [IN] lpBuffer - pointer of the buffer of the output PCM data.
  401. [IN] dwLen - length of the buffer of the output PCM data, should be exactly
  402. the number of bytes needed of the resampled data.
  403. [IN] resampler - pointer of the resampler instance.
  404. Return value:
  405. None.
  406. --*/
  407. {
  408. int src_samples = lpSpec->size / lpSpec->channels / 2, i;
  409. for (i = 0; i < lpSpec->channels; i++)
  410. {
  411. const short *src = (short *)lpData + i;
  412. short *dst = (short *)lpBuffer + i;
  413. int channel_len = dwLen / lpSpec->channels, total_bytes = 0;
  414. resampler_clear(resampler);
  415. while (total_bytes < channel_len && src_samples > 0)
  416. {
  417. int to_write, j;
  418. to_write = resampler_get_free_count(resampler);
  419. if (to_write > src_samples) to_write = src_samples;
  420. for (j = 0; j < to_write; j++)
  421. {
  422. resampler_write_sample(resampler, SDL_SwapLE16(*src));
  423. src += lpSpec->channels;
  424. }
  425. src_samples -= to_write;
  426. while (total_bytes < channel_len && resampler_get_sample_count(resampler) > 0)
  427. {
  428. *dst = resampler_get_and_remove_sample(resampler);
  429. dst += lpSpec->channels; total_bytes += (SDL_AUDIO_BITSIZE(AUDIO_S16) >> 3);
  430. }
  431. }
  432. /* Flush resampler's output buffer */
  433. while (total_bytes < channel_len)
  434. {
  435. int j, to_write = resampler_get_free_count(resampler);
  436. short val = SDL_SwapLE16(src[-lpSpec->channels]);
  437. for (j = 0; j < to_write; j++)
  438. resampler_write_sample(resampler, val);
  439. while (total_bytes < channel_len && resampler_get_sample_count(resampler) > 0)
  440. {
  441. *dst = resampler_get_and_remove_sample(resampler);
  442. dst += lpSpec->channels; total_bytes += (SDL_AUDIO_BITSIZE(AUDIO_S16) >> 3);
  443. }
  444. }
  445. }
  446. }
  447. static VOID SDLCALL
  448. AUDIO_FillBuffer(
  449. LPVOID udata,
  450. LPBYTE stream,
  451. INT len
  452. )
  453. /*++
  454. Purpose:
  455. SDL sound callback function.
  456. Parameters:
  457. [IN] udata - pointer to user-defined parameters (Not used).
  458. [OUT] stream - pointer to the stream buffer.
  459. [IN] len - Length of the buffer.
  460. Return value:
  461. None.
  462. --*/
  463. {
  464. #if SDL_VERSION_ATLEAST(2,0,0)
  465. memset(stream, 0, len);
  466. #endif
  467. SDL_mutexP(gSndPlayer.mtx);
  468. gSndPlayer.cvt.buf = stream;
  469. gSndPlayer.cvt.len = len;
  470. //
  471. // Play music
  472. //
  473. if (gSndPlayer.fMusicEnabled)
  474. {
  475. if (gSndPlayer.pMusPlayer)
  476. {
  477. gSndPlayer.pMusPlayer->FillBuffer(gSndPlayer.pMusPlayer, stream, len);
  478. }
  479. if (gSndPlayer.pCDPlayer)
  480. {
  481. gSndPlayer.pCDPlayer->FillBuffer(gSndPlayer.pCDPlayer, stream, len);
  482. }
  483. }
  484. //
  485. // Play sound
  486. //
  487. if (gSndPlayer.fSoundEnabled && gSndPlayer.wavePlayer.len > 0)
  488. {
  489. //
  490. // Mix as much sound data as possible
  491. //
  492. WAVEPLAYER *player = &gSndPlayer.wavePlayer;
  493. int mixlen = min(player->len, len >> 1);
  494. if (player->pos + mixlen > player->buf_len)
  495. {
  496. AUDIO_MixNativeVolume((short *)stream, gConfig.iMusicVolume, player->buf + player->pos, gConfig.iSoundVolume, player->buf_len - player->pos);
  497. stream += (player->buf_len - player->pos) << 1; memset(player->buf + player->pos, 0, (player->buf_len - player->pos) << 1);
  498. AUDIO_MixNativeVolume((short *)stream, gConfig.iMusicVolume, player->buf, gConfig.iSoundVolume, player->pos + mixlen - player->buf_len);
  499. stream += (player->pos + mixlen - player->buf_len) << 1; memset(player->buf, 0, (player->pos + mixlen - player->buf_len) << 1);
  500. }
  501. else
  502. {
  503. AUDIO_MixNativeVolume((short *)stream, gConfig.iMusicVolume, player->buf + player->pos, gConfig.iSoundVolume, mixlen);
  504. stream += mixlen << 1; memset(player->buf + player->pos, 0, mixlen << 1);
  505. }
  506. player->pos = (player->pos + mixlen) % player->buf_len; player->len -= mixlen; len -= (mixlen << 1);
  507. }
  508. //
  509. // Adjust volume in the remaing buffer
  510. //
  511. AUDIO_AdjustNativeVolume((short *)stream, gConfig.iMusicVolume, len >> 1);
  512. //
  513. // Convert audio from native byte-order to actual byte-order
  514. //
  515. SDL_ConvertAudio(&gSndPlayer.cvt);
  516. SDL_mutexV(gSndPlayer.mtx);
  517. }
  518. static VOID
  519. SOUND_LoadMKF(
  520. VOID
  521. )
  522. /*++
  523. Purpose:
  524. Load MKF contents into memory.
  525. Parameters:
  526. None.
  527. Return value:
  528. None.
  529. --*/
  530. {
  531. char *mkfs[2];
  532. FNLoadSoundData func[2];
  533. int i;
  534. if (gConfig.fIsWIN95)
  535. {
  536. mkfs[0] = "sounds.mkf"; func[0] = SOUND_LoadWAVEData;
  537. mkfs[1] = "voc.mkf"; func[1] = SOUND_LoadVOCData;
  538. }
  539. else
  540. {
  541. mkfs[0] = "voc.mkf"; func[0] = SOUND_LoadVOCData;
  542. mkfs[1] = "sounds.mkf"; func[1] = SOUND_LoadWAVEData;
  543. }
  544. for (i = 0; i < 2; i++)
  545. {
  546. gSndPlayer.mkf = UTIL_OpenFile(mkfs[i]);
  547. if (gSndPlayer.mkf)
  548. {
  549. gSndPlayer.wavePlayer.LoadSoundData = func[i];
  550. break;
  551. }
  552. }
  553. }
  554. INT
  555. AUDIO_OpenDevice(
  556. VOID
  557. )
  558. /*++
  559. Purpose:
  560. Initialize the audio subsystem.
  561. Parameters:
  562. None.
  563. Return value:
  564. 0 if succeed, others if failed.
  565. --*/
  566. {
  567. SDL_AudioSpec spec;
  568. if (gSndPlayer.fOpened)
  569. {
  570. //
  571. // Already opened
  572. //
  573. return -1;
  574. }
  575. gSndPlayer.fOpened = FALSE;
  576. gSndPlayer.fMusicEnabled = TRUE;
  577. gSndPlayer.fSoundEnabled = TRUE;
  578. //
  579. // Load the MKF file.
  580. //
  581. SOUND_LoadMKF();
  582. if (gSndPlayer.mkf == NULL)
  583. {
  584. return -2;
  585. }
  586. //
  587. // Initialize the resampler
  588. //
  589. resampler_init();
  590. gSndPlayer.wavePlayer.resampler = resampler_create();
  591. //
  592. // Open the sound subsystem.
  593. //
  594. gSndPlayer.spec.freq = gConfig.iSampleRate;
  595. gSndPlayer.spec.format = AUDIO_S16;
  596. gSndPlayer.spec.channels = gConfig.iAudioChannels;
  597. gSndPlayer.spec.samples = gConfig.wAudioBufferSize;
  598. gSndPlayer.spec.callback = AUDIO_FillBuffer;
  599. if (SDL_OpenAudio(&gSndPlayer.spec, &spec) < 0)
  600. {
  601. //
  602. // Failed
  603. //
  604. return -3;
  605. }
  606. else
  607. gSndPlayer.spec = spec;
  608. SDL_BuildAudioCVT(&gSndPlayer.cvt, AUDIO_S16SYS, spec.channels, spec.freq, spec.format, spec.channels, spec.freq);
  609. gSndPlayer.wavePlayer.buf = NULL;
  610. gSndPlayer.wavePlayer.buf_len = 0;
  611. gSndPlayer.wavePlayer.pos = 0;
  612. gSndPlayer.wavePlayer.len = 0;
  613. gSndPlayer.mtx = SDL_CreateMutex();
  614. gSndPlayer.fOpened = TRUE;
  615. //
  616. // Initialize the music subsystem.
  617. //
  618. switch (gConfig.eMusicType)
  619. {
  620. case MUSIC_RIX:
  621. if (!(gSndPlayer.pMusPlayer = RIX_Init(va("%s%s", gConfig.pszGamePath, "mus.mkf"))))
  622. {
  623. gSndPlayer.pMusPlayer = RIX_Init(va("%s%s", gConfig.pszGamePath, "MUS.MKF"));
  624. }
  625. break;
  626. case MUSIC_MP3:
  627. #if PAL_HAS_MP3
  628. gSndPlayer.pMusPlayer = MP3_Init(NULL);
  629. #else
  630. gSndPlayer.pMusPlayer = NULL;
  631. #endif
  632. break;
  633. case MUSIC_OGG:
  634. #if PAL_HAS_OGG
  635. gSndPlayer.pMusPlayer = OGG_Init(NULL);
  636. #else
  637. gSndPlayer.pMusPlayer = NULL;
  638. #endif
  639. break;
  640. case MUSIC_MIDI:
  641. gSndPlayer.pMusPlayer = NULL;
  642. break;
  643. }
  644. //
  645. // Initialize the CD audio.
  646. //
  647. switch (gConfig.eCDType)
  648. {
  649. case MUSIC_SDLCD:
  650. {
  651. #if PAL_HAS_SDLCD
  652. int i;
  653. gSndPlayer.pCD = NULL;
  654. for (i = 0; i < SDL_CDNumDrives(); i++)
  655. {
  656. gSndPlayer.pCD = SDL_CDOpen(i);
  657. if (gSndPlayer.pCD != NULL)
  658. {
  659. if (!CD_INDRIVE(SDL_CDStatus(gSndPlayer.pCD)))
  660. {
  661. SDL_CDClose(gSndPlayer.pCD);
  662. gSndPlayer.pCD = NULL;
  663. }
  664. else
  665. {
  666. break;
  667. }
  668. }
  669. }
  670. #endif
  671. gSndPlayer.pCDPlayer = NULL;
  672. break;
  673. }
  674. case MUSIC_MP3:
  675. #if PAL_HAS_MP3
  676. gSndPlayer.pCDPlayer = MP3_Init(NULL);
  677. #else
  678. gSndPlayer.pCDPlayer = NULL;
  679. #endif
  680. break;
  681. case MUSIC_OGG:
  682. #if PAL_HAS_OGG
  683. gSndPlayer.pCDPlayer = OGG_Init(NULL);
  684. #else
  685. gSndPlayer.pCDPlayer = NULL;
  686. #endif
  687. break;
  688. }
  689. //
  690. // Let the callback function run so that musics will be played.
  691. //
  692. SDL_PauseAudio(0);
  693. return 0;
  694. }
  695. VOID
  696. AUDIO_CloseDevice(
  697. VOID
  698. )
  699. /*++
  700. Purpose:
  701. Close the audio subsystem.
  702. Parameters:
  703. None.
  704. Return value:
  705. None.
  706. --*/
  707. {
  708. SDL_CloseAudio();
  709. SDL_mutexP(gSndPlayer.mtx);
  710. if (gSndPlayer.wavePlayer.buf != NULL)
  711. {
  712. free(gSndPlayer.wavePlayer.buf);
  713. gSndPlayer.wavePlayer.buf = NULL;
  714. gSndPlayer.wavePlayer.buf_len = 0;
  715. gSndPlayer.wavePlayer.pos = 0;
  716. gSndPlayer.wavePlayer.len = 0;
  717. }
  718. if (gSndPlayer.mkf != NULL)
  719. {
  720. fclose(gSndPlayer.mkf);
  721. gSndPlayer.mkf = NULL;
  722. }
  723. if (gSndPlayer.pMusPlayer)
  724. {
  725. gSndPlayer.pMusPlayer->Shutdown(gSndPlayer.pMusPlayer);
  726. gSndPlayer.pMusPlayer = NULL;
  727. }
  728. if (gSndPlayer.pCDPlayer)
  729. {
  730. gSndPlayer.pCDPlayer->Shutdown(gSndPlayer.pCDPlayer);
  731. gSndPlayer.pCDPlayer = NULL;
  732. }
  733. #if PAL_HAS_SDLCD
  734. if (gSndPlayer.pCD != NULL)
  735. {
  736. AUDIO_PlayCDTrack(-1);
  737. SDL_CDClose(gSndPlayer.pCD);
  738. }
  739. #endif
  740. if (gConfig.eMusicType == MUSIC_MIDI) MIDI_Play(0, FALSE);
  741. if (gSndPlayer.wavePlayer.resampler)
  742. {
  743. resampler_delete(gSndPlayer.wavePlayer.resampler);
  744. gSndPlayer.wavePlayer.resampler = NULL;
  745. }
  746. SDL_mutexV(gSndPlayer.mtx);
  747. SDL_DestroyMutex(gSndPlayer.mtx);
  748. }
  749. SDL_AudioSpec*
  750. AUDIO_GetDeviceSpec(
  751. VOID
  752. )
  753. {
  754. return &gSndPlayer.spec;
  755. }
  756. static INT
  757. AUDIO_AdjustVolumeByValue(
  758. INT *iVolume,
  759. INT iValue
  760. )
  761. {
  762. *iVolume += iValue;
  763. if (*iVolume > PAL_MAX_VOLUME)
  764. *iVolume = PAL_MAX_VOLUME;
  765. else if (*iVolume < 0)
  766. *iVolume = 0;
  767. return *iVolume;
  768. }
  769. VOID
  770. AUDIO_AdjustVolume(
  771. INT iDirection
  772. )
  773. /*++
  774. Purpose:
  775. SDL sound volume adjust function.
  776. Parameters:
  777. [IN] iDirection - value, Increase (>0) or decrease (<=0) 3% volume.
  778. Return value:
  779. None.
  780. --*/
  781. {
  782. AUDIO_AdjustVolumeByValue(&gConfig.iMusicVolume, (iDirection > 0) ? 3 : -3);
  783. AUDIO_AdjustVolumeByValue(&gConfig.iSoundVolume, (iDirection > 0) ? 3 : -3);
  784. }
  785. VOID
  786. AUDIO_PlaySound(
  787. INT iSoundNum
  788. )
  789. /*++
  790. Purpose:
  791. Play a sound in voc.mkf/sounds.mkf file.
  792. Parameters:
  793. [IN] iSoundNum - number of the sound; the absolute value is used.
  794. Return value:
  795. None.
  796. --*/
  797. {
  798. SDL_AudioCVT wavecvt;
  799. SDL_AudioSpec wavespec;
  800. LPBYTE buf, bufdec;
  801. LPCBYTE bufsrc;
  802. int len;
  803. if (!gSndPlayer.fOpened || !gSndPlayer.fSoundEnabled)
  804. {
  805. return;
  806. }
  807. if (iSoundNum < 0)
  808. {
  809. iSoundNum = -iSoundNum;
  810. }
  811. //
  812. // Get the length of the sound file.
  813. //
  814. len = PAL_MKFGetChunkSize(iSoundNum, gSndPlayer.mkf);
  815. if (len <= 0)
  816. {
  817. return;
  818. }
  819. buf = (LPBYTE)malloc(len);
  820. if (buf == NULL)
  821. {
  822. return;
  823. }
  824. //
  825. // Read the sound file from the MKF archive.
  826. //
  827. PAL_MKFReadChunk(buf, len, iSoundNum, gSndPlayer.mkf);
  828. bufsrc = gSndPlayer.wavePlayer.LoadSoundData(buf, len, &wavespec);
  829. if (bufsrc == NULL)
  830. {
  831. free(buf);
  832. return;
  833. }
  834. if (wavespec.freq != gSndPlayer.spec.freq)
  835. {
  836. /* Resampler is needed */
  837. resampler_set_quality(gSndPlayer.wavePlayer.resampler, AUDIO_IsIntegerConversion(wavespec.freq) ? RESAMPLER_QUALITY_MIN : gConfig.iResampleQuality);
  838. resampler_set_rate(gSndPlayer.wavePlayer.resampler, (double)wavespec.freq / (double)gSndPlayer.spec.freq);
  839. len = (int)ceil(wavespec.size * (double)gSndPlayer.spec.freq / (double)wavespec.freq) * (SDL_AUDIO_BITSIZE(AUDIO_S16SYS) / SDL_AUDIO_BITSIZE(wavespec.format));
  840. if (len >= wavespec.channels * 2 && (bufdec = malloc(len)))
  841. {
  842. if (wavespec.format == AUDIO_S16)
  843. SOUND_ResampleS16(bufsrc, &wavespec, bufdec, len, gSndPlayer.wavePlayer.resampler);
  844. else
  845. SOUND_ResampleU8(bufsrc, &wavespec, bufdec, len, gSndPlayer.wavePlayer.resampler);
  846. /* Free the original buffer and reset the pointer for simpler later operations */
  847. free(buf); buf = bufdec;
  848. wavespec.format = AUDIO_S16SYS;
  849. wavespec.freq = gSndPlayer.spec.freq;
  850. }
  851. else
  852. {
  853. free(buf);
  854. return;
  855. }
  856. }
  857. else
  858. {
  859. bufdec = (LPBYTE)bufsrc;
  860. len = wavespec.size;
  861. }
  862. //
  863. // Build the audio converter and create conversion buffers
  864. //
  865. if (SDL_BuildAudioCVT(&wavecvt, wavespec.format, wavespec.channels, wavespec.freq,
  866. AUDIO_S16SYS, gSndPlayer.spec.channels, gSndPlayer.spec.freq) < 0)
  867. {
  868. free(buf);
  869. return;
  870. }
  871. wavecvt.len = len & ~((SDL_AUDIO_BITSIZE(wavespec.format) >> 3) * wavespec.channels - 1);
  872. wavecvt.buf = (LPBYTE)malloc(wavecvt.len * wavecvt.len_mult);
  873. if (wavecvt.buf == NULL)
  874. {
  875. free(buf);
  876. return;
  877. }
  878. memcpy(wavecvt.buf, bufdec, len);
  879. free(buf);
  880. //
  881. // Run the audio converter
  882. //
  883. if (SDL_ConvertAudio(&wavecvt) == 0)
  884. {
  885. WAVEPLAYER *player = &gSndPlayer.wavePlayer;
  886. wavecvt.len = (int)(wavecvt.len * wavecvt.len_ratio) >> 1;
  887. SDL_mutexP(gSndPlayer.mtx);
  888. //
  889. // Check if the current sound buffer is large enough
  890. //
  891. if (gSndPlayer.wavePlayer.buf_len < wavecvt.len)
  892. {
  893. if (player->pos + player->len > player->buf_len)
  894. {
  895. short *old_buf = player->buf;
  896. player->buf = (short *)malloc(wavecvt.len << 1);
  897. memcpy(player->buf, old_buf + player->pos, (player->buf_len - player->pos) << 1);
  898. memcpy(player->buf + player->buf_len - player->pos, old_buf, (player->pos + player->len - player->buf_len) << 1);
  899. player->pos = 0; free(old_buf);
  900. }
  901. else
  902. player->buf = (short *)realloc(player->buf, wavecvt.len << 1);
  903. memset(player->buf + player->pos + player->len, 0, ((player->buf_len = wavecvt.len) - player->pos - player->len) << 1);
  904. }
  905. //
  906. // Mix the current sound buffer with newly played sound and adjust the length of valid data
  907. //
  908. if (player->pos + wavecvt.len > player->buf_len)
  909. {
  910. AUDIO_MixNative(player->buf + player->pos, (short *)wavecvt.buf, player->buf_len - player->pos);
  911. AUDIO_MixNative(player->buf, (short *)wavecvt.buf + player->buf_len - player->pos, player->pos + wavecvt.len - player->buf_len);
  912. }
  913. else
  914. AUDIO_MixNative(player->buf + player->pos, (short *)wavecvt.buf, wavecvt.len);
  915. player->len = max(player->len, wavecvt.len);
  916. SDL_mutexV(gSndPlayer.mtx);
  917. }
  918. free(wavecvt.buf);
  919. }
  920. VOID
  921. AUDIO_PlayMusic(
  922. INT iNumRIX,
  923. BOOL fLoop,
  924. FLOAT flFadeTime
  925. )
  926. {
  927. SDL_mutexP(gSndPlayer.mtx);
  928. if (gConfig.eMusicType == MUSIC_MIDI)
  929. {
  930. MIDI_Play(iNumRIX, fLoop);
  931. }
  932. else if (gSndPlayer.pMusPlayer)
  933. {
  934. gSndPlayer.pMusPlayer->Play(gSndPlayer.pMusPlayer, iNumRIX, fLoop, flFadeTime);
  935. }
  936. SDL_mutexV(gSndPlayer.mtx);
  937. }
  938. BOOL
  939. AUDIO_PlayCDTrack(
  940. INT iNumTrack
  941. )
  942. /*++
  943. Purpose:
  944. Play a CD Audio Track.
  945. Parameters:
  946. [IN] iNumTrack - number of the CD Audio Track.
  947. Return value:
  948. TRUE if the track can be played, FALSE if not.
  949. --*/
  950. {
  951. BOOL ret = FALSE;
  952. #if PAL_HAS_SDLCD
  953. if (gSndPlayer.pCD != NULL)
  954. {
  955. if (CD_INDRIVE(SDL_CDStatus(gSndPlayer.pCD)))
  956. {
  957. SDL_CDStop(gSndPlayer.pCD);
  958. if (iNumTrack != -1)
  959. {
  960. AUDIO_PlayMusic(-1, FALSE, 0);
  961. if (SDL_CDPlayTracks(gSndPlayer.pCD, iNumTrack - 1, 0, 1, 0) == 0)
  962. {
  963. return TRUE;
  964. }
  965. }
  966. }
  967. }
  968. #endif
  969. SDL_mutexP(gSndPlayer.mtx);
  970. if (gSndPlayer.pCDPlayer)
  971. {
  972. if (iNumTrack != -1)
  973. {
  974. AUDIO_PlayMusic(-1, FALSE, 0);
  975. ret = gSndPlayer.pCDPlayer->Play(gSndPlayer.pCDPlayer, PAL_CDTRACK_BASE + iNumTrack, TRUE, 0);
  976. }
  977. else
  978. {
  979. ret = gSndPlayer.pCDPlayer->Play(gSndPlayer.pCDPlayer, -1, FALSE, 0);
  980. }
  981. }
  982. SDL_mutexV(gSndPlayer.mtx);
  983. return ret;
  984. }
  985. VOID
  986. AUDIO_EnableMusic(
  987. BOOL fEnable
  988. )
  989. {
  990. gSndPlayer.fMusicEnabled = fEnable;
  991. }
  992. BOOL
  993. AUDIO_MusicEnabled(
  994. VOID
  995. )
  996. {
  997. return gSndPlayer.fMusicEnabled;
  998. }
  999. VOID
  1000. AUDIO_EnableSound(
  1001. BOOL fEnable
  1002. )
  1003. {
  1004. gSndPlayer.fSoundEnabled = fEnable;
  1005. }
  1006. BOOL
  1007. AUDIO_SoundEnabled(
  1008. VOID
  1009. )
  1010. {
  1011. return gSndPlayer.fSoundEnabled;
  1012. }
  1013. #ifdef PSP
  1014. void
  1015. SOUND_Reload(
  1016. void
  1017. )
  1018. {
  1019. fclose(gSndPlayer.mkf);
  1020. SOUND_LoadMKF();
  1021. }
  1022. #endif