sound.c 27 KB

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