sound.c 22 KB

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