sound.c 22 KB

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